mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 06:43:09 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (120 commits) usb: don't update devnum for wusb devices wusb: make ep0_reinit available for modules wusb: devices dont use a set address wusb: teach choose_address() about wireless devices wusb: add link wusb-usb device wusb: add authenticathed bit to usb_dev USB: remove unnecessary type casting of urb->context usb serial: more fixes and groundwork for tty changes USB: replace remaining __FUNCTION__ occurrences USB: usbfs: export the URB_NO_INTERRUPT flag to userspace USB: fix compile problems in ehci-hcd USB: ehci: qh_completions cleanup and bugfix USB: cdc-acm: signedness fix USB: add documentation about callbacks USB: don't explicitly reenable root-hub status interrupts USB: OHCI: turn off RD when remote wakeup is disabled USB: HCDs use the do_remote_wakeup flag USB: g_file_storage: ignore bulk-out data after invalid CBW USB: serial: remove endpoints setting checks from core and header USB: serial: remove unneeded number endpoints settings ...
This commit is contained in:
commit
37b05b1798
50
Documentation/usb/anchors.txt
Normal file
50
Documentation/usb/anchors.txt
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
What is anchor?
|
||||||
|
===============
|
||||||
|
|
||||||
|
A USB driver needs to support some callbacks requiring
|
||||||
|
a driver to cease all IO to an interface. To do so, a
|
||||||
|
driver has to keep track of the URBs it has submitted
|
||||||
|
to know they've all completed or to call usb_kill_urb
|
||||||
|
for them. The anchor is a data structure takes care of
|
||||||
|
keeping track of URBs and provides methods to deal with
|
||||||
|
multiple URBs.
|
||||||
|
|
||||||
|
Allocation and Initialisation
|
||||||
|
=============================
|
||||||
|
|
||||||
|
There's no API to allocate an anchor. It is simply declared
|
||||||
|
as struct usb_anchor. init_usb_anchor() must be called to
|
||||||
|
initialise the data structure.
|
||||||
|
|
||||||
|
Deallocation
|
||||||
|
============
|
||||||
|
|
||||||
|
Once it has no more URBs associated with it, the anchor can be
|
||||||
|
freed with normal memory management operations.
|
||||||
|
|
||||||
|
Association and disassociation of URBs with anchors
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
An association of URBs to an anchor is made by an explicit
|
||||||
|
call to usb_anchor_urb(). The association is maintained until
|
||||||
|
an URB is finished by (successfull) completion. Thus disassociation
|
||||||
|
is automatic. A function is provided to forcibly finish (kill)
|
||||||
|
all URBs associated with an anchor.
|
||||||
|
Furthermore, disassociation can be made with usb_unanchor_urb()
|
||||||
|
|
||||||
|
Operations on multitudes of URBs
|
||||||
|
================================
|
||||||
|
|
||||||
|
usb_kill_anchored_urbs()
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
This function kills all URBs associated with an anchor. The URBs
|
||||||
|
are called in the reverse temporal order they were submitted.
|
||||||
|
This way no data can be reordered.
|
||||||
|
|
||||||
|
usb_wait_anchor_empty_timeout()
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
This function waits for all URBs associated with an anchor to finish
|
||||||
|
or a timeout, whichever comes first. Its return value will tell you
|
||||||
|
whether the timeout was reached.
|
132
Documentation/usb/callbacks.txt
Normal file
132
Documentation/usb/callbacks.txt
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
What callbacks will usbcore do?
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Usbcore will call into a driver through callbacks defined in the driver
|
||||||
|
structure and through the completion handler of URBs a driver submits.
|
||||||
|
Only the former are in the scope of this document. These two kinds of
|
||||||
|
callbacks are completely independent of each other. Information on the
|
||||||
|
completion callback can be found in Documentation/usb/URB.txt.
|
||||||
|
|
||||||
|
The callbacks defined in the driver structure are:
|
||||||
|
|
||||||
|
1. Hotplugging callbacks:
|
||||||
|
|
||||||
|
* @probe: Called to see if the driver is willing to manage a particular
|
||||||
|
* interface on a device.
|
||||||
|
* @disconnect: Called when the interface is no longer accessible, usually
|
||||||
|
* because its device has been (or is being) disconnected or the
|
||||||
|
* driver module is being unloaded.
|
||||||
|
|
||||||
|
2. Odd backdoor through usbfs:
|
||||||
|
|
||||||
|
* @ioctl: Used for drivers that want to talk to userspace through
|
||||||
|
* the "usbfs" filesystem. This lets devices provide ways to
|
||||||
|
* expose information to user space regardless of where they
|
||||||
|
* do (or don't) show up otherwise in the filesystem.
|
||||||
|
|
||||||
|
3. Power management (PM) callbacks:
|
||||||
|
|
||||||
|
* @suspend: Called when the device is going to be suspended.
|
||||||
|
* @resume: Called when the device is being resumed.
|
||||||
|
* @reset_resume: Called when the suspended device has been reset instead
|
||||||
|
* of being resumed.
|
||||||
|
|
||||||
|
4. Device level operations:
|
||||||
|
|
||||||
|
* @pre_reset: Called when the device is about to be reset.
|
||||||
|
* @post_reset: Called after the device has been reset
|
||||||
|
|
||||||
|
The ioctl interface (2) should be used only if you have a very good
|
||||||
|
reason. Sysfs is preferred these days. The PM callbacks are covered
|
||||||
|
separately in Documentation/usb/power-management.txt.
|
||||||
|
|
||||||
|
Calling conventions
|
||||||
|
===================
|
||||||
|
|
||||||
|
All callbacks are mutually exclusive. There's no need for locking
|
||||||
|
against other USB callbacks. All callbacks are called from a task
|
||||||
|
context. You may sleep. However, it is important that all sleeps have a
|
||||||
|
small fixed upper limit in time. In particular you must not call out to
|
||||||
|
user space and await results.
|
||||||
|
|
||||||
|
Hotplugging callbacks
|
||||||
|
=====================
|
||||||
|
|
||||||
|
These callbacks are intended to associate and disassociate a driver with
|
||||||
|
an interface. A driver's bond to an interface is exclusive.
|
||||||
|
|
||||||
|
The probe() callback
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
int (*probe) (struct usb_interface *intf,
|
||||||
|
const struct usb_device_id *id);
|
||||||
|
|
||||||
|
Accept or decline an interface. If you accept the device return 0,
|
||||||
|
otherwise -ENODEV or -ENXIO. Other error codes should be used only if a
|
||||||
|
genuine error occurred during initialisation which prevented a driver
|
||||||
|
from accepting a device that would else have been accepted.
|
||||||
|
You are strongly encouraged to use usbcore'sfacility,
|
||||||
|
usb_set_intfdata(), to associate a data structure with an interface, so
|
||||||
|
that you know which internal state and identity you associate with a
|
||||||
|
particular interface. The device will not be suspended and you may do IO
|
||||||
|
to the interface you are called for and endpoint 0 of the device. Device
|
||||||
|
initialisation that doesn't take too long is a good idea here.
|
||||||
|
|
||||||
|
The disconnect() callback
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
void (*disconnect) (struct usb_interface *intf);
|
||||||
|
|
||||||
|
This callback is a signal to break any connection with an interface.
|
||||||
|
You are not allowed any IO to a device after returning from this
|
||||||
|
callback. You also may not do any other operation that may interfere
|
||||||
|
with another driver bound the interface, eg. a power management
|
||||||
|
operation.
|
||||||
|
If you are called due to a physical disconnection, all your URBs will be
|
||||||
|
killed by usbcore. Note that in this case disconnect will be called some
|
||||||
|
time after the physical disconnection. Thus your driver must be prepared
|
||||||
|
to deal with failing IO even prior to the callback.
|
||||||
|
|
||||||
|
Device level callbacks
|
||||||
|
======================
|
||||||
|
|
||||||
|
pre_reset
|
||||||
|
---------
|
||||||
|
|
||||||
|
int (*pre_reset)(struct usb_interface *intf);
|
||||||
|
|
||||||
|
Another driver or user space is triggering a reset on the device which
|
||||||
|
contains the interface passed as an argument. Cease IO and save any
|
||||||
|
device state you need to restore.
|
||||||
|
|
||||||
|
If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if you
|
||||||
|
are in atomic context.
|
||||||
|
|
||||||
|
post_reset
|
||||||
|
----------
|
||||||
|
|
||||||
|
int (*post_reset)(struct usb_interface *intf);
|
||||||
|
|
||||||
|
The reset has completed. Restore any saved device state and begin
|
||||||
|
using the device again.
|
||||||
|
|
||||||
|
If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if you
|
||||||
|
are in atomic context.
|
||||||
|
|
||||||
|
Call sequences
|
||||||
|
==============
|
||||||
|
|
||||||
|
No callbacks other than probe will be invoked for an interface
|
||||||
|
that isn't bound to your driver.
|
||||||
|
|
||||||
|
Probe will never be called for an interface bound to a driver.
|
||||||
|
Hence following a successful probe, disconnect will be called
|
||||||
|
before there is another probe for the same interface.
|
||||||
|
|
||||||
|
Once your driver is bound to an interface, disconnect can be
|
||||||
|
called at any time except in between pre_reset and post_reset.
|
||||||
|
pre_reset is always followed by post_reset, even if the reset
|
||||||
|
failed or the device has been unplugged.
|
||||||
|
|
||||||
|
suspend is always followed by one of: resume, reset_resume, or
|
||||||
|
disconnect.
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Alan Stern <stern@rowland.harvard.edu>
|
Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
|
||||||
September 2, 2006 (Updated May 29, 2007)
|
September 2, 2006 (Updated February 25, 2008)
|
||||||
|
|
||||||
|
|
||||||
What is the problem?
|
What is the problem?
|
||||||
@ -65,9 +65,10 @@ much better.)
|
|||||||
|
|
||||||
What is the solution?
|
What is the solution?
|
||||||
|
|
||||||
Setting CONFIG_USB_PERSIST will cause the kernel to work around these
|
The kernel includes a feature called USB-persist. It tries to work
|
||||||
issues. It enables a mode in which the core USB device data
|
around these issues by allowing the core USB device data structures to
|
||||||
structures are allowed to persist across a power-session disruption.
|
persist across a power-session disruption.
|
||||||
|
|
||||||
It works like this. If the kernel sees that a USB host controller is
|
It works like this. If the kernel sees that a USB host controller is
|
||||||
not in the expected state during resume (i.e., if the controller was
|
not in the expected state during resume (i.e., if the controller was
|
||||||
reset or otherwise had lost power) then it applies a persistence check
|
reset or otherwise had lost power) then it applies a persistence check
|
||||||
@ -80,28 +81,30 @@ re-enumeration shows that the device now attached to that port has the
|
|||||||
same descriptors as before, including the Vendor and Product IDs, then
|
same descriptors as before, including the Vendor and Product IDs, then
|
||||||
the kernel continues to use the same device structure. In effect, the
|
the kernel continues to use the same device structure. In effect, the
|
||||||
kernel treats the device as though it had merely been reset instead of
|
kernel treats the device as though it had merely been reset instead of
|
||||||
unplugged.
|
unplugged. The same thing happens if the host controller is in the
|
||||||
|
expected state but a USB device was unplugged and then replugged.
|
||||||
|
|
||||||
If no device is now attached to the port, or if the descriptors are
|
If no device is now attached to the port, or if the descriptors are
|
||||||
different from what the kernel remembers, then the treatment is what
|
different from what the kernel remembers, then the treatment is what
|
||||||
you would expect. The kernel destroys the old device structure and
|
you would expect. The kernel destroys the old device structure and
|
||||||
behaves as though the old device had been unplugged and a new device
|
behaves as though the old device had been unplugged and a new device
|
||||||
plugged in, just as it would without the CONFIG_USB_PERSIST option.
|
plugged in.
|
||||||
|
|
||||||
The end result is that the USB device remains available and usable.
|
The end result is that the USB device remains available and usable.
|
||||||
Filesystem mounts and memory mappings are unaffected, and the world is
|
Filesystem mounts and memory mappings are unaffected, and the world is
|
||||||
now a good and happy place.
|
now a good and happy place.
|
||||||
|
|
||||||
Note that even when CONFIG_USB_PERSIST is set, the "persist" feature
|
Note that the "USB-persist" feature will be applied only to those
|
||||||
will be applied only to those devices for which it is enabled. You
|
devices for which it is enabled. You can enable the feature by doing
|
||||||
can enable the feature by doing (as root):
|
(as root):
|
||||||
|
|
||||||
echo 1 >/sys/bus/usb/devices/.../power/persist
|
echo 1 >/sys/bus/usb/devices/.../power/persist
|
||||||
|
|
||||||
where the "..." should be filled in the with the device's ID. Disable
|
where the "..." should be filled in the with the device's ID. Disable
|
||||||
the feature by writing 0 instead of 1. For hubs the feature is
|
the feature by writing 0 instead of 1. For hubs the feature is
|
||||||
automatically and permanently enabled, so you only have to worry about
|
automatically and permanently enabled and the power/persist file
|
||||||
setting it for devices where it really matters.
|
doesn't even exist, so you only have to worry about setting it for
|
||||||
|
devices where it really matters.
|
||||||
|
|
||||||
|
|
||||||
Is this the best solution?
|
Is this the best solution?
|
||||||
@ -112,19 +115,19 @@ centralized Logical Volume Manager. Such a solution would allow you
|
|||||||
to plug in a USB flash device, create a persistent volume associated
|
to plug in a USB flash device, create a persistent volume associated
|
||||||
with it, unplug the flash device, plug it back in later, and still
|
with it, unplug the flash device, plug it back in later, and still
|
||||||
have the same persistent volume associated with the device. As such
|
have the same persistent volume associated with the device. As such
|
||||||
it would be more far-reaching than CONFIG_USB_PERSIST.
|
it would be more far-reaching than USB-persist.
|
||||||
|
|
||||||
On the other hand, writing a persistent volume manager would be a big
|
On the other hand, writing a persistent volume manager would be a big
|
||||||
job and using it would require significant input from the user. This
|
job and using it would require significant input from the user. This
|
||||||
solution is much quicker and easier -- and it exists now, a giant
|
solution is much quicker and easier -- and it exists now, a giant
|
||||||
point in its favor!
|
point in its favor!
|
||||||
|
|
||||||
Furthermore, the USB_PERSIST option applies to _all_ USB devices, not
|
Furthermore, the USB-persist feature applies to _all_ USB devices, not
|
||||||
just mass-storage devices. It might turn out to be equally useful for
|
just mass-storage devices. It might turn out to be equally useful for
|
||||||
other device types, such as network interfaces.
|
other device types, such as network interfaces.
|
||||||
|
|
||||||
|
|
||||||
WARNING: Using CONFIG_USB_PERSIST can be dangerous!!
|
WARNING: USB-persist can be dangerous!!
|
||||||
|
|
||||||
When recovering an interrupted power session the kernel does its best
|
When recovering an interrupted power session the kernel does its best
|
||||||
to make sure the USB device hasn't been changed; that is, the same
|
to make sure the USB device hasn't been changed; that is, the same
|
||||||
@ -133,10 +136,10 @@ aren't guaranteed to be 100% accurate.
|
|||||||
|
|
||||||
If you replace one USB device with another of the same type (same
|
If you replace one USB device with another of the same type (same
|
||||||
manufacturer, same IDs, and so on) there's an excellent chance the
|
manufacturer, same IDs, and so on) there's an excellent chance the
|
||||||
kernel won't detect the change. Serial numbers and other strings are
|
kernel won't detect the change. The serial number string and other
|
||||||
not compared. In many cases it wouldn't help if they were, because
|
descriptors are compared with the kernel's stored values, but this
|
||||||
manufacturers frequently omit serial numbers entirely in their
|
might not help since manufacturers frequently omit serial numbers
|
||||||
devices.
|
entirely in their devices.
|
||||||
|
|
||||||
Furthermore it's quite possible to leave a USB device exactly the same
|
Furthermore it's quite possible to leave a USB device exactly the same
|
||||||
while changing its media. If you replace the flash memory card in a
|
while changing its media. If you replace the flash memory card in a
|
||||||
@ -152,5 +155,5 @@ but yourself.
|
|||||||
YOU HAVE BEEN WARNED! USE AT YOUR OWN RISK!
|
YOU HAVE BEEN WARNED! USE AT YOUR OWN RISK!
|
||||||
|
|
||||||
That having been said, most of the time there shouldn't be any trouble
|
That having been said, most of the time there shouldn't be any trouble
|
||||||
at all. The "persist" feature can be extremely useful. Make the most
|
at all. The USB-persist feature can be extremely useful. Make the
|
||||||
of it.
|
most of it.
|
||||||
|
@ -192,12 +192,9 @@ Keyspan USA-series Serial Adapters
|
|||||||
|
|
||||||
FTDI Single Port Serial Driver
|
FTDI Single Port Serial Driver
|
||||||
|
|
||||||
This is a single port DB-25 serial adapter. More information about this
|
This is a single port DB-25 serial adapter.
|
||||||
device and the Linux driver can be found at:
|
|
||||||
http://reality.sgi.com/bryder_wellington/ftdi_sio/
|
|
||||||
|
|
||||||
For any questions or problems with this driver, please contact Bill Ryder
|
For any questions or problems with this driver, please contact Bill Ryder.
|
||||||
at bryder@sgi.com
|
|
||||||
|
|
||||||
|
|
||||||
ZyXEL omni.net lcd plus ISDN TA
|
ZyXEL omni.net lcd plus ISDN TA
|
||||||
|
@ -405,9 +405,11 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
|
|||||||
static void xpad_irq_in(struct urb *urb)
|
static void xpad_irq_in(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct usb_xpad *xpad = urb->context;
|
struct usb_xpad *xpad = urb->context;
|
||||||
int retval;
|
int retval, status;
|
||||||
|
|
||||||
switch (urb->status) {
|
status = urb->status;
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
/* success */
|
/* success */
|
||||||
break;
|
break;
|
||||||
@ -416,11 +418,11 @@ static void xpad_irq_in(struct urb *urb)
|
|||||||
case -ESHUTDOWN:
|
case -ESHUTDOWN:
|
||||||
/* this urb is terminated, clean up */
|
/* this urb is terminated, clean up */
|
||||||
dbg("%s - urb shutting down with status: %d",
|
dbg("%s - urb shutting down with status: %d",
|
||||||
__FUNCTION__, urb->status);
|
__FUNCTION__, status);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
dbg("%s - nonzero urb status received: %d",
|
dbg("%s - nonzero urb status received: %d",
|
||||||
__FUNCTION__, urb->status);
|
__FUNCTION__, status);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,9 +447,11 @@ static void xpad_irq_in(struct urb *urb)
|
|||||||
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
||||||
static void xpad_irq_out(struct urb *urb)
|
static void xpad_irq_out(struct urb *urb)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval, status;
|
||||||
|
|
||||||
switch (urb->status) {
|
status = urb->status;
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
/* success */
|
/* success */
|
||||||
break;
|
break;
|
||||||
@ -456,11 +460,11 @@ static void xpad_irq_out(struct urb *urb)
|
|||||||
case -ESHUTDOWN:
|
case -ESHUTDOWN:
|
||||||
/* this urb is terminated, clean up */
|
/* this urb is terminated, clean up */
|
||||||
dbg("%s - urb shutting down with status: %d",
|
dbg("%s - urb shutting down with status: %d",
|
||||||
__FUNCTION__, urb->status);
|
__FUNCTION__, status);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
dbg("%s - nonzero urb status received: %d",
|
dbg("%s - nonzero urb status received: %d",
|
||||||
__FUNCTION__, urb->status);
|
__FUNCTION__, status);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +444,7 @@ CXACRU_ALL_FILES(INIT);
|
|||||||
/* the following three functions are stolen from drivers/usb/core/message.c */
|
/* the following three functions are stolen from drivers/usb/core/message.c */
|
||||||
static void cxacru_blocking_completion(struct urb *urb)
|
static void cxacru_blocking_completion(struct urb *urb)
|
||||||
{
|
{
|
||||||
complete((struct completion *)urb->context);
|
complete(urb->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cxacru_timeout_kill(unsigned long data)
|
static void cxacru_timeout_kill(unsigned long data)
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
if (debug >= 1) \
|
if (debug >= 1) \
|
||||||
dev_dbg(&(usb_dev)->dev, \
|
dev_dbg(&(usb_dev)->dev, \
|
||||||
"[ueagle-atm dbg] %s: " format, \
|
"[ueagle-atm dbg] %s: " format, \
|
||||||
__FUNCTION__, ##args); \
|
__func__, ##args); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define uea_vdbg(usb_dev, format, args...) \
|
#define uea_vdbg(usb_dev, format, args...) \
|
||||||
@ -94,10 +94,10 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define uea_enters(usb_dev) \
|
#define uea_enters(usb_dev) \
|
||||||
uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__)
|
uea_vdbg(usb_dev, "entering %s\n", __func__)
|
||||||
|
|
||||||
#define uea_leaves(usb_dev) \
|
#define uea_leaves(usb_dev) \
|
||||||
uea_vdbg(usb_dev, "leaving %s\n", __FUNCTION__)
|
uea_vdbg(usb_dev, "leaving %s\n", __func__)
|
||||||
|
|
||||||
#define uea_err(usb_dev, format,args...) \
|
#define uea_err(usb_dev, format,args...) \
|
||||||
dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args)
|
dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args)
|
||||||
|
@ -80,6 +80,7 @@
|
|||||||
#include <linux/stat.h>
|
#include <linux/stat.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
|
|
||||||
#ifdef VERBOSE_DEBUG
|
#ifdef VERBOSE_DEBUG
|
||||||
static int usbatm_print_packet(const unsigned char *data, int len);
|
static int usbatm_print_packet(const unsigned char *data, int len);
|
||||||
@ -1014,10 +1015,7 @@ static int usbatm_do_heavy_init(void *arg)
|
|||||||
struct usbatm_data *instance = arg;
|
struct usbatm_data *instance = arg;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
daemonize(instance->driver->driver_name);
|
|
||||||
allow_signal(SIGTERM);
|
allow_signal(SIGTERM);
|
||||||
instance->thread_pid = current->pid;
|
|
||||||
|
|
||||||
complete(&instance->thread_started);
|
complete(&instance->thread_started);
|
||||||
|
|
||||||
ret = instance->driver->heavy_init(instance, instance->usb_intf);
|
ret = instance->driver->heavy_init(instance, instance->usb_intf);
|
||||||
@ -1026,7 +1024,7 @@ static int usbatm_do_heavy_init(void *arg)
|
|||||||
ret = usbatm_atm_init(instance);
|
ret = usbatm_atm_init(instance);
|
||||||
|
|
||||||
mutex_lock(&instance->serialize);
|
mutex_lock(&instance->serialize);
|
||||||
instance->thread_pid = -1;
|
instance->thread = NULL;
|
||||||
mutex_unlock(&instance->serialize);
|
mutex_unlock(&instance->serialize);
|
||||||
|
|
||||||
complete_and_exit(&instance->thread_exited, ret);
|
complete_and_exit(&instance->thread_exited, ret);
|
||||||
@ -1034,13 +1032,18 @@ static int usbatm_do_heavy_init(void *arg)
|
|||||||
|
|
||||||
static int usbatm_heavy_init(struct usbatm_data *instance)
|
static int usbatm_heavy_init(struct usbatm_data *instance)
|
||||||
{
|
{
|
||||||
int ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_FS | CLONE_FILES);
|
struct task_struct *t;
|
||||||
|
|
||||||
if (ret < 0) {
|
t = kthread_create(usbatm_do_heavy_init, instance,
|
||||||
usb_err(instance, "%s: failed to create kernel_thread (%d)!\n", __func__, ret);
|
instance->driver->driver_name);
|
||||||
return ret;
|
if (IS_ERR(t)) {
|
||||||
|
usb_err(instance, "%s: failed to create kernel_thread (%ld)!\n",
|
||||||
|
__func__, PTR_ERR(t));
|
||||||
|
return PTR_ERR(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance->thread = t;
|
||||||
|
wake_up_process(t);
|
||||||
wait_for_completion(&instance->thread_started);
|
wait_for_completion(&instance->thread_started);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1124,7 +1127,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
|
|||||||
kref_init(&instance->refcount); /* dropped in usbatm_usb_disconnect */
|
kref_init(&instance->refcount); /* dropped in usbatm_usb_disconnect */
|
||||||
mutex_init(&instance->serialize);
|
mutex_init(&instance->serialize);
|
||||||
|
|
||||||
instance->thread_pid = -1;
|
instance->thread = NULL;
|
||||||
init_completion(&instance->thread_started);
|
init_completion(&instance->thread_started);
|
||||||
init_completion(&instance->thread_exited);
|
init_completion(&instance->thread_exited);
|
||||||
|
|
||||||
@ -1287,8 +1290,8 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
|
|||||||
|
|
||||||
mutex_lock(&instance->serialize);
|
mutex_lock(&instance->serialize);
|
||||||
instance->disconnected = 1;
|
instance->disconnected = 1;
|
||||||
if (instance->thread_pid >= 0)
|
if (instance->thread != NULL)
|
||||||
kill_proc(instance->thread_pid, SIGTERM, 1);
|
send_sig(SIGTERM, instance->thread, 1);
|
||||||
mutex_unlock(&instance->serialize);
|
mutex_unlock(&instance->serialize);
|
||||||
|
|
||||||
wait_for_completion(&instance->thread_exited);
|
wait_for_completion(&instance->thread_exited);
|
||||||
|
@ -175,7 +175,7 @@ struct usbatm_data {
|
|||||||
int disconnected;
|
int disconnected;
|
||||||
|
|
||||||
/* heavy init */
|
/* heavy init */
|
||||||
int thread_pid;
|
struct task_struct *thread;
|
||||||
struct completion thread_started;
|
struct completion thread_started;
|
||||||
struct completion thread_exited;
|
struct completion thread_exited;
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
* v0.23 - use softirq for rx processing, as needed by tty layer
|
* v0.23 - use softirq for rx processing, as needed by tty layer
|
||||||
* v0.24 - change probe method to evaluate CDC union descriptor
|
* v0.24 - change probe method to evaluate CDC union descriptor
|
||||||
* v0.25 - downstream tasks paralelized to maximize throughput
|
* v0.25 - downstream tasks paralelized to maximize throughput
|
||||||
|
* v0.26 - multiple write urbs, writesize increased
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -72,7 +73,7 @@
|
|||||||
/*
|
/*
|
||||||
* Version Information
|
* Version Information
|
||||||
*/
|
*/
|
||||||
#define DRIVER_VERSION "v0.25"
|
#define DRIVER_VERSION "v0.26"
|
||||||
#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek"
|
#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek"
|
||||||
#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
|
#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
|
||||||
|
|
||||||
@ -118,7 +119,7 @@ static int acm_wb_alloc(struct acm *acm)
|
|||||||
int i, wbn;
|
int i, wbn;
|
||||||
struct acm_wb *wb;
|
struct acm_wb *wb;
|
||||||
|
|
||||||
wbn = acm->write_current;
|
wbn = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
wb = &acm->wb[wbn];
|
wb = &acm->wb[wbn];
|
||||||
@ -132,11 +133,6 @@ static int acm_wb_alloc(struct acm *acm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void acm_wb_free(struct acm *acm, int wbn)
|
|
||||||
{
|
|
||||||
acm->wb[wbn].use = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int acm_wb_is_avail(struct acm *acm)
|
static int acm_wb_is_avail(struct acm *acm)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
@ -156,26 +152,22 @@ static inline int acm_wb_is_used(struct acm *acm, int wbn)
|
|||||||
/*
|
/*
|
||||||
* Finish write.
|
* Finish write.
|
||||||
*/
|
*/
|
||||||
static void acm_write_done(struct acm *acm)
|
static void acm_write_done(struct acm *acm, struct acm_wb *wb)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int wbn;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&acm->write_lock, flags);
|
spin_lock_irqsave(&acm->write_lock, flags);
|
||||||
acm->write_ready = 1;
|
acm->write_ready = 1;
|
||||||
wbn = acm->write_current;
|
wb->use = 0;
|
||||||
acm_wb_free(acm, wbn);
|
|
||||||
acm->write_current = (wbn + 1) % ACM_NW;
|
|
||||||
spin_unlock_irqrestore(&acm->write_lock, flags);
|
spin_unlock_irqrestore(&acm->write_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Poke write.
|
* Poke write.
|
||||||
*/
|
*/
|
||||||
static int acm_write_start(struct acm *acm)
|
static int acm_write_start(struct acm *acm, int wbn)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int wbn;
|
|
||||||
struct acm_wb *wb;
|
struct acm_wb *wb;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -190,24 +182,24 @@ static int acm_write_start(struct acm *acm)
|
|||||||
return 0; /* A white lie */
|
return 0; /* A white lie */
|
||||||
}
|
}
|
||||||
|
|
||||||
wbn = acm->write_current;
|
|
||||||
if (!acm_wb_is_used(acm, wbn)) {
|
if (!acm_wb_is_used(acm, wbn)) {
|
||||||
spin_unlock_irqrestore(&acm->write_lock, flags);
|
spin_unlock_irqrestore(&acm->write_lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
wb = &acm->wb[wbn];
|
wb = &acm->wb[wbn];
|
||||||
|
|
||||||
acm->write_ready = 0;
|
if(acm_wb_is_avail(acm) <= 1)
|
||||||
|
acm->write_ready = 0;
|
||||||
spin_unlock_irqrestore(&acm->write_lock, flags);
|
spin_unlock_irqrestore(&acm->write_lock, flags);
|
||||||
|
|
||||||
acm->writeurb->transfer_buffer = wb->buf;
|
wb->urb->transfer_buffer = wb->buf;
|
||||||
acm->writeurb->transfer_dma = wb->dmah;
|
wb->urb->transfer_dma = wb->dmah;
|
||||||
acm->writeurb->transfer_buffer_length = wb->len;
|
wb->urb->transfer_buffer_length = wb->len;
|
||||||
acm->writeurb->dev = acm->dev;
|
wb->urb->dev = acm->dev;
|
||||||
|
|
||||||
if ((rc = usb_submit_urb(acm->writeurb, GFP_ATOMIC)) < 0) {
|
if ((rc = usb_submit_urb(wb->urb, GFP_ATOMIC)) < 0) {
|
||||||
dbg("usb_submit_urb(write bulk) failed: %d", rc);
|
dbg("usb_submit_urb(write bulk) failed: %d", rc);
|
||||||
acm_write_done(acm);
|
acm_write_done(acm, wb);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -268,10 +260,10 @@ static void acm_ctrl_irq(struct urb *urb)
|
|||||||
case -ENOENT:
|
case -ENOENT:
|
||||||
case -ESHUTDOWN:
|
case -ESHUTDOWN:
|
||||||
/* this urb is terminated, clean up */
|
/* this urb is terminated, clean up */
|
||||||
dbg("%s - urb shutting down with status: %d", __FUNCTION__, status);
|
dbg("%s - urb shutting down with status: %d", __func__, status);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
dbg("%s - nonzero urb status received: %d", __FUNCTION__, status);
|
dbg("%s - nonzero urb status received: %d", __func__, status);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +307,7 @@ static void acm_ctrl_irq(struct urb *urb)
|
|||||||
retval = usb_submit_urb (urb, GFP_ATOMIC);
|
retval = usb_submit_urb (urb, GFP_ATOMIC);
|
||||||
if (retval)
|
if (retval)
|
||||||
err ("%s - usb_submit_urb failed with result %d",
|
err ("%s - usb_submit_urb failed with result %d",
|
||||||
__FUNCTION__, retval);
|
__func__, retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* data interface returns incoming bytes, or we got unthrottled */
|
/* data interface returns incoming bytes, or we got unthrottled */
|
||||||
@ -450,12 +442,13 @@ static void acm_rx_tasklet(unsigned long _acm)
|
|||||||
/* data interface wrote those outgoing bytes */
|
/* data interface wrote those outgoing bytes */
|
||||||
static void acm_write_bulk(struct urb *urb)
|
static void acm_write_bulk(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct acm *acm = (struct acm *)urb->context;
|
struct acm *acm;
|
||||||
|
struct acm_wb *wb = urb->context;
|
||||||
|
|
||||||
dbg("Entering acm_write_bulk with status %d", urb->status);
|
dbg("Entering acm_write_bulk with status %d", urb->status);
|
||||||
|
|
||||||
acm_write_done(acm);
|
acm = wb->instance;
|
||||||
acm_write_start(acm);
|
acm_write_done(acm, wb);
|
||||||
if (ACM_READY(acm))
|
if (ACM_READY(acm))
|
||||||
schedule_work(&acm->work);
|
schedule_work(&acm->work);
|
||||||
}
|
}
|
||||||
@ -489,6 +482,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
|
|||||||
else
|
else
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
|
||||||
|
set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
|
||||||
tty->driver_data = acm;
|
tty->driver_data = acm;
|
||||||
acm->tty = tty;
|
acm->tty = tty;
|
||||||
|
|
||||||
@ -556,7 +550,8 @@ static void acm_tty_unregister(struct acm *acm)
|
|||||||
usb_put_intf(acm->control);
|
usb_put_intf(acm->control);
|
||||||
acm_table[acm->minor] = NULL;
|
acm_table[acm->minor] = NULL;
|
||||||
usb_free_urb(acm->ctrlurb);
|
usb_free_urb(acm->ctrlurb);
|
||||||
usb_free_urb(acm->writeurb);
|
for (i = 0; i < ACM_NW; i++)
|
||||||
|
usb_free_urb(acm->wb[i].urb);
|
||||||
for (i = 0; i < nr; i++)
|
for (i = 0; i < nr; i++)
|
||||||
usb_free_urb(acm->ru[i].urb);
|
usb_free_urb(acm->ru[i].urb);
|
||||||
kfree(acm->country_codes);
|
kfree(acm->country_codes);
|
||||||
@ -577,7 +572,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
|
|||||||
if (acm->dev) {
|
if (acm->dev) {
|
||||||
acm_set_control(acm, acm->ctrlout = 0);
|
acm_set_control(acm, acm->ctrlout = 0);
|
||||||
usb_kill_urb(acm->ctrlurb);
|
usb_kill_urb(acm->ctrlurb);
|
||||||
usb_kill_urb(acm->writeurb);
|
for (i = 0; i < ACM_NW; i++)
|
||||||
|
usb_kill_urb(acm->wb[i].urb);
|
||||||
for (i = 0; i < nr; i++)
|
for (i = 0; i < nr; i++)
|
||||||
usb_kill_urb(acm->ru[i].urb);
|
usb_kill_urb(acm->ru[i].urb);
|
||||||
usb_autopm_put_interface(acm->control);
|
usb_autopm_put_interface(acm->control);
|
||||||
@ -605,7 +601,6 @@ static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
|
|||||||
spin_lock_irqsave(&acm->write_lock, flags);
|
spin_lock_irqsave(&acm->write_lock, flags);
|
||||||
if ((wbn = acm_wb_alloc(acm)) < 0) {
|
if ((wbn = acm_wb_alloc(acm)) < 0) {
|
||||||
spin_unlock_irqrestore(&acm->write_lock, flags);
|
spin_unlock_irqrestore(&acm->write_lock, flags);
|
||||||
acm_write_start(acm);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
wb = &acm->wb[wbn];
|
wb = &acm->wb[wbn];
|
||||||
@ -616,7 +611,7 @@ static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
|
|||||||
wb->len = count;
|
wb->len = count;
|
||||||
spin_unlock_irqrestore(&acm->write_lock, flags);
|
spin_unlock_irqrestore(&acm->write_lock, flags);
|
||||||
|
|
||||||
if ((stat = acm_write_start(acm)) < 0)
|
if ((stat = acm_write_start(acm, wbn)) < 0)
|
||||||
return stat;
|
return stat;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@ -809,7 +804,7 @@ static int acm_probe (struct usb_interface *intf,
|
|||||||
{
|
{
|
||||||
struct usb_cdc_union_desc *union_header = NULL;
|
struct usb_cdc_union_desc *union_header = NULL;
|
||||||
struct usb_cdc_country_functional_desc *cfd = NULL;
|
struct usb_cdc_country_functional_desc *cfd = NULL;
|
||||||
char *buffer = intf->altsetting->extra;
|
unsigned char *buffer = intf->altsetting->extra;
|
||||||
int buflen = intf->altsetting->extralen;
|
int buflen = intf->altsetting->extralen;
|
||||||
struct usb_interface *control_interface;
|
struct usb_interface *control_interface;
|
||||||
struct usb_interface *data_interface;
|
struct usb_interface *data_interface;
|
||||||
@ -886,9 +881,13 @@ static int acm_probe (struct usb_interface *intf,
|
|||||||
if ((call_management_function & 3) != 3)
|
if ((call_management_function & 3) != 3)
|
||||||
err("This device cannot do calls on its own. It is no modem.");
|
err("This device cannot do calls on its own. It is no modem.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
err("Ignoring extra header, type %d, length %d", buffer[2], buffer[0]);
|
/* there are LOTS more CDC descriptors that
|
||||||
|
* could legitimately be found here.
|
||||||
|
*/
|
||||||
|
dev_dbg(&intf->dev, "Ignoring descriptor: "
|
||||||
|
"type %02x, length %d\n",
|
||||||
|
buffer[2], buffer[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
next_desc:
|
next_desc:
|
||||||
@ -976,7 +975,7 @@ static int acm_probe (struct usb_interface *intf,
|
|||||||
|
|
||||||
ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
|
ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
|
||||||
readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2);
|
readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2);
|
||||||
acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
|
acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize) * 20;
|
||||||
acm->control = control_interface;
|
acm->control = control_interface;
|
||||||
acm->data = data_interface;
|
acm->data = data_interface;
|
||||||
acm->minor = minor;
|
acm->minor = minor;
|
||||||
@ -1031,10 +1030,19 @@ static int acm_probe (struct usb_interface *intf,
|
|||||||
goto alloc_fail7;
|
goto alloc_fail7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
|
for(i = 0; i < ACM_NW; i++)
|
||||||
if (!acm->writeurb) {
|
{
|
||||||
dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n");
|
struct acm_wb *snd = &(acm->wb[i]);
|
||||||
goto alloc_fail7;
|
|
||||||
|
if (!(snd->urb = usb_alloc_urb(0, GFP_KERNEL))) {
|
||||||
|
dev_dbg(&intf->dev, "out of memory (write urbs usb_alloc_urb)");
|
||||||
|
goto alloc_fail7;
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_fill_bulk_urb(snd->urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
|
||||||
|
NULL, acm->writesize, acm_write_bulk, snd);
|
||||||
|
snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||||
|
snd->instance = acm;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_set_intfdata (intf, acm);
|
usb_set_intfdata (intf, acm);
|
||||||
@ -1070,10 +1078,6 @@ static int acm_probe (struct usb_interface *intf,
|
|||||||
acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||||
acm->ctrlurb->transfer_dma = acm->ctrl_dma;
|
acm->ctrlurb->transfer_dma = acm->ctrl_dma;
|
||||||
|
|
||||||
usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
|
|
||||||
NULL, acm->writesize, acm_write_bulk, acm);
|
|
||||||
acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
|
|
||||||
|
|
||||||
dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
|
dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
|
||||||
|
|
||||||
acm_set_control(acm, acm->ctrlout);
|
acm_set_control(acm, acm->ctrlout);
|
||||||
@ -1091,7 +1095,8 @@ static int acm_probe (struct usb_interface *intf,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
alloc_fail8:
|
alloc_fail8:
|
||||||
usb_free_urb(acm->writeurb);
|
for (i = 0; i < ACM_NW; i++)
|
||||||
|
usb_free_urb(acm->wb[i].urb);
|
||||||
alloc_fail7:
|
alloc_fail7:
|
||||||
for (i = 0; i < num_rx_buf; i++)
|
for (i = 0; i < num_rx_buf; i++)
|
||||||
usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
|
usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
|
||||||
@ -1115,7 +1120,8 @@ static void stop_data_traffic(struct acm *acm)
|
|||||||
tasklet_disable(&acm->urb_task);
|
tasklet_disable(&acm->urb_task);
|
||||||
|
|
||||||
usb_kill_urb(acm->ctrlurb);
|
usb_kill_urb(acm->ctrlurb);
|
||||||
usb_kill_urb(acm->writeurb);
|
for(i = 0; i < ACM_NW; i++)
|
||||||
|
usb_kill_urb(acm->wb[i].urb);
|
||||||
for (i = 0; i < acm->rx_buflimit; i++)
|
for (i = 0; i < acm->rx_buflimit; i++)
|
||||||
usb_kill_urb(acm->ru[i].urb);
|
usb_kill_urb(acm->ru[i].urb);
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
* when processing onlcr, so we only need 2 buffers. These values must be
|
* when processing onlcr, so we only need 2 buffers. These values must be
|
||||||
* powers of 2.
|
* powers of 2.
|
||||||
*/
|
*/
|
||||||
#define ACM_NW 2
|
#define ACM_NW 16
|
||||||
#define ACM_NR 16
|
#define ACM_NR 16
|
||||||
|
|
||||||
struct acm_wb {
|
struct acm_wb {
|
||||||
@ -67,6 +67,8 @@ struct acm_wb {
|
|||||||
dma_addr_t dmah;
|
dma_addr_t dmah;
|
||||||
int len;
|
int len;
|
||||||
int use;
|
int use;
|
||||||
|
struct urb *urb;
|
||||||
|
struct acm *instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct acm_rb {
|
struct acm_rb {
|
||||||
@ -88,7 +90,7 @@ struct acm {
|
|||||||
struct usb_interface *control; /* control interface */
|
struct usb_interface *control; /* control interface */
|
||||||
struct usb_interface *data; /* data interface */
|
struct usb_interface *data; /* data interface */
|
||||||
struct tty_struct *tty; /* the corresponding tty */
|
struct tty_struct *tty; /* the corresponding tty */
|
||||||
struct urb *ctrlurb, *writeurb; /* urbs */
|
struct urb *ctrlurb; /* urbs */
|
||||||
u8 *ctrl_buffer; /* buffers of urbs */
|
u8 *ctrl_buffer; /* buffers of urbs */
|
||||||
dma_addr_t ctrl_dma; /* dma handles of buffers */
|
dma_addr_t ctrl_dma; /* dma handles of buffers */
|
||||||
u8 *country_codes; /* country codes from device */
|
u8 *country_codes; /* country codes from device */
|
||||||
@ -103,7 +105,6 @@ struct acm {
|
|||||||
struct list_head spare_read_urbs;
|
struct list_head spare_read_urbs;
|
||||||
struct list_head spare_read_bufs;
|
struct list_head spare_read_bufs;
|
||||||
struct list_head filled_read_bufs;
|
struct list_head filled_read_bufs;
|
||||||
int write_current; /* current write buffer */
|
|
||||||
int write_used; /* number of non-empty write buffers */
|
int write_used; /* number of non-empty write buffers */
|
||||||
int write_ready; /* write urb is not running */
|
int write_ready; /* write urb is not running */
|
||||||
spinlock_t write_lock;
|
spinlock_t write_lock;
|
||||||
|
@ -76,8 +76,8 @@ config USB_DEVICE_CLASS
|
|||||||
NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"
|
NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"
|
||||||
|
|
||||||
config USB_DYNAMIC_MINORS
|
config USB_DYNAMIC_MINORS
|
||||||
bool "Dynamic USB minor allocation (EXPERIMENTAL)"
|
bool "Dynamic USB minor allocation"
|
||||||
depends on USB && EXPERIMENTAL
|
depends on USB
|
||||||
help
|
help
|
||||||
If you say Y here, the USB subsystem will use dynamic minor
|
If you say Y here, the USB subsystem will use dynamic minor
|
||||||
allocation for any device that uses the USB major number.
|
allocation for any device that uses the USB major number.
|
||||||
@ -102,31 +102,6 @@ config USB_SUSPEND
|
|||||||
|
|
||||||
If you are unsure about this, say N here.
|
If you are unsure about this, say N here.
|
||||||
|
|
||||||
config USB_PERSIST
|
|
||||||
bool "USB device persistence during system suspend (DANGEROUS)"
|
|
||||||
depends on USB && PM && EXPERIMENTAL
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
|
|
||||||
If you say Y here and enable the "power/persist" attribute
|
|
||||||
for a USB device, the device's data structures will remain
|
|
||||||
persistent across system suspend, even if the USB bus loses
|
|
||||||
power. (This includes hibernation, also known as swsusp or
|
|
||||||
suspend-to-disk.) The devices will reappear as if by magic
|
|
||||||
when the system wakes up, with no need to unmount USB
|
|
||||||
filesystems, rmmod host-controller drivers, or do anything
|
|
||||||
else.
|
|
||||||
|
|
||||||
WARNING: This option can be dangerous!
|
|
||||||
|
|
||||||
If a USB device is replaced by another of the same type while
|
|
||||||
the system is asleep, there's a good chance the kernel won't
|
|
||||||
detect the change. Likewise if the media in a USB storage
|
|
||||||
device is replaced. When this happens it's almost certain to
|
|
||||||
cause data corruption and maybe even crash your system.
|
|
||||||
|
|
||||||
If you are unsure, say N here.
|
|
||||||
|
|
||||||
config USB_OTG
|
config USB_OTG
|
||||||
bool
|
bool
|
||||||
depends on USB && EXPERIMENTAL
|
depends on USB && EXPERIMENTAL
|
||||||
@ -136,14 +111,16 @@ config USB_OTG
|
|||||||
|
|
||||||
config USB_OTG_WHITELIST
|
config USB_OTG_WHITELIST
|
||||||
bool "Rely on OTG Targeted Peripherals List"
|
bool "Rely on OTG Targeted Peripherals List"
|
||||||
depends on USB_OTG
|
depends on USB_OTG || EMBEDDED
|
||||||
default y
|
default y if USB_OTG
|
||||||
|
default n if EMBEDDED
|
||||||
help
|
help
|
||||||
If you say Y here, the "otg_whitelist.h" file will be used as a
|
If you say Y here, the "otg_whitelist.h" file will be used as a
|
||||||
product whitelist, so USB peripherals not listed there will be
|
product whitelist, so USB peripherals not listed there will be
|
||||||
rejected during enumeration. This behavior is required by the
|
rejected during enumeration. This behavior is required by the
|
||||||
USB OTG specification for all devices not on your product's
|
USB OTG specification for all devices not on your product's
|
||||||
"Targeted Peripherals List".
|
"Targeted Peripherals List". "Embedded Hosts" are likewise
|
||||||
|
allowed to support only a limited number of peripherals.
|
||||||
|
|
||||||
Otherwise, peripherals not listed there will only generate a
|
Otherwise, peripherals not listed there will only generate a
|
||||||
warning and enumeration will continue. That's more like what
|
warning and enumeration will continue. That's more like what
|
||||||
@ -152,9 +129,10 @@ config USB_OTG_WHITELIST
|
|||||||
|
|
||||||
config USB_OTG_BLACKLIST_HUB
|
config USB_OTG_BLACKLIST_HUB
|
||||||
bool "Disable external hubs"
|
bool "Disable external hubs"
|
||||||
depends on USB_OTG
|
depends on USB_OTG || EMBEDDED
|
||||||
help
|
help
|
||||||
If you say Y here, then Linux will refuse to enumerate
|
If you say Y here, then Linux will refuse to enumerate
|
||||||
external hubs. OTG hosts are allowed to reduce hardware
|
external hubs. OTG hosts are allowed to reduce hardware
|
||||||
and software costs by not supporting external hubs.
|
and software costs by not supporting external hubs. So
|
||||||
|
are "Emedded Hosts" that don't offer OTG support.
|
||||||
|
|
||||||
|
@ -145,6 +145,23 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
|
|||||||
endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
|
endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some buggy high speed devices have bulk endpoints using
|
||||||
|
* maxpacket sizes other than 512. High speed HCDs may not
|
||||||
|
* be able to handle that particular bug, so let's warn...
|
||||||
|
*/
|
||||||
|
if (to_usb_device(ddev)->speed == USB_SPEED_HIGH
|
||||||
|
&& usb_endpoint_xfer_bulk(d)) {
|
||||||
|
unsigned maxp;
|
||||||
|
|
||||||
|
maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize) & 0x07ff;
|
||||||
|
if (maxp != 512)
|
||||||
|
dev_warn(ddev, "config %d interface %d altsetting %d "
|
||||||
|
"bulk endpoint 0x%X has invalid maxpacket %d\n",
|
||||||
|
cfgno, inum, asnum, d->bEndpointAddress,
|
||||||
|
maxp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip over any Class Specific or Vendor Specific descriptors;
|
/* Skip over any Class Specific or Vendor Specific descriptors;
|
||||||
* find the next endpoint or interface descriptor */
|
* find the next endpoint or interface descriptor */
|
||||||
endpoint->extra = buffer;
|
endpoint->extra = buffer;
|
||||||
|
@ -647,6 +647,7 @@ static int proc_control(struct dev_state *ps, void __user *arg)
|
|||||||
struct usbdevfs_ctrltransfer ctrl;
|
struct usbdevfs_ctrltransfer ctrl;
|
||||||
unsigned int tmo;
|
unsigned int tmo;
|
||||||
unsigned char *tbuf;
|
unsigned char *tbuf;
|
||||||
|
unsigned wLength;
|
||||||
int i, j, ret;
|
int i, j, ret;
|
||||||
|
|
||||||
if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
|
if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
|
||||||
@ -654,7 +655,8 @@ static int proc_control(struct dev_state *ps, void __user *arg)
|
|||||||
ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex);
|
ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (ctrl.wLength > PAGE_SIZE)
|
wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */
|
||||||
|
if (wLength > PAGE_SIZE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
tbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
|
tbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
|
||||||
if (!tbuf)
|
if (!tbuf)
|
||||||
@ -946,8 +948,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
|||||||
int ret, ifnum = -1;
|
int ret, ifnum = -1;
|
||||||
int is_in;
|
int is_in;
|
||||||
|
|
||||||
if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK|
|
if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP |
|
||||||
URB_NO_FSBR|URB_ZERO_PACKET))
|
USBDEVFS_URB_SHORT_NOT_OK |
|
||||||
|
USBDEVFS_URB_NO_FSBR |
|
||||||
|
USBDEVFS_URB_ZERO_PACKET |
|
||||||
|
USBDEVFS_URB_NO_INTERRUPT))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!uurb->buffer)
|
if (!uurb->buffer)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1102,8 +1107,24 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
|||||||
as->urb->pipe = (uurb->type << 30) |
|
as->urb->pipe = (uurb->type << 30) |
|
||||||
__create_pipe(ps->dev, uurb->endpoint & 0xf) |
|
__create_pipe(ps->dev, uurb->endpoint & 0xf) |
|
||||||
(uurb->endpoint & USB_DIR_IN);
|
(uurb->endpoint & USB_DIR_IN);
|
||||||
as->urb->transfer_flags = uurb->flags |
|
|
||||||
(is_in ? URB_DIR_IN : URB_DIR_OUT);
|
/* This tedious sequence is necessary because the URB_* flags
|
||||||
|
* are internal to the kernel and subject to change, whereas
|
||||||
|
* the USBDEVFS_URB_* flags are a user API and must not be changed.
|
||||||
|
*/
|
||||||
|
u = (is_in ? URB_DIR_IN : URB_DIR_OUT);
|
||||||
|
if (uurb->flags & USBDEVFS_URB_ISO_ASAP)
|
||||||
|
u |= URB_ISO_ASAP;
|
||||||
|
if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK)
|
||||||
|
u |= URB_SHORT_NOT_OK;
|
||||||
|
if (uurb->flags & USBDEVFS_URB_NO_FSBR)
|
||||||
|
u |= URB_NO_FSBR;
|
||||||
|
if (uurb->flags & USBDEVFS_URB_ZERO_PACKET)
|
||||||
|
u |= URB_ZERO_PACKET;
|
||||||
|
if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT)
|
||||||
|
u |= URB_NO_INTERRUPT;
|
||||||
|
as->urb->transfer_flags = u;
|
||||||
|
|
||||||
as->urb->transfer_buffer_length = uurb->buffer_length;
|
as->urb->transfer_buffer_length = uurb->buffer_length;
|
||||||
as->urb->setup_packet = (unsigned char *)dr;
|
as->urb->setup_packet = (unsigned char *)dr;
|
||||||
as->urb->start_frame = uurb->start_frame;
|
as->urb->start_frame = uurb->start_frame;
|
||||||
@ -1509,60 +1530,60 @@ static int usbdev_ioctl(struct inode *inode, struct file *file,
|
|||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case USBDEVFS_CONTROL:
|
case USBDEVFS_CONTROL:
|
||||||
snoop(&dev->dev, "%s: CONTROL\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: CONTROL\n", __func__);
|
||||||
ret = proc_control(ps, p);
|
ret = proc_control(ps, p);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
inode->i_mtime = CURRENT_TIME;
|
inode->i_mtime = CURRENT_TIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_BULK:
|
case USBDEVFS_BULK:
|
||||||
snoop(&dev->dev, "%s: BULK\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: BULK\n", __func__);
|
||||||
ret = proc_bulk(ps, p);
|
ret = proc_bulk(ps, p);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
inode->i_mtime = CURRENT_TIME;
|
inode->i_mtime = CURRENT_TIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_RESETEP:
|
case USBDEVFS_RESETEP:
|
||||||
snoop(&dev->dev, "%s: RESETEP\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: RESETEP\n", __func__);
|
||||||
ret = proc_resetep(ps, p);
|
ret = proc_resetep(ps, p);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
inode->i_mtime = CURRENT_TIME;
|
inode->i_mtime = CURRENT_TIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_RESET:
|
case USBDEVFS_RESET:
|
||||||
snoop(&dev->dev, "%s: RESET\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: RESET\n", __func__);
|
||||||
ret = proc_resetdevice(ps);
|
ret = proc_resetdevice(ps);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_CLEAR_HALT:
|
case USBDEVFS_CLEAR_HALT:
|
||||||
snoop(&dev->dev, "%s: CLEAR_HALT\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: CLEAR_HALT\n", __func__);
|
||||||
ret = proc_clearhalt(ps, p);
|
ret = proc_clearhalt(ps, p);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
inode->i_mtime = CURRENT_TIME;
|
inode->i_mtime = CURRENT_TIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_GETDRIVER:
|
case USBDEVFS_GETDRIVER:
|
||||||
snoop(&dev->dev, "%s: GETDRIVER\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: GETDRIVER\n", __func__);
|
||||||
ret = proc_getdriver(ps, p);
|
ret = proc_getdriver(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_CONNECTINFO:
|
case USBDEVFS_CONNECTINFO:
|
||||||
snoop(&dev->dev, "%s: CONNECTINFO\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: CONNECTINFO\n", __func__);
|
||||||
ret = proc_connectinfo(ps, p);
|
ret = proc_connectinfo(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_SETINTERFACE:
|
case USBDEVFS_SETINTERFACE:
|
||||||
snoop(&dev->dev, "%s: SETINTERFACE\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: SETINTERFACE\n", __func__);
|
||||||
ret = proc_setintf(ps, p);
|
ret = proc_setintf(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_SETCONFIGURATION:
|
case USBDEVFS_SETCONFIGURATION:
|
||||||
snoop(&dev->dev, "%s: SETCONFIGURATION\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: SETCONFIGURATION\n", __func__);
|
||||||
ret = proc_setconfig(ps, p);
|
ret = proc_setconfig(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_SUBMITURB:
|
case USBDEVFS_SUBMITURB:
|
||||||
snoop(&dev->dev, "%s: SUBMITURB\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: SUBMITURB\n", __func__);
|
||||||
ret = proc_submiturb(ps, p);
|
ret = proc_submiturb(ps, p);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
inode->i_mtime = CURRENT_TIME;
|
inode->i_mtime = CURRENT_TIME;
|
||||||
@ -1571,60 +1592,60 @@ static int usbdev_ioctl(struct inode *inode, struct file *file,
|
|||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
|
|
||||||
case USBDEVFS_SUBMITURB32:
|
case USBDEVFS_SUBMITURB32:
|
||||||
snoop(&dev->dev, "%s: SUBMITURB32\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: SUBMITURB32\n", __func__);
|
||||||
ret = proc_submiturb_compat(ps, p);
|
ret = proc_submiturb_compat(ps, p);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
inode->i_mtime = CURRENT_TIME;
|
inode->i_mtime = CURRENT_TIME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_REAPURB32:
|
case USBDEVFS_REAPURB32:
|
||||||
snoop(&dev->dev, "%s: REAPURB32\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: REAPURB32\n", __func__);
|
||||||
ret = proc_reapurb_compat(ps, p);
|
ret = proc_reapurb_compat(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_REAPURBNDELAY32:
|
case USBDEVFS_REAPURBNDELAY32:
|
||||||
snoop(&dev->dev, "%s: REAPURBDELAY32\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: REAPURBDELAY32\n", __func__);
|
||||||
ret = proc_reapurbnonblock_compat(ps, p);
|
ret = proc_reapurbnonblock_compat(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_IOCTL32:
|
case USBDEVFS_IOCTL32:
|
||||||
snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: IOCTL\n", __func__);
|
||||||
ret = proc_ioctl_compat(ps, ptr_to_compat(p));
|
ret = proc_ioctl_compat(ps, ptr_to_compat(p));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case USBDEVFS_DISCARDURB:
|
case USBDEVFS_DISCARDURB:
|
||||||
snoop(&dev->dev, "%s: DISCARDURB\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: DISCARDURB\n", __func__);
|
||||||
ret = proc_unlinkurb(ps, p);
|
ret = proc_unlinkurb(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_REAPURB:
|
case USBDEVFS_REAPURB:
|
||||||
snoop(&dev->dev, "%s: REAPURB\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: REAPURB\n", __func__);
|
||||||
ret = proc_reapurb(ps, p);
|
ret = proc_reapurb(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_REAPURBNDELAY:
|
case USBDEVFS_REAPURBNDELAY:
|
||||||
snoop(&dev->dev, "%s: REAPURBDELAY\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: REAPURBDELAY\n", __func__);
|
||||||
ret = proc_reapurbnonblock(ps, p);
|
ret = proc_reapurbnonblock(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_DISCSIGNAL:
|
case USBDEVFS_DISCSIGNAL:
|
||||||
snoop(&dev->dev, "%s: DISCSIGNAL\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__);
|
||||||
ret = proc_disconnectsignal(ps, p);
|
ret = proc_disconnectsignal(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_CLAIMINTERFACE:
|
case USBDEVFS_CLAIMINTERFACE:
|
||||||
snoop(&dev->dev, "%s: CLAIMINTERFACE\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: CLAIMINTERFACE\n", __func__);
|
||||||
ret = proc_claiminterface(ps, p);
|
ret = proc_claiminterface(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_RELEASEINTERFACE:
|
case USBDEVFS_RELEASEINTERFACE:
|
||||||
snoop(&dev->dev, "%s: RELEASEINTERFACE\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: RELEASEINTERFACE\n", __func__);
|
||||||
ret = proc_releaseinterface(ps, p);
|
ret = proc_releaseinterface(ps, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBDEVFS_IOCTL:
|
case USBDEVFS_IOCTL:
|
||||||
snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
|
snoop(&dev->dev, "%s: IOCTL\n", __func__);
|
||||||
ret = proc_ioctl_default(ps, p);
|
ret = proc_ioctl_default(ps, p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ static int usb_probe_device(struct device *dev)
|
|||||||
struct usb_device *udev;
|
struct usb_device *udev;
|
||||||
int error = -ENODEV;
|
int error = -ENODEV;
|
||||||
|
|
||||||
dev_dbg(dev, "%s\n", __FUNCTION__);
|
dev_dbg(dev, "%s\n", __func__);
|
||||||
|
|
||||||
if (!is_usb_device(dev)) /* Sanity check */
|
if (!is_usb_device(dev)) /* Sanity check */
|
||||||
return error;
|
return error;
|
||||||
@ -194,7 +194,7 @@ static int usb_probe_interface(struct device *dev)
|
|||||||
const struct usb_device_id *id;
|
const struct usb_device_id *id;
|
||||||
int error = -ENODEV;
|
int error = -ENODEV;
|
||||||
|
|
||||||
dev_dbg(dev, "%s\n", __FUNCTION__);
|
dev_dbg(dev, "%s\n", __func__);
|
||||||
|
|
||||||
if (is_usb_device(dev)) /* Sanity check */
|
if (is_usb_device(dev)) /* Sanity check */
|
||||||
return error;
|
return error;
|
||||||
@ -211,7 +211,7 @@ static int usb_probe_interface(struct device *dev)
|
|||||||
if (!id)
|
if (!id)
|
||||||
id = usb_match_dynamic_id(intf, driver);
|
id = usb_match_dynamic_id(intf, driver);
|
||||||
if (id) {
|
if (id) {
|
||||||
dev_dbg(dev, "%s - got id\n", __FUNCTION__);
|
dev_dbg(dev, "%s - got id\n", __func__);
|
||||||
|
|
||||||
error = usb_autoresume_device(udev);
|
error = usb_autoresume_device(udev);
|
||||||
if (error)
|
if (error)
|
||||||
@ -793,9 +793,7 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg)
|
|||||||
status = udriver->suspend(udev, msg);
|
status = udriver->suspend(udev, msg);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
|
dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
|
||||||
if (status == 0)
|
|
||||||
udev->dev.power.power_state.event = msg.event;
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,11 +821,9 @@ static int usb_resume_device(struct usb_device *udev)
|
|||||||
status = udriver->resume(udev);
|
status = udriver->resume(udev);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
|
dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
|
||||||
if (status == 0) {
|
if (status == 0)
|
||||||
udev->autoresume_disabled = 0;
|
udev->autoresume_disabled = 0;
|
||||||
udev->dev.power.power_state.event = PM_EVENT_ON;
|
|
||||||
}
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,7 +860,7 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dev_vdbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status);
|
dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,7 +910,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dev_vdbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status);
|
dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
mark_active(intf);
|
mark_active(intf);
|
||||||
|
|
||||||
@ -936,7 +932,6 @@ static int autosuspend_check(struct usb_device *udev, int reschedule)
|
|||||||
* is disabled. Also fail if any interfaces require remote wakeup
|
* is disabled. Also fail if any interfaces require remote wakeup
|
||||||
* but it isn't available.
|
* but it isn't available.
|
||||||
*/
|
*/
|
||||||
udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
|
|
||||||
if (udev->pm_usage_cnt > 0)
|
if (udev->pm_usage_cnt > 0)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled)
|
if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled)
|
||||||
@ -1098,7 +1093,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
|
dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1180,8 +1175,7 @@ static int usb_resume_both(struct usb_device *udev)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Needed for setting udev->dev.power.power_state.event,
|
/* Needed for reset-resume */
|
||||||
* for possible debugging message, and for reset_resume. */
|
|
||||||
status = usb_resume_device(udev);
|
status = usb_resume_device(udev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1193,8 +1187,9 @@ static int usb_resume_both(struct usb_device *udev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dev_vdbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
|
dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
|
||||||
udev->reset_resume = 0;
|
if (!status)
|
||||||
|
udev->reset_resume = 0;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1262,7 +1257,7 @@ void usb_autosuspend_device(struct usb_device *udev)
|
|||||||
|
|
||||||
status = usb_autopm_do_device(udev, -1);
|
status = usb_autopm_do_device(udev, -1);
|
||||||
dev_vdbg(&udev->dev, "%s: cnt %d\n",
|
dev_vdbg(&udev->dev, "%s: cnt %d\n",
|
||||||
__FUNCTION__, udev->pm_usage_cnt);
|
__func__, udev->pm_usage_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1282,7 +1277,7 @@ void usb_try_autosuspend_device(struct usb_device *udev)
|
|||||||
{
|
{
|
||||||
usb_autopm_do_device(udev, 0);
|
usb_autopm_do_device(udev, 0);
|
||||||
dev_vdbg(&udev->dev, "%s: cnt %d\n",
|
dev_vdbg(&udev->dev, "%s: cnt %d\n",
|
||||||
__FUNCTION__, udev->pm_usage_cnt);
|
__func__, udev->pm_usage_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1310,7 +1305,7 @@ int usb_autoresume_device(struct usb_device *udev)
|
|||||||
|
|
||||||
status = usb_autopm_do_device(udev, 1);
|
status = usb_autopm_do_device(udev, 1);
|
||||||
dev_vdbg(&udev->dev, "%s: status %d cnt %d\n",
|
dev_vdbg(&udev->dev, "%s: status %d cnt %d\n",
|
||||||
__FUNCTION__, status, udev->pm_usage_cnt);
|
__func__, status, udev->pm_usage_cnt);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1382,7 +1377,7 @@ void usb_autopm_put_interface(struct usb_interface *intf)
|
|||||||
|
|
||||||
status = usb_autopm_do_interface(intf, -1);
|
status = usb_autopm_do_interface(intf, -1);
|
||||||
dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
|
dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
|
||||||
__FUNCTION__, status, intf->pm_usage_cnt);
|
__func__, status, intf->pm_usage_cnt);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
|
EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
|
||||||
|
|
||||||
@ -1426,7 +1421,7 @@ int usb_autopm_get_interface(struct usb_interface *intf)
|
|||||||
|
|
||||||
status = usb_autopm_do_interface(intf, 1);
|
status = usb_autopm_do_interface(intf, 1);
|
||||||
dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
|
dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
|
||||||
__FUNCTION__, status, intf->pm_usage_cnt);
|
__func__, status, intf->pm_usage_cnt);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usb_autopm_get_interface);
|
EXPORT_SYMBOL_GPL(usb_autopm_get_interface);
|
||||||
@ -1448,7 +1443,7 @@ int usb_autopm_set_interface(struct usb_interface *intf)
|
|||||||
|
|
||||||
status = usb_autopm_do_interface(intf, 0);
|
status = usb_autopm_do_interface(intf, 0);
|
||||||
dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
|
dev_vdbg(&intf->dev, "%s: status %d cnt %d\n",
|
||||||
__FUNCTION__, status, intf->pm_usage_cnt);
|
__func__, status, intf->pm_usage_cnt);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usb_autopm_set_interface);
|
EXPORT_SYMBOL_GPL(usb_autopm_set_interface);
|
||||||
@ -1523,9 +1518,14 @@ static int usb_suspend(struct device *dev, pm_message_t message)
|
|||||||
udev = to_usb_device(dev);
|
udev = to_usb_device(dev);
|
||||||
|
|
||||||
/* If udev is already suspended, we can skip this suspend and
|
/* If udev is already suspended, we can skip this suspend and
|
||||||
* we should also skip the upcoming system resume. */
|
* we should also skip the upcoming system resume. High-speed
|
||||||
|
* root hubs are an exception; they need to resume whenever the
|
||||||
|
* system wakes up in order for USB-PERSIST port handover to work
|
||||||
|
* properly.
|
||||||
|
*/
|
||||||
if (udev->state == USB_STATE_SUSPENDED) {
|
if (udev->state == USB_STATE_SUSPENDED) {
|
||||||
udev->skip_sys_resume = 1;
|
if (udev->parent || udev->speed != USB_SPEED_HIGH)
|
||||||
|
udev->skip_sys_resume = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,6 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||||||
if (pci_enable_device(dev) < 0)
|
if (pci_enable_device(dev) < 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
dev->current_state = PCI_D0;
|
dev->current_state = PCI_D0;
|
||||||
dev->dev.power.power_state = PMSG_ON;
|
|
||||||
|
|
||||||
if (!dev->irq) {
|
if (!dev->irq) {
|
||||||
dev_err(&dev->dev,
|
dev_err(&dev->dev,
|
||||||
@ -216,9 +215,9 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
|
|||||||
hcd->state == HC_STATE_HALT))
|
hcd->state == HC_STATE_HALT))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if (hcd->driver->suspend) {
|
if (hcd->driver->pci_suspend) {
|
||||||
retval = hcd->driver->suspend(hcd, message);
|
retval = hcd->driver->pci_suspend(hcd, message);
|
||||||
suspend_report_result(hcd->driver->suspend, retval);
|
suspend_report_result(hcd->driver->pci_suspend, retval);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -302,8 +301,6 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
dev->dev.power.power_state = PMSG_SUSPEND;
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_PMAC
|
#ifdef CONFIG_PPC_PMAC
|
||||||
/* Disable ASIC clocks for USB */
|
/* Disable ASIC clocks for USB */
|
||||||
if (machine_is(powermac)) {
|
if (machine_is(powermac)) {
|
||||||
@ -406,12 +403,10 @@ int usb_hcd_pci_resume(struct pci_dev *dev)
|
|||||||
pci_set_master(dev);
|
pci_set_master(dev);
|
||||||
pci_restore_state(dev);
|
pci_restore_state(dev);
|
||||||
|
|
||||||
dev->dev.power.power_state = PMSG_ON;
|
|
||||||
|
|
||||||
clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
|
clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
|
||||||
|
|
||||||
if (hcd->driver->resume) {
|
if (hcd->driver->pci_resume) {
|
||||||
retval = hcd->driver->resume(hcd);
|
retval = hcd->driver->pci_resume(hcd);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
dev_err(hcd->self.controller,
|
dev_err(hcd->self.controller,
|
||||||
"PCI post-resume error %d!\n", retval);
|
"PCI post-resume error %d!\n", retval);
|
||||||
|
@ -129,7 +129,7 @@ static const u8 usb2_rh_dev_descriptor [18] = {
|
|||||||
|
|
||||||
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
|
0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
|
||||||
0x00, /* __u8 bDeviceSubClass; */
|
0x00, /* __u8 bDeviceSubClass; */
|
||||||
0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/
|
0x00, /* __u8 bDeviceProtocol; [ usb 2.0 no TT ] */
|
||||||
0x40, /* __u8 bMaxPacketSize0; 64 Bytes */
|
0x40, /* __u8 bMaxPacketSize0; 64 Bytes */
|
||||||
|
|
||||||
0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */
|
0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */
|
||||||
@ -291,7 +291,6 @@ static int ascii2utf (char *s, u8 *utf, int utfmax)
|
|||||||
* rh_string - provides manufacturer, product and serial strings for root hub
|
* rh_string - provides manufacturer, product and serial strings for root hub
|
||||||
* @id: the string ID number (1: serial number, 2: product, 3: vendor)
|
* @id: the string ID number (1: serial number, 2: product, 3: vendor)
|
||||||
* @hcd: the host controller for this root hub
|
* @hcd: the host controller for this root hub
|
||||||
* @type: string describing our driver
|
|
||||||
* @data: return packet in UTF-16 LE
|
* @data: return packet in UTF-16 LE
|
||||||
* @len: length of the return packet
|
* @len: length of the return packet
|
||||||
*
|
*
|
||||||
@ -355,9 +354,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
|
|||||||
__attribute__((aligned(4)));
|
__attribute__((aligned(4)));
|
||||||
const u8 *bufp = tbuf;
|
const u8 *bufp = tbuf;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int patch_wakeup = 0;
|
|
||||||
int status;
|
int status;
|
||||||
int n;
|
int n;
|
||||||
|
u8 patch_wakeup = 0;
|
||||||
|
u8 patch_protocol = 0;
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
@ -434,6 +434,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
|
|||||||
else
|
else
|
||||||
goto error;
|
goto error;
|
||||||
len = 18;
|
len = 18;
|
||||||
|
if (hcd->has_tt)
|
||||||
|
patch_protocol = 1;
|
||||||
break;
|
break;
|
||||||
case USB_DT_CONFIG << 8:
|
case USB_DT_CONFIG << 8:
|
||||||
if (hcd->driver->flags & HCD_USB2) {
|
if (hcd->driver->flags & HCD_USB2) {
|
||||||
@ -528,6 +530,13 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
|
|||||||
bmAttributes))
|
bmAttributes))
|
||||||
((struct usb_config_descriptor *)ubuf)->bmAttributes
|
((struct usb_config_descriptor *)ubuf)->bmAttributes
|
||||||
|= USB_CONFIG_ATT_WAKEUP;
|
|= USB_CONFIG_ATT_WAKEUP;
|
||||||
|
|
||||||
|
/* report whether RH hardware has an integrated TT */
|
||||||
|
if (patch_protocol &&
|
||||||
|
len > offsetof(struct usb_device_descriptor,
|
||||||
|
bDeviceProtocol))
|
||||||
|
((struct usb_device_descriptor *) ubuf)->
|
||||||
|
bDeviceProtocol = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* any errors get returned through the urb completion */
|
/* any errors get returned through the urb completion */
|
||||||
@ -915,15 +924,6 @@ static int register_root_hub(struct usb_hcd *hcd)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_enable_root_hub_irq (struct usb_bus *bus)
|
|
||||||
{
|
|
||||||
struct usb_hcd *hcd;
|
|
||||||
|
|
||||||
hcd = container_of (bus, struct usb_hcd, self);
|
|
||||||
if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT)
|
|
||||||
hcd->driver->hub_irq_enable (hcd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -1677,7 +1677,6 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);
|
|||||||
* usb_hcd_irq - hook IRQs to HCD framework (bus glue)
|
* usb_hcd_irq - hook IRQs to HCD framework (bus glue)
|
||||||
* @irq: the IRQ being raised
|
* @irq: the IRQ being raised
|
||||||
* @__hcd: pointer to the HCD whose IRQ is being signaled
|
* @__hcd: pointer to the HCD whose IRQ is being signaled
|
||||||
* @r: saved hardware registers
|
|
||||||
*
|
*
|
||||||
* If the controller isn't HALTed, calls the driver's irq handler.
|
* If the controller isn't HALTed, calls the driver's irq handler.
|
||||||
* Checks whether the controller is now dead.
|
* Checks whether the controller is now dead.
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
/*
|
/*
|
||||||
* USB Packet IDs (PIDs)
|
* USB Packet IDs (PIDs)
|
||||||
*/
|
*/
|
||||||
#define USB_PID_UNDEF_0 0xf0
|
#define USB_PID_EXT 0xf0 /* USB 2.0 LPM ECN */
|
||||||
#define USB_PID_OUT 0xe1
|
#define USB_PID_OUT 0xe1
|
||||||
#define USB_PID_ACK 0xd2
|
#define USB_PID_ACK 0xd2
|
||||||
#define USB_PID_DATA0 0xc3
|
#define USB_PID_DATA0 0xc3
|
||||||
@ -99,6 +99,7 @@ struct usb_hcd {
|
|||||||
unsigned poll_pending:1; /* status has changed? */
|
unsigned poll_pending:1; /* status has changed? */
|
||||||
unsigned wireless:1; /* Wireless USB HCD */
|
unsigned wireless:1; /* Wireless USB HCD */
|
||||||
unsigned authorized_default:1;
|
unsigned authorized_default:1;
|
||||||
|
unsigned has_tt:1; /* Integrated TT in root hub */
|
||||||
|
|
||||||
int irq; /* irq allocated */
|
int irq; /* irq allocated */
|
||||||
void __iomem *regs; /* device memory/io */
|
void __iomem *regs; /* device memory/io */
|
||||||
@ -177,10 +178,10 @@ struct hc_driver {
|
|||||||
* a whole, not just the root hub; they're for PCI bus glue.
|
* a whole, not just the root hub; they're for PCI bus glue.
|
||||||
*/
|
*/
|
||||||
/* called after suspending the hub, before entering D3 etc */
|
/* called after suspending the hub, before entering D3 etc */
|
||||||
int (*suspend) (struct usb_hcd *hcd, pm_message_t message);
|
int (*pci_suspend) (struct usb_hcd *hcd, pm_message_t message);
|
||||||
|
|
||||||
/* called after entering D0 (etc), before resuming the hub */
|
/* called after entering D0 (etc), before resuming the hub */
|
||||||
int (*resume) (struct usb_hcd *hcd);
|
int (*pci_resume) (struct usb_hcd *hcd);
|
||||||
|
|
||||||
/* cleanly make HCD stop writing memory and doing I/O */
|
/* cleanly make HCD stop writing memory and doing I/O */
|
||||||
void (*stop) (struct usb_hcd *hcd);
|
void (*stop) (struct usb_hcd *hcd);
|
||||||
@ -209,8 +210,6 @@ struct hc_driver {
|
|||||||
int (*bus_suspend)(struct usb_hcd *);
|
int (*bus_suspend)(struct usb_hcd *);
|
||||||
int (*bus_resume)(struct usb_hcd *);
|
int (*bus_resume)(struct usb_hcd *);
|
||||||
int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
|
int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
|
||||||
void (*hub_irq_enable)(struct usb_hcd *);
|
|
||||||
/* Needed only if port-change IRQs are level-triggered */
|
|
||||||
|
|
||||||
/* force handover of high-speed port to full-speed companion */
|
/* force handover of high-speed port to full-speed companion */
|
||||||
void (*relinquish_port)(struct usb_hcd *, int);
|
void (*relinquish_port)(struct usb_hcd *, int);
|
||||||
|
@ -30,12 +30,6 @@
|
|||||||
#include "hcd.h"
|
#include "hcd.h"
|
||||||
#include "hub.h"
|
#include "hub.h"
|
||||||
|
|
||||||
#ifdef CONFIG_USB_PERSIST
|
|
||||||
#define USB_PERSIST 1
|
|
||||||
#else
|
|
||||||
#define USB_PERSIST 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* if we are in debug mode, always announce new devices */
|
/* if we are in debug mode, always announce new devices */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#ifndef CONFIG_USB_ANNOUNCE_NEW_DEVICES
|
#ifndef CONFIG_USB_ANNOUNCE_NEW_DEVICES
|
||||||
@ -333,6 +327,27 @@ static int get_port_status(struct usb_device *hdev, int port1,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hub_port_status(struct usb_hub *hub, int port1,
|
||||||
|
u16 *status, u16 *change)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&hub->status_mutex);
|
||||||
|
ret = get_port_status(hub->hdev, port1, &hub->status->port);
|
||||||
|
if (ret < 4) {
|
||||||
|
dev_err(hub->intfdev,
|
||||||
|
"%s failed (err = %d)\n", __func__, ret);
|
||||||
|
if (ret >= 0)
|
||||||
|
ret = -EIO;
|
||||||
|
} else {
|
||||||
|
*status = le16_to_cpu(hub->status->port.wPortStatus);
|
||||||
|
*change = le16_to_cpu(hub->status->port.wPortChange);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
mutex_unlock(&hub->status_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void kick_khubd(struct usb_hub *hub)
|
static void kick_khubd(struct usb_hub *hub)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -560,7 +575,7 @@ static int hub_hub_status(struct usb_hub *hub,
|
|||||||
ret = get_hub_status(hub->hdev, &hub->status->hub);
|
ret = get_hub_status(hub->hdev, &hub->status->hub);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
dev_err (hub->intfdev,
|
dev_err (hub->intfdev,
|
||||||
"%s failed (err = %d)\n", __FUNCTION__, ret);
|
"%s failed (err = %d)\n", __func__, ret);
|
||||||
else {
|
else {
|
||||||
*status = le16_to_cpu(hub->status->hub.wHubStatus);
|
*status = le16_to_cpu(hub->status->hub.wHubStatus);
|
||||||
*change = le16_to_cpu(hub->status->hub.wHubChange);
|
*change = le16_to_cpu(hub->status->hub.wHubChange);
|
||||||
@ -610,9 +625,8 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* caller has locked the hub device */
|
/* caller has locked the hub device */
|
||||||
static int hub_pre_reset(struct usb_interface *intf)
|
static void hub_stop(struct usb_hub *hub)
|
||||||
{
|
{
|
||||||
struct usb_hub *hub = usb_get_intfdata(intf);
|
|
||||||
struct usb_device *hdev = hub->hdev;
|
struct usb_device *hdev = hub->hdev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -622,6 +636,89 @@ static int hub_pre_reset(struct usb_interface *intf)
|
|||||||
usb_disconnect(&hdev->children[i]);
|
usb_disconnect(&hdev->children[i]);
|
||||||
}
|
}
|
||||||
hub_quiesce(hub);
|
hub_quiesce(hub);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HUB_RESET 1
|
||||||
|
#define HUB_RESUME 2
|
||||||
|
#define HUB_RESET_RESUME 3
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
|
static void hub_restart(struct usb_hub *hub, int type)
|
||||||
|
{
|
||||||
|
struct usb_device *hdev = hub->hdev;
|
||||||
|
int port1;
|
||||||
|
|
||||||
|
/* Check each of the children to see if they require
|
||||||
|
* USB-PERSIST handling or disconnection. Also check
|
||||||
|
* each unoccupied port to make sure it is still disabled.
|
||||||
|
*/
|
||||||
|
for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
|
||||||
|
struct usb_device *udev = hdev->children[port1-1];
|
||||||
|
int status = 0;
|
||||||
|
u16 portstatus, portchange;
|
||||||
|
|
||||||
|
if (!udev || udev->state == USB_STATE_NOTATTACHED) {
|
||||||
|
if (type != HUB_RESET) {
|
||||||
|
status = hub_port_status(hub, port1,
|
||||||
|
&portstatus, &portchange);
|
||||||
|
if (status == 0 && (portstatus &
|
||||||
|
USB_PORT_STAT_ENABLE))
|
||||||
|
clear_port_feature(hdev, port1,
|
||||||
|
USB_PORT_FEAT_ENABLE);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Was the power session lost while we were suspended? */
|
||||||
|
switch (type) {
|
||||||
|
case HUB_RESET_RESUME:
|
||||||
|
portstatus = 0;
|
||||||
|
portchange = USB_PORT_STAT_C_CONNECTION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HUB_RESET:
|
||||||
|
case HUB_RESUME:
|
||||||
|
status = hub_port_status(hub, port1,
|
||||||
|
&portstatus, &portchange);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For "USB_PERSIST"-enabled children we must
|
||||||
|
* mark the child device for reset-resume and
|
||||||
|
* turn off the various status changes to prevent
|
||||||
|
* khubd from disconnecting it later.
|
||||||
|
*/
|
||||||
|
if (udev->persist_enabled && status == 0 &&
|
||||||
|
!(portstatus & USB_PORT_STAT_ENABLE)) {
|
||||||
|
if (portchange & USB_PORT_STAT_C_ENABLE)
|
||||||
|
clear_port_feature(hub->hdev, port1,
|
||||||
|
USB_PORT_FEAT_C_ENABLE);
|
||||||
|
if (portchange & USB_PORT_STAT_C_CONNECTION)
|
||||||
|
clear_port_feature(hub->hdev, port1,
|
||||||
|
USB_PORT_FEAT_C_CONNECTION);
|
||||||
|
udev->reset_resume = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise for a reset_resume we must disconnect the child,
|
||||||
|
* but as we may not lock the child device here
|
||||||
|
* we have to do a "logical" disconnect.
|
||||||
|
*/
|
||||||
|
else if (type == HUB_RESET_RESUME)
|
||||||
|
hub_port_logical_disconnect(hub, port1);
|
||||||
|
}
|
||||||
|
|
||||||
|
hub_activate(hub);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
|
/* caller has locked the hub device */
|
||||||
|
static int hub_pre_reset(struct usb_interface *intf)
|
||||||
|
{
|
||||||
|
struct usb_hub *hub = usb_get_intfdata(intf);
|
||||||
|
|
||||||
|
hub_stop(hub);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -910,7 +1007,7 @@ static void hub_disconnect(struct usb_interface *intf)
|
|||||||
|
|
||||||
/* Disconnect all children and quiesce the hub */
|
/* Disconnect all children and quiesce the hub */
|
||||||
hub->error = 0;
|
hub->error = 0;
|
||||||
hub_pre_reset(intf);
|
hub_stop(hub);
|
||||||
|
|
||||||
usb_set_intfdata (intf, NULL);
|
usb_set_intfdata (intf, NULL);
|
||||||
|
|
||||||
@ -1098,21 +1195,42 @@ void usb_set_device_state(struct usb_device *udev,
|
|||||||
spin_unlock_irqrestore(&device_state_lock, flags);
|
spin_unlock_irqrestore(&device_state_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WUSB devices are simple: they have no hubs behind, so the mapping
|
||||||
|
* device <-> virtual port number becomes 1:1. Why? to simplify the
|
||||||
|
* life of the device connection logic in
|
||||||
|
* drivers/usb/wusbcore/devconnect.c. When we do the initial secret
|
||||||
|
* handshake we need to assign a temporary address in the unauthorized
|
||||||
|
* space. For simplicity we use the first virtual port number found to
|
||||||
|
* be free [drivers/usb/wusbcore/devconnect.c:wusbhc_devconnect_ack()]
|
||||||
|
* and that becomes it's address [X < 128] or its unauthorized address
|
||||||
|
* [X | 0x80].
|
||||||
|
*
|
||||||
|
* We add 1 as an offset to the one-based USB-stack port number
|
||||||
|
* (zero-based wusb virtual port index) for two reasons: (a) dev addr
|
||||||
|
* 0 is reserved by USB for default address; (b) Linux's USB stack
|
||||||
|
* uses always #1 for the root hub of the controller. So USB stack's
|
||||||
|
* port #1, which is wusb virtual-port #0 has address #2.
|
||||||
|
*/
|
||||||
static void choose_address(struct usb_device *udev)
|
static void choose_address(struct usb_device *udev)
|
||||||
{
|
{
|
||||||
int devnum;
|
int devnum;
|
||||||
struct usb_bus *bus = udev->bus;
|
struct usb_bus *bus = udev->bus;
|
||||||
|
|
||||||
/* If khubd ever becomes multithreaded, this will need a lock */
|
/* If khubd ever becomes multithreaded, this will need a lock */
|
||||||
|
if (udev->wusb) {
|
||||||
/* Try to allocate the next devnum beginning at bus->devnum_next. */
|
devnum = udev->portnum + 1;
|
||||||
devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
|
BUG_ON(test_bit(devnum, bus->devmap.devicemap));
|
||||||
bus->devnum_next);
|
} else {
|
||||||
if (devnum >= 128)
|
/* Try to allocate the next devnum beginning at
|
||||||
devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1);
|
* bus->devnum_next. */
|
||||||
|
devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
|
||||||
bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
|
bus->devnum_next);
|
||||||
|
if (devnum >= 128)
|
||||||
|
devnum = find_next_zero_bit(bus->devmap.devicemap,
|
||||||
|
128, 1);
|
||||||
|
bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
|
||||||
|
}
|
||||||
if (devnum < 128) {
|
if (devnum < 128) {
|
||||||
set_bit(devnum, bus->devmap.devicemap);
|
set_bit(devnum, bus->devmap.devicemap);
|
||||||
udev->devnum = devnum;
|
udev->devnum = devnum;
|
||||||
@ -1127,6 +1245,13 @@ static void release_address(struct usb_device *udev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_address(struct usb_device *udev, int devnum)
|
||||||
|
{
|
||||||
|
/* The address for a WUSB device is managed by wusbcore. */
|
||||||
|
if (!udev->wusb)
|
||||||
|
udev->devnum = devnum;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_USB_SUSPEND
|
#ifdef CONFIG_USB_SUSPEND
|
||||||
|
|
||||||
static void usb_stop_pm(struct usb_device *udev)
|
static void usb_stop_pm(struct usb_device *udev)
|
||||||
@ -1173,7 +1298,7 @@ void usb_disconnect(struct usb_device **pdev)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!udev) {
|
if (!udev) {
|
||||||
pr_debug ("%s nodev\n", __FUNCTION__);
|
pr_debug ("%s nodev\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1510,28 +1635,6 @@ int usb_authorize_device(struct usb_device *usb_dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hub_port_status(struct usb_hub *hub, int port1,
|
|
||||||
u16 *status, u16 *change)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mutex_lock(&hub->status_mutex);
|
|
||||||
ret = get_port_status(hub->hdev, port1, &hub->status->port);
|
|
||||||
if (ret < 4) {
|
|
||||||
dev_err (hub->intfdev,
|
|
||||||
"%s failed (err = %d)\n", __FUNCTION__, ret);
|
|
||||||
if (ret >= 0)
|
|
||||||
ret = -EIO;
|
|
||||||
} else {
|
|
||||||
*status = le16_to_cpu(hub->status->port.wPortStatus);
|
|
||||||
*change = le16_to_cpu(hub->status->port.wPortChange);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
mutex_unlock(&hub->status_mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns 1 if @hub is a WUSB root hub, 0 otherwise */
|
/* Returns 1 if @hub is a WUSB root hub, 0 otherwise */
|
||||||
static unsigned hub_is_wusb(struct usb_hub *hub)
|
static unsigned hub_is_wusb(struct usb_hub *hub)
|
||||||
{
|
{
|
||||||
@ -1637,7 +1740,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
|
|||||||
case 0:
|
case 0:
|
||||||
/* TRSTRCY = 10 ms; plus some extra */
|
/* TRSTRCY = 10 ms; plus some extra */
|
||||||
msleep(10 + 40);
|
msleep(10 + 40);
|
||||||
udev->devnum = 0; /* Device now at address 0 */
|
update_address(udev, 0);
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
case -ENOTCONN:
|
case -ENOTCONN:
|
||||||
case -ENODEV:
|
case -ENODEV:
|
||||||
@ -1842,9 +1945,8 @@ static int finish_port_resume(struct usb_device *udev)
|
|||||||
* the host and the device is the same as it was when the device
|
* the host and the device is the same as it was when the device
|
||||||
* suspended.
|
* suspended.
|
||||||
*
|
*
|
||||||
* If CONFIG_USB_PERSIST and @udev->reset_resume are both set then this
|
* If @udev->reset_resume is set then this routine won't check that the
|
||||||
* routine won't check that the port is still enabled. Furthermore,
|
* port is still enabled. Furthermore, finish_port_resume() above will
|
||||||
* if @udev->reset_resume is set then finish_port_resume() above will
|
|
||||||
* reset @udev. The end result is that a broken power session can be
|
* reset @udev. The end result is that a broken power session can be
|
||||||
* recovered and @udev will appear to persist across a loss of VBUS power.
|
* recovered and @udev will appear to persist across a loss of VBUS power.
|
||||||
*
|
*
|
||||||
@ -1856,8 +1958,8 @@ static int finish_port_resume(struct usb_device *udev)
|
|||||||
* to it will be lost. Using the USB_PERSIST facility, the device can be
|
* to it will be lost. Using the USB_PERSIST facility, the device can be
|
||||||
* made to appear as if it had not disconnected.
|
* made to appear as if it had not disconnected.
|
||||||
*
|
*
|
||||||
* This facility is inherently dangerous. Although usb_reset_device()
|
* This facility can be dangerous. Although usb_reset_device() makes
|
||||||
* makes every effort to insure that the same device is present after the
|
* every effort to insure that the same device is present after the
|
||||||
* reset as before, it cannot provide a 100% guarantee. Furthermore it's
|
* reset as before, it cannot provide a 100% guarantee. Furthermore it's
|
||||||
* quite possible for a device to remain unaltered but its media to be
|
* quite possible for a device to remain unaltered but its media to be
|
||||||
* changed. If the user replaces a flash memory card while the system is
|
* changed. If the user replaces a flash memory card while the system is
|
||||||
@ -1902,7 +2004,7 @@ int usb_port_resume(struct usb_device *udev)
|
|||||||
status = hub_port_status(hub, port1, &portstatus, &portchange);
|
status = hub_port_status(hub, port1, &portstatus, &portchange);
|
||||||
|
|
||||||
SuspendCleared:
|
SuspendCleared:
|
||||||
if (USB_PERSIST && udev->reset_resume)
|
if (udev->reset_resume)
|
||||||
want_flags = USB_PORT_STAT_POWER
|
want_flags = USB_PORT_STAT_POWER
|
||||||
| USB_PORT_STAT_CONNECTION;
|
| USB_PORT_STAT_CONNECTION;
|
||||||
else
|
else
|
||||||
@ -1927,8 +2029,6 @@ int usb_port_resume(struct usb_device *udev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
clear_bit(port1, hub->busy_bits);
|
clear_bit(port1, hub->busy_bits);
|
||||||
if (!hub->hdev->parent && !hub->busy_bits[0])
|
|
||||||
usb_enable_root_hub_irq(hub->hdev->bus);
|
|
||||||
|
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
status = finish_port_resume(udev);
|
status = finish_port_resume(udev);
|
||||||
@ -2000,7 +2100,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
|
dev_dbg(&intf->dev, "%s\n", __func__);
|
||||||
|
|
||||||
/* stop khubd and related activity */
|
/* stop khubd and related activity */
|
||||||
hub_quiesce(hub);
|
hub_quiesce(hub);
|
||||||
@ -2009,49 +2109,20 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
|||||||
|
|
||||||
static int hub_resume(struct usb_interface *intf)
|
static int hub_resume(struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
struct usb_hub *hub = usb_get_intfdata (intf);
|
struct usb_hub *hub = usb_get_intfdata(intf);
|
||||||
|
|
||||||
dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
|
dev_dbg(&intf->dev, "%s\n", __func__);
|
||||||
|
hub_restart(hub, HUB_RESUME);
|
||||||
/* tell khubd to look for changes on this hub */
|
|
||||||
hub_activate(hub);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hub_reset_resume(struct usb_interface *intf)
|
static int hub_reset_resume(struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
struct usb_hub *hub = usb_get_intfdata(intf);
|
struct usb_hub *hub = usb_get_intfdata(intf);
|
||||||
struct usb_device *hdev = hub->hdev;
|
|
||||||
int port1;
|
|
||||||
|
|
||||||
|
dev_dbg(&intf->dev, "%s\n", __func__);
|
||||||
hub_power_on(hub);
|
hub_power_on(hub);
|
||||||
|
hub_restart(hub, HUB_RESET_RESUME);
|
||||||
for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
|
|
||||||
struct usb_device *child = hdev->children[port1-1];
|
|
||||||
|
|
||||||
if (child) {
|
|
||||||
|
|
||||||
/* For "USB_PERSIST"-enabled children we must
|
|
||||||
* mark the child device for reset-resume and
|
|
||||||
* turn off the connect-change status to prevent
|
|
||||||
* khubd from disconnecting it later.
|
|
||||||
*/
|
|
||||||
if (USB_PERSIST && child->persist_enabled) {
|
|
||||||
child->reset_resume = 1;
|
|
||||||
clear_port_feature(hdev, port1,
|
|
||||||
USB_PORT_FEAT_C_CONNECTION);
|
|
||||||
|
|
||||||
/* Otherwise we must disconnect the child,
|
|
||||||
* but as we may not lock the child device here
|
|
||||||
* we have to do a "logical" disconnect.
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
hub_port_logical_disconnect(hub, port1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hub_activate(hub);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2061,10 +2132,10 @@ static int hub_reset_resume(struct usb_interface *intf)
|
|||||||
*
|
*
|
||||||
* The USB host controller driver calls this function when its root hub
|
* The USB host controller driver calls this function when its root hub
|
||||||
* is resumed and Vbus power has been interrupted or the controller
|
* is resumed and Vbus power has been interrupted or the controller
|
||||||
* has been reset. The routine marks @rhdev as having lost power. When
|
* has been reset. The routine marks @rhdev as having lost power.
|
||||||
* the hub driver is resumed it will take notice; if CONFIG_USB_PERSIST
|
* When the hub driver is resumed it will take notice and carry out
|
||||||
* is enabled then it will carry out power-session recovery, otherwise
|
* power-session recovery for all the "USB-PERSIST"-enabled child devices;
|
||||||
* it will disconnect all the child devices.
|
* the others will be disconnected.
|
||||||
*/
|
*/
|
||||||
void usb_root_hub_lost_power(struct usb_device *rhdev)
|
void usb_root_hub_lost_power(struct usb_device *rhdev)
|
||||||
{
|
{
|
||||||
@ -2147,12 +2218,13 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)
|
|||||||
return portstatus;
|
return portstatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ep0_reinit(struct usb_device *udev)
|
void usb_ep0_reinit(struct usb_device *udev)
|
||||||
{
|
{
|
||||||
usb_disable_endpoint(udev, 0 + USB_DIR_IN);
|
usb_disable_endpoint(udev, 0 + USB_DIR_IN);
|
||||||
usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
|
usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
|
||||||
usb_enable_endpoint(udev, &udev->ep0);
|
usb_enable_endpoint(udev, &udev->ep0);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
|
||||||
|
|
||||||
#define usb_sndaddr0pipe() (PIPE_CONTROL << 30)
|
#define usb_sndaddr0pipe() (PIPE_CONTROL << 30)
|
||||||
#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN)
|
#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN)
|
||||||
@ -2171,9 +2243,10 @@ static int hub_set_address(struct usb_device *udev, int devnum)
|
|||||||
USB_REQ_SET_ADDRESS, 0, devnum, 0,
|
USB_REQ_SET_ADDRESS, 0, devnum, 0,
|
||||||
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
udev->devnum = devnum; /* Device now using proper address */
|
/* Device now using proper address. */
|
||||||
|
update_address(udev, devnum);
|
||||||
usb_set_device_state(udev, USB_STATE_ADDRESS);
|
usb_set_device_state(udev, USB_STATE_ADDRESS);
|
||||||
ep0_reinit(udev);
|
usb_ep0_reinit(udev);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -2355,26 +2428,33 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
|||||||
#undef GET_DESCRIPTOR_BUFSIZE
|
#undef GET_DESCRIPTOR_BUFSIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
|
/*
|
||||||
retval = hub_set_address(udev, devnum);
|
* If device is WUSB, we already assigned an
|
||||||
if (retval >= 0)
|
* unauthorized address in the Connect Ack sequence;
|
||||||
|
* authorization will assign the final address.
|
||||||
|
*/
|
||||||
|
if (udev->wusb == 0) {
|
||||||
|
for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
|
||||||
|
retval = hub_set_address(udev, devnum);
|
||||||
|
if (retval >= 0)
|
||||||
|
break;
|
||||||
|
msleep(200);
|
||||||
|
}
|
||||||
|
if (retval < 0) {
|
||||||
|
dev_err(&udev->dev,
|
||||||
|
"device not accepting address %d, error %d\n",
|
||||||
|
devnum, retval);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cope with hardware quirkiness:
|
||||||
|
* - let SET_ADDRESS settle, some device hardware wants it
|
||||||
|
* - read ep0 maxpacket even for high and low speed,
|
||||||
|
*/
|
||||||
|
msleep(10);
|
||||||
|
if (USE_NEW_SCHEME(retry_counter))
|
||||||
break;
|
break;
|
||||||
msleep(200);
|
}
|
||||||
}
|
|
||||||
if (retval < 0) {
|
|
||||||
dev_err(&udev->dev,
|
|
||||||
"device not accepting address %d, error %d\n",
|
|
||||||
devnum, retval);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cope with hardware quirkiness:
|
|
||||||
* - let SET_ADDRESS settle, some device hardware wants it
|
|
||||||
* - read ep0 maxpacket even for high and low speed,
|
|
||||||
*/
|
|
||||||
msleep(10);
|
|
||||||
if (USE_NEW_SCHEME(retry_counter))
|
|
||||||
break;
|
|
||||||
|
|
||||||
retval = usb_get_device_descriptor(udev, 8);
|
retval = usb_get_device_descriptor(udev, 8);
|
||||||
if (retval < 8) {
|
if (retval < 8) {
|
||||||
@ -2391,7 +2471,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
|||||||
if (retval)
|
if (retval)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
i = udev->descriptor.bMaxPacketSize0 == 0xff?
|
i = udev->descriptor.bMaxPacketSize0 == 0xff? /* wusb device? */
|
||||||
512 : udev->descriptor.bMaxPacketSize0;
|
512 : udev->descriptor.bMaxPacketSize0;
|
||||||
if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
|
if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
|
||||||
if (udev->speed != USB_SPEED_FULL ||
|
if (udev->speed != USB_SPEED_FULL ||
|
||||||
@ -2402,7 +2482,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
|||||||
}
|
}
|
||||||
dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
|
dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
|
||||||
udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
|
udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
|
||||||
ep0_reinit(udev);
|
usb_ep0_reinit(udev);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
|
retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);
|
||||||
@ -2419,7 +2499,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
|
|||||||
fail:
|
fail:
|
||||||
if (retval) {
|
if (retval) {
|
||||||
hub_port_disable(hub, port1, 0);
|
hub_port_disable(hub, port1, 0);
|
||||||
udev->devnum = devnum; /* for disconnect processing */
|
update_address(udev, devnum); /* for disconnect processing */
|
||||||
}
|
}
|
||||||
mutex_unlock(&usb_address0_mutex);
|
mutex_unlock(&usb_address0_mutex);
|
||||||
return retval;
|
return retval;
|
||||||
@ -2568,6 +2648,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
|||||||
udev->speed = USB_SPEED_UNKNOWN;
|
udev->speed = USB_SPEED_UNKNOWN;
|
||||||
udev->bus_mA = hub->mA_per_port;
|
udev->bus_mA = hub->mA_per_port;
|
||||||
udev->level = hdev->level + 1;
|
udev->level = hdev->level + 1;
|
||||||
|
udev->wusb = hub_is_wusb(hub);
|
||||||
|
|
||||||
/* set the address */
|
/* set the address */
|
||||||
choose_address(udev);
|
choose_address(udev);
|
||||||
@ -2657,12 +2738,13 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
|||||||
loop_disable:
|
loop_disable:
|
||||||
hub_port_disable(hub, port1, 1);
|
hub_port_disable(hub, port1, 1);
|
||||||
loop:
|
loop:
|
||||||
ep0_reinit(udev);
|
usb_ep0_reinit(udev);
|
||||||
release_address(udev);
|
release_address(udev);
|
||||||
usb_put_dev(udev);
|
usb_put_dev(udev);
|
||||||
if ((status == -ENOTCONN) || (status == -ENOTSUPP))
|
if ((status == -ENOTCONN) || (status == -ENOTSUPP))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
hub_port_disable(hub, port1, 1);
|
hub_port_disable(hub, port1, 1);
|
||||||
@ -2726,7 +2808,7 @@ static void hub_events(void)
|
|||||||
/* If the hub has died, clean up after it */
|
/* If the hub has died, clean up after it */
|
||||||
if (hdev->state == USB_STATE_NOTATTACHED) {
|
if (hdev->state == USB_STATE_NOTATTACHED) {
|
||||||
hub->error = -ENODEV;
|
hub->error = -ENODEV;
|
||||||
hub_pre_reset(intf);
|
hub_stop(hub);
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2872,11 +2954,6 @@ static void hub_events(void)
|
|||||||
|
|
||||||
hub->activating = 0;
|
hub->activating = 0;
|
||||||
|
|
||||||
/* If this is a root hub, tell the HCD it's okay to
|
|
||||||
* re-enable port-change interrupts now. */
|
|
||||||
if (!hdev->parent && !hub->busy_bits[0])
|
|
||||||
usb_enable_root_hub_irq(hdev->bus);
|
|
||||||
|
|
||||||
loop_autopm:
|
loop_autopm:
|
||||||
/* Allow autosuspend if we're not going to run again */
|
/* Allow autosuspend if we're not going to run again */
|
||||||
if (list_empty(&hub->event_list))
|
if (list_empty(&hub->event_list))
|
||||||
@ -2890,7 +2967,13 @@ static void hub_events(void)
|
|||||||
|
|
||||||
static int hub_thread(void *__unused)
|
static int hub_thread(void *__unused)
|
||||||
{
|
{
|
||||||
|
/* khubd needs to be freezable to avoid intefering with USB-PERSIST
|
||||||
|
* port handover. Otherwise it might see that a full-speed device
|
||||||
|
* was gone before the EHCI controller had handed its port over to
|
||||||
|
* the companion full-speed controller.
|
||||||
|
*/
|
||||||
set_freezable();
|
set_freezable();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
hub_events();
|
hub_events();
|
||||||
wait_event_freezable(khubd_wait,
|
wait_event_freezable(khubd_wait,
|
||||||
@ -2959,16 +3042,36 @@ void usb_hub_cleanup(void)
|
|||||||
usb_deregister(&hub_driver);
|
usb_deregister(&hub_driver);
|
||||||
} /* usb_hub_cleanup() */
|
} /* usb_hub_cleanup() */
|
||||||
|
|
||||||
static int config_descriptors_changed(struct usb_device *udev)
|
static int descriptors_changed(struct usb_device *udev,
|
||||||
|
struct usb_device_descriptor *old_device_descriptor)
|
||||||
{
|
{
|
||||||
unsigned index;
|
int changed = 0;
|
||||||
unsigned len = 0;
|
unsigned index;
|
||||||
struct usb_config_descriptor *buf;
|
unsigned serial_len = 0;
|
||||||
|
unsigned len;
|
||||||
|
unsigned old_length;
|
||||||
|
int length;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
if (memcmp(&udev->descriptor, old_device_descriptor,
|
||||||
|
sizeof(*old_device_descriptor)) != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Since the idVendor, idProduct, and bcdDevice values in the
|
||||||
|
* device descriptor haven't changed, we will assume the
|
||||||
|
* Manufacturer and Product strings haven't changed either.
|
||||||
|
* But the SerialNumber string could be different (e.g., a
|
||||||
|
* different flash card of the same brand).
|
||||||
|
*/
|
||||||
|
if (udev->serial)
|
||||||
|
serial_len = strlen(udev->serial) + 1;
|
||||||
|
|
||||||
|
len = serial_len;
|
||||||
for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
|
for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
|
||||||
if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
|
old_length = le16_to_cpu(udev->config[index].desc.wTotalLength);
|
||||||
len = le16_to_cpu(udev->config[index].desc.wTotalLength);
|
len = max(len, old_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = kmalloc(len, GFP_NOIO);
|
buf = kmalloc(len, GFP_NOIO);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
dev_err(&udev->dev, "no mem to re-read configs after reset\n");
|
dev_err(&udev->dev, "no mem to re-read configs after reset\n");
|
||||||
@ -2976,25 +3079,41 @@ static int config_descriptors_changed(struct usb_device *udev)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
|
for (index = 0; index < udev->descriptor.bNumConfigurations; index++) {
|
||||||
int length;
|
old_length = le16_to_cpu(udev->config[index].desc.wTotalLength);
|
||||||
int old_length = le16_to_cpu(udev->config[index].desc.wTotalLength);
|
|
||||||
|
|
||||||
length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf,
|
length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf,
|
||||||
old_length);
|
old_length);
|
||||||
if (length < old_length) {
|
if (length != old_length) {
|
||||||
dev_dbg(&udev->dev, "config index %d, error %d\n",
|
dev_dbg(&udev->dev, "config index %d, error %d\n",
|
||||||
index, length);
|
index, length);
|
||||||
|
changed = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (memcmp (buf, udev->rawdescriptors[index], old_length)
|
if (memcmp (buf, udev->rawdescriptors[index], old_length)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
dev_dbg(&udev->dev, "config index %d changed (#%d)\n",
|
dev_dbg(&udev->dev, "config index %d changed (#%d)\n",
|
||||||
index, buf->bConfigurationValue);
|
index,
|
||||||
|
((struct usb_config_descriptor *) buf)->
|
||||||
|
bConfigurationValue);
|
||||||
|
changed = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!changed && serial_len) {
|
||||||
|
length = usb_string(udev, udev->descriptor.iSerialNumber,
|
||||||
|
buf, serial_len);
|
||||||
|
if (length + 1 != serial_len) {
|
||||||
|
dev_dbg(&udev->dev, "serial string error %d\n",
|
||||||
|
length);
|
||||||
|
changed = 1;
|
||||||
|
} else if (memcmp(buf, udev->serial, length) != 0) {
|
||||||
|
dev_dbg(&udev->dev, "serial string changed\n");
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
return index != udev->descriptor.bNumConfigurations;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3044,7 +3163,7 @@ int usb_reset_device(struct usb_device *udev)
|
|||||||
|
|
||||||
if (!parent_hdev) {
|
if (!parent_hdev) {
|
||||||
/* this requires hcd-specific logic; see OHCI hc_restart() */
|
/* this requires hcd-specific logic; see OHCI hc_restart() */
|
||||||
dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__);
|
dev_dbg(&udev->dev, "%s for root hub!\n", __func__);
|
||||||
return -EISDIR;
|
return -EISDIR;
|
||||||
}
|
}
|
||||||
parent_hub = hdev_to_hub(parent_hdev);
|
parent_hub = hdev_to_hub(parent_hdev);
|
||||||
@ -3054,21 +3173,18 @@ int usb_reset_device(struct usb_device *udev)
|
|||||||
|
|
||||||
/* ep0 maxpacket size may change; let the HCD know about it.
|
/* ep0 maxpacket size may change; let the HCD know about it.
|
||||||
* Other endpoints will be handled by re-enumeration. */
|
* Other endpoints will be handled by re-enumeration. */
|
||||||
ep0_reinit(udev);
|
usb_ep0_reinit(udev);
|
||||||
ret = hub_port_init(parent_hub, udev, port1, i);
|
ret = hub_port_init(parent_hub, udev, port1, i);
|
||||||
if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)
|
if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
clear_bit(port1, parent_hub->busy_bits);
|
clear_bit(port1, parent_hub->busy_bits);
|
||||||
if (!parent_hdev->parent && !parent_hub->busy_bits[0])
|
|
||||||
usb_enable_root_hub_irq(parent_hdev->bus);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto re_enumerate;
|
goto re_enumerate;
|
||||||
|
|
||||||
/* Device might have changed firmware (DFU or similar) */
|
/* Device might have changed firmware (DFU or similar) */
|
||||||
if (memcmp(&udev->descriptor, &descriptor, sizeof descriptor)
|
if (descriptors_changed(udev, &descriptor)) {
|
||||||
|| config_descriptors_changed (udev)) {
|
|
||||||
dev_info(&udev->dev, "device firmware changed\n");
|
dev_info(&udev->dev, "device firmware changed\n");
|
||||||
udev->descriptor = descriptor; /* for disconnect() calls */
|
udev->descriptor = descriptor; /* for disconnect() calls */
|
||||||
goto re_enumerate;
|
goto re_enumerate;
|
||||||
|
@ -41,9 +41,10 @@
|
|||||||
*/
|
*/
|
||||||
#define USB_PORT_FEAT_CONNECTION 0
|
#define USB_PORT_FEAT_CONNECTION 0
|
||||||
#define USB_PORT_FEAT_ENABLE 1
|
#define USB_PORT_FEAT_ENABLE 1
|
||||||
#define USB_PORT_FEAT_SUSPEND 2
|
#define USB_PORT_FEAT_SUSPEND 2 /* L2 suspend */
|
||||||
#define USB_PORT_FEAT_OVER_CURRENT 3
|
#define USB_PORT_FEAT_OVER_CURRENT 3
|
||||||
#define USB_PORT_FEAT_RESET 4
|
#define USB_PORT_FEAT_RESET 4
|
||||||
|
#define USB_PORT_FEAT_L1 5 /* L1 suspend */
|
||||||
#define USB_PORT_FEAT_POWER 8
|
#define USB_PORT_FEAT_POWER 8
|
||||||
#define USB_PORT_FEAT_LOWSPEED 9
|
#define USB_PORT_FEAT_LOWSPEED 9
|
||||||
#define USB_PORT_FEAT_HIGHSPEED 10
|
#define USB_PORT_FEAT_HIGHSPEED 10
|
||||||
@ -54,6 +55,7 @@
|
|||||||
#define USB_PORT_FEAT_C_RESET 20
|
#define USB_PORT_FEAT_C_RESET 20
|
||||||
#define USB_PORT_FEAT_TEST 21
|
#define USB_PORT_FEAT_TEST 21
|
||||||
#define USB_PORT_FEAT_INDICATOR 22
|
#define USB_PORT_FEAT_INDICATOR 22
|
||||||
|
#define USB_PORT_FEAT_C_PORT_L1 23
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hub Status and Hub Change results
|
* Hub Status and Hub Change results
|
||||||
@ -73,7 +75,8 @@ struct usb_port_status {
|
|||||||
#define USB_PORT_STAT_SUSPEND 0x0004
|
#define USB_PORT_STAT_SUSPEND 0x0004
|
||||||
#define USB_PORT_STAT_OVERCURRENT 0x0008
|
#define USB_PORT_STAT_OVERCURRENT 0x0008
|
||||||
#define USB_PORT_STAT_RESET 0x0010
|
#define USB_PORT_STAT_RESET 0x0010
|
||||||
/* bits 5 to 7 are reserved */
|
#define USB_PORT_STAT_L1 0x0020
|
||||||
|
/* bits 6 to 7 are reserved */
|
||||||
#define USB_PORT_STAT_POWER 0x0100
|
#define USB_PORT_STAT_POWER 0x0100
|
||||||
#define USB_PORT_STAT_LOW_SPEED 0x0200
|
#define USB_PORT_STAT_LOW_SPEED 0x0200
|
||||||
#define USB_PORT_STAT_HIGH_SPEED 0x0400
|
#define USB_PORT_STAT_HIGH_SPEED 0x0400
|
||||||
@ -91,6 +94,7 @@ struct usb_port_status {
|
|||||||
#define USB_PORT_STAT_C_SUSPEND 0x0004
|
#define USB_PORT_STAT_C_SUSPEND 0x0004
|
||||||
#define USB_PORT_STAT_C_OVERCURRENT 0x0008
|
#define USB_PORT_STAT_C_OVERCURRENT 0x0008
|
||||||
#define USB_PORT_STAT_C_RESET 0x0010
|
#define USB_PORT_STAT_C_RESET 0x0010
|
||||||
|
#define USB_PORT_STAT_C_L1 0x0020
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wHubCharacteristics (masks)
|
* wHubCharacteristics (masks)
|
||||||
@ -191,5 +195,6 @@ struct usb_tt_clear {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe);
|
extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe);
|
||||||
|
extern void usb_ep0_reinit(struct usb_device *);
|
||||||
|
|
||||||
#endif /* __LINUX_HUB_H */
|
#endif /* __LINUX_HUB_H */
|
||||||
|
@ -463,13 +463,13 @@ static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
|
inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
|
||||||
|
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
dbg("%s: could not get inode!",__FUNCTION__);
|
dbg("%s: could not get inode!",__func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
root = d_alloc_root(inode);
|
root = d_alloc_root(inode);
|
||||||
if (!root) {
|
if (!root) {
|
||||||
dbg("%s: could not get root dentry!",__FUNCTION__);
|
dbg("%s: could not get root dentry!",__func__);
|
||||||
iput(inode);
|
iput(inode);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ static void sg_complete(struct urb *urb)
|
|||||||
retval != -EBUSY)
|
retval != -EBUSY)
|
||||||
dev_err(&io->dev->dev,
|
dev_err(&io->dev->dev,
|
||||||
"%s, unlink --> %d\n",
|
"%s, unlink --> %d\n",
|
||||||
__FUNCTION__, retval);
|
__func__, retval);
|
||||||
} else if (urb == io->urbs [i])
|
} else if (urb == io->urbs [i])
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
@ -550,7 +550,7 @@ void usb_sg_wait(struct usb_sg_request *io)
|
|||||||
io->urbs[i]->dev = NULL;
|
io->urbs[i]->dev = NULL;
|
||||||
io->urbs[i]->status = retval;
|
io->urbs[i]->status = retval;
|
||||||
dev_dbg(&io->dev->dev, "%s, submit --> %d\n",
|
dev_dbg(&io->dev->dev, "%s, submit --> %d\n",
|
||||||
__FUNCTION__, retval);
|
__func__, retval);
|
||||||
usb_sg_cancel(io);
|
usb_sg_cancel(io);
|
||||||
}
|
}
|
||||||
spin_lock_irq(&io->lock);
|
spin_lock_irq(&io->lock);
|
||||||
@ -600,7 +600,7 @@ void usb_sg_cancel(struct usb_sg_request *io)
|
|||||||
retval = usb_unlink_urb(io->urbs [i]);
|
retval = usb_unlink_urb(io->urbs [i]);
|
||||||
if (retval != -EINPROGRESS && retval != -EBUSY)
|
if (retval != -EINPROGRESS && retval != -EBUSY)
|
||||||
dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
|
dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
|
||||||
__FUNCTION__, retval);
|
__func__, retval);
|
||||||
}
|
}
|
||||||
spin_lock(&io->lock);
|
spin_lock(&io->lock);
|
||||||
}
|
}
|
||||||
@ -784,7 +784,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
|
|||||||
if (size <= 0 || !buf || !index)
|
if (size <= 0 || !buf || !index)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
tbuf = kmalloc(256, GFP_KERNEL);
|
tbuf = kmalloc(256, GFP_NOIO);
|
||||||
if (!tbuf)
|
if (!tbuf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -1068,7 +1068,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __FUNCTION__,
|
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
|
||||||
skip_ep0 ? "non-ep0" : "all");
|
skip_ep0 ? "non-ep0" : "all");
|
||||||
for (i = skip_ep0; i < 16; ++i) {
|
for (i = skip_ep0; i < 16; ++i) {
|
||||||
usb_disable_endpoint(dev, i);
|
usb_disable_endpoint(dev, i);
|
||||||
@ -1089,8 +1089,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
|
|||||||
continue;
|
continue;
|
||||||
dev_dbg(&dev->dev, "unregistering interface %s\n",
|
dev_dbg(&dev->dev, "unregistering interface %s\n",
|
||||||
interface->dev.bus_id);
|
interface->dev.bus_id);
|
||||||
usb_remove_sysfs_intf_files(interface);
|
|
||||||
device_del(&interface->dev);
|
device_del(&interface->dev);
|
||||||
|
usb_remove_sysfs_intf_files(interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that the interfaces are unbound, nobody should
|
/* Now that the interfaces are unbound, nobody should
|
||||||
@ -1231,7 +1231,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* prevent submissions using previous endpoint settings */
|
/* prevent submissions using previous endpoint settings */
|
||||||
if (iface->cur_altsetting != alt && device_is_registered(&iface->dev))
|
if (iface->cur_altsetting != alt)
|
||||||
usb_remove_sysfs_intf_files(iface);
|
usb_remove_sysfs_intf_files(iface);
|
||||||
usb_disable_interface(dev, iface);
|
usb_disable_interface(dev, iface);
|
||||||
|
|
||||||
@ -1330,8 +1330,7 @@ int usb_reset_configuration(struct usb_device *dev)
|
|||||||
struct usb_interface *intf = config->interface[i];
|
struct usb_interface *intf = config->interface[i];
|
||||||
struct usb_host_interface *alt;
|
struct usb_host_interface *alt;
|
||||||
|
|
||||||
if (device_is_registered(&intf->dev))
|
usb_remove_sysfs_intf_files(intf);
|
||||||
usb_remove_sysfs_intf_files(intf);
|
|
||||||
alt = usb_altnum_to_altsetting(intf, 0);
|
alt = usb_altnum_to_altsetting(intf, 0);
|
||||||
|
|
||||||
/* No altsetting 0? We'll assume the first altsetting.
|
/* No altsetting 0? We'll assume the first altsetting.
|
||||||
|
@ -97,4 +97,18 @@ void usb_detect_quirks(struct usb_device *udev)
|
|||||||
if (udev->descriptor.bDeviceClass != USB_CLASS_HUB)
|
if (udev->descriptor.bDeviceClass != USB_CLASS_HUB)
|
||||||
udev->autosuspend_disabled = 1;
|
udev->autosuspend_disabled = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For the present, all devices default to USB-PERSIST enabled */
|
||||||
|
#if 0 /* was: #ifdef CONFIG_PM */
|
||||||
|
/* Hubs are automatically enabled for USB-PERSIST */
|
||||||
|
if (udev->descriptor.bDeviceClass == USB_CLASS_HUB)
|
||||||
|
udev->persist_enabled = 1;
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* In the absence of PM, we can safely enable USB-PERSIST
|
||||||
|
* for all devices. It will affect things like hub resets
|
||||||
|
* and EMF-related port disables.
|
||||||
|
*/
|
||||||
|
udev->persist_enabled = 1;
|
||||||
|
#endif /* CONFIG_PM */
|
||||||
}
|
}
|
||||||
|
@ -180,11 +180,9 @@ show_urbnum(struct device *dev, struct device_attribute *attr, char *buf)
|
|||||||
static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL);
|
static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL);
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND)
|
#ifdef CONFIG_PM
|
||||||
static const char power_group[] = "power";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_USB_PERSIST
|
static const char power_group[] = "power";
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
show_persist(struct device *dev, struct device_attribute *attr, char *buf)
|
show_persist(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
@ -222,12 +220,13 @@ static int add_persist_attributes(struct device *dev)
|
|||||||
if (is_usb_device(dev)) {
|
if (is_usb_device(dev)) {
|
||||||
struct usb_device *udev = to_usb_device(dev);
|
struct usb_device *udev = to_usb_device(dev);
|
||||||
|
|
||||||
/* Hubs are automatically enabled for USB_PERSIST */
|
/* Hubs are automatically enabled for USB_PERSIST,
|
||||||
if (udev->descriptor.bDeviceClass == USB_CLASS_HUB)
|
* no point in creating the attribute file.
|
||||||
udev->persist_enabled = 1;
|
*/
|
||||||
rc = sysfs_add_file_to_group(&dev->kobj,
|
if (udev->descriptor.bDeviceClass != USB_CLASS_HUB)
|
||||||
&dev_attr_persist.attr,
|
rc = sysfs_add_file_to_group(&dev->kobj,
|
||||||
power_group);
|
&dev_attr_persist.attr,
|
||||||
|
power_group);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -238,13 +237,12 @@ static void remove_persist_attributes(struct device *dev)
|
|||||||
&dev_attr_persist.attr,
|
&dev_attr_persist.attr,
|
||||||
power_group);
|
power_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define add_persist_attributes(dev) 0
|
#define add_persist_attributes(dev) 0
|
||||||
#define remove_persist_attributes(dev) do {} while (0)
|
#define remove_persist_attributes(dev) do {} while (0)
|
||||||
|
|
||||||
#endif /* CONFIG_USB_PERSIST */
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
#ifdef CONFIG_USB_SUSPEND
|
#ifdef CONFIG_USB_SUSPEND
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
|||||||
dev_dbg(&dev->dev,
|
dev_dbg(&dev->dev,
|
||||||
"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
|
"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
|
||||||
usb_endpoint_num(&ep->desc), is_out ? "out" : "in",
|
usb_endpoint_num(&ep->desc), is_out ? "out" : "in",
|
||||||
__FUNCTION__, max);
|
__func__, max);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,6 +589,30 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
|
EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse
|
||||||
|
* @anchor: anchor the requests are bound to
|
||||||
|
*
|
||||||
|
* this allows all outstanding URBs to be unlinked starting
|
||||||
|
* from the back of the queue. This function is asynchronous.
|
||||||
|
* The unlinking is just tiggered. It may happen after this
|
||||||
|
* function has returned.
|
||||||
|
*/
|
||||||
|
void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
|
||||||
|
{
|
||||||
|
struct urb *victim;
|
||||||
|
|
||||||
|
spin_lock_irq(&anchor->lock);
|
||||||
|
while (!list_empty(&anchor->urb_list)) {
|
||||||
|
victim = list_entry(anchor->urb_list.prev, struct urb,
|
||||||
|
anchor_list);
|
||||||
|
/* this will unanchor the URB */
|
||||||
|
usb_unlink_urb(victim);
|
||||||
|
}
|
||||||
|
spin_unlock_irq(&anchor->lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* usb_wait_anchor_empty_timeout - wait for an anchor to be unused
|
* usb_wait_anchor_empty_timeout - wait for an anchor to be unused
|
||||||
* @anchor: the anchor you want to become unused
|
* @anchor: the anchor you want to become unused
|
||||||
|
@ -114,13 +114,11 @@ static inline int is_usb_device_driver(struct device_driver *drv)
|
|||||||
static inline void mark_active(struct usb_interface *f)
|
static inline void mark_active(struct usb_interface *f)
|
||||||
{
|
{
|
||||||
f->is_active = 1;
|
f->is_active = 1;
|
||||||
f->dev.power.power_state.event = PM_EVENT_ON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mark_quiesced(struct usb_interface *f)
|
static inline void mark_quiesced(struct usb_interface *f)
|
||||||
{
|
{
|
||||||
f->is_active = 0;
|
f->is_active = 0;
|
||||||
f->dev.power.power_state.event = PM_EVENT_SUSPEND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int is_active(const struct usb_interface *f)
|
static inline int is_active(const struct usb_interface *f)
|
||||||
|
@ -44,8 +44,8 @@ menuconfig USB_GADGET
|
|||||||
if USB_GADGET
|
if USB_GADGET
|
||||||
|
|
||||||
config USB_GADGET_DEBUG
|
config USB_GADGET_DEBUG
|
||||||
boolean "Debugging messages"
|
boolean "Debugging messages (DEVELOPMENT)"
|
||||||
depends on USB_GADGET && DEBUG_KERNEL && EXPERIMENTAL
|
depends on USB_GADGET && DEBUG_KERNEL
|
||||||
help
|
help
|
||||||
Many controller and gadget drivers will print some debugging
|
Many controller and gadget drivers will print some debugging
|
||||||
messages if you use this option to ask for those messages.
|
messages if you use this option to ask for those messages.
|
||||||
@ -58,7 +58,7 @@ config USB_GADGET_DEBUG
|
|||||||
production build.
|
production build.
|
||||||
|
|
||||||
config USB_GADGET_DEBUG_FILES
|
config USB_GADGET_DEBUG_FILES
|
||||||
boolean "Debugging information files"
|
boolean "Debugging information files (DEVELOPMENT)"
|
||||||
depends on USB_GADGET && PROC_FS
|
depends on USB_GADGET && PROC_FS
|
||||||
help
|
help
|
||||||
Some of the drivers in the "gadget" framework can expose
|
Some of the drivers in the "gadget" framework can expose
|
||||||
@ -69,7 +69,7 @@ config USB_GADGET_DEBUG_FILES
|
|||||||
here. If in doubt, or to conserve kernel memory, say "N".
|
here. If in doubt, or to conserve kernel memory, say "N".
|
||||||
|
|
||||||
config USB_GADGET_DEBUG_FS
|
config USB_GADGET_DEBUG_FS
|
||||||
boolean "Debugging information files in debugfs"
|
boolean "Debugging information files in debugfs (DEVELOPMENT)"
|
||||||
depends on USB_GADGET && DEBUG_FS
|
depends on USB_GADGET && DEBUG_FS
|
||||||
help
|
help
|
||||||
Some of the drivers in the "gadget" framework can expose
|
Some of the drivers in the "gadget" framework can expose
|
||||||
@ -337,7 +337,7 @@ config USB_AT91
|
|||||||
|
|
||||||
config USB_GADGET_DUMMY_HCD
|
config USB_GADGET_DUMMY_HCD
|
||||||
boolean "Dummy HCD (DEVELOPMENT)"
|
boolean "Dummy HCD (DEVELOPMENT)"
|
||||||
depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL
|
depends on USB=y || (USB=m && USB_GADGET=m)
|
||||||
select USB_GADGET_DUALSPEED
|
select USB_GADGET_DUALSPEED
|
||||||
help
|
help
|
||||||
This host controller driver emulates USB, looping all data transfer
|
This host controller driver emulates USB, looping all data transfer
|
||||||
@ -404,7 +404,6 @@ choice
|
|||||||
|
|
||||||
config USB_ZERO
|
config USB_ZERO
|
||||||
tristate "Gadget Zero (DEVELOPMENT)"
|
tristate "Gadget Zero (DEVELOPMENT)"
|
||||||
depends on EXPERIMENTAL
|
|
||||||
help
|
help
|
||||||
Gadget Zero is a two-configuration device. It either sinks and
|
Gadget Zero is a two-configuration device. It either sinks and
|
||||||
sources bulk data; or it loops back a configurable number of
|
sources bulk data; or it loops back a configurable number of
|
||||||
@ -468,8 +467,8 @@ config USB_ETH
|
|||||||
dynamically linked module called "g_ether".
|
dynamically linked module called "g_ether".
|
||||||
|
|
||||||
config USB_ETH_RNDIS
|
config USB_ETH_RNDIS
|
||||||
bool "RNDIS support (EXPERIMENTAL)"
|
bool "RNDIS support"
|
||||||
depends on USB_ETH && EXPERIMENTAL
|
depends on USB_ETH
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
|
Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
|
||||||
@ -495,6 +494,9 @@ config USB_GADGETFS
|
|||||||
All endpoints, transfer speeds, and transfer types supported by
|
All endpoints, transfer speeds, and transfer types supported by
|
||||||
the hardware are available, through read() and write() calls.
|
the hardware are available, through read() and write() calls.
|
||||||
|
|
||||||
|
Currently, this option is still labelled as EXPERIMENTAL because
|
||||||
|
of existing race conditions in the underlying in-kernel AIO core.
|
||||||
|
|
||||||
Say "y" to link the driver statically, or "m" to build a
|
Say "y" to link the driver statically, or "m" to build a
|
||||||
dynamically linked module called "gadgetfs".
|
dynamically linked module called "gadgetfs".
|
||||||
|
|
||||||
|
@ -3248,6 +3248,8 @@ static int udc_pci_probe(
|
|||||||
|
|
||||||
/* pci setup */
|
/* pci setup */
|
||||||
if (pci_enable_device(pdev) < 0) {
|
if (pci_enable_device(pdev) < 0) {
|
||||||
|
kfree(dev);
|
||||||
|
dev = 0;
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto finished;
|
goto finished;
|
||||||
}
|
}
|
||||||
@ -3259,6 +3261,8 @@ static int udc_pci_probe(
|
|||||||
|
|
||||||
if (!request_mem_region(resource, len, name)) {
|
if (!request_mem_region(resource, len, name)) {
|
||||||
dev_dbg(&pdev->dev, "pci device used already\n");
|
dev_dbg(&pdev->dev, "pci device used already\n");
|
||||||
|
kfree(dev);
|
||||||
|
dev = 0;
|
||||||
retval = -EBUSY;
|
retval = -EBUSY;
|
||||||
goto finished;
|
goto finished;
|
||||||
}
|
}
|
||||||
@ -3267,18 +3271,24 @@ static int udc_pci_probe(
|
|||||||
dev->virt_addr = ioremap_nocache(resource, len);
|
dev->virt_addr = ioremap_nocache(resource, len);
|
||||||
if (dev->virt_addr == NULL) {
|
if (dev->virt_addr == NULL) {
|
||||||
dev_dbg(&pdev->dev, "start address cannot be mapped\n");
|
dev_dbg(&pdev->dev, "start address cannot be mapped\n");
|
||||||
|
kfree(dev);
|
||||||
|
dev = 0;
|
||||||
retval = -EFAULT;
|
retval = -EFAULT;
|
||||||
goto finished;
|
goto finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pdev->irq) {
|
if (!pdev->irq) {
|
||||||
dev_err(&dev->pdev->dev, "irq not set\n");
|
dev_err(&dev->pdev->dev, "irq not set\n");
|
||||||
|
kfree(dev);
|
||||||
|
dev = 0;
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto finished;
|
goto finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
|
if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
|
||||||
dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
|
dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
|
||||||
|
kfree(dev);
|
||||||
|
dev = 0;
|
||||||
retval = -EBUSY;
|
retval = -EBUSY;
|
||||||
goto finished;
|
goto finished;
|
||||||
}
|
}
|
||||||
|
@ -389,6 +389,7 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req)
|
|||||||
u32 csr = __raw_readl(creg);
|
u32 csr = __raw_readl(creg);
|
||||||
u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0));
|
u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0));
|
||||||
unsigned total, count, is_last;
|
unsigned total, count, is_last;
|
||||||
|
u8 *buf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: allow for writing two packets to the fifo ... that'll
|
* TODO: allow for writing two packets to the fifo ... that'll
|
||||||
@ -413,6 +414,8 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf = req->req.buf + req->req.actual;
|
||||||
|
prefetch(buf);
|
||||||
total = req->req.length - req->req.actual;
|
total = req->req.length - req->req.actual;
|
||||||
if (ep->ep.maxpacket < total) {
|
if (ep->ep.maxpacket < total) {
|
||||||
count = ep->ep.maxpacket;
|
count = ep->ep.maxpacket;
|
||||||
@ -435,7 +438,7 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req)
|
|||||||
* recover when the actual bytecount matters (e.g. for USB Test
|
* recover when the actual bytecount matters (e.g. for USB Test
|
||||||
* and Measurement Class devices).
|
* and Measurement Class devices).
|
||||||
*/
|
*/
|
||||||
__raw_writesb(dreg, req->req.buf + req->req.actual, count);
|
__raw_writesb(dreg, buf, count);
|
||||||
csr &= ~SET_FX;
|
csr &= ~SET_FX;
|
||||||
csr |= CLR_FX | AT91_UDP_TXPKTRDY;
|
csr |= CLR_FX | AT91_UDP_TXPKTRDY;
|
||||||
__raw_writel(csr, creg);
|
__raw_writel(csr, creg);
|
||||||
@ -457,7 +460,7 @@ static void nuke(struct at91_ep *ep, int status)
|
|||||||
if (list_empty(&ep->queue))
|
if (list_empty(&ep->queue))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VDBG("%s %s\n", __FUNCTION__, ep->ep.name);
|
VDBG("%s %s\n", __func__, ep->ep.name);
|
||||||
while (!list_empty(&ep->queue)) {
|
while (!list_empty(&ep->queue)) {
|
||||||
req = list_entry(ep->queue.next, struct at91_request, queue);
|
req = list_entry(ep->queue.next, struct at91_request, queue);
|
||||||
done(ep, req, status);
|
done(ep, req, status);
|
||||||
@ -792,7 +795,7 @@ static int at91_wakeup(struct usb_gadget *gadget)
|
|||||||
int status = -EINVAL;
|
int status = -EINVAL;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DBG("%s\n", __FUNCTION__ );
|
DBG("%s\n", __func__ );
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
if (!udc->clocked || !udc->suspended)
|
if (!udc->clocked || !udc->suspended)
|
||||||
|
@ -365,16 +365,14 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
|
|||||||
case USB_SPEED_HIGH:
|
case USB_SPEED_HIGH:
|
||||||
if (max == 512)
|
if (max == 512)
|
||||||
break;
|
break;
|
||||||
/* conserve return statements */
|
goto done;
|
||||||
default:
|
case USB_SPEED_FULL:
|
||||||
switch (max) {
|
if (max == 8 || max == 16 || max == 32 || max == 64)
|
||||||
case 8: case 16: case 32: case 64:
|
|
||||||
/* we'll fake any legal size */
|
/* we'll fake any legal size */
|
||||||
break;
|
break;
|
||||||
default:
|
/* save a return statement */
|
||||||
case USB_SPEED_LOW:
|
default:
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_ENDPOINT_XFER_INT:
|
case USB_ENDPOINT_XFER_INT:
|
||||||
@ -894,13 +892,12 @@ static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state)
|
|||||||
{
|
{
|
||||||
struct dummy *dum = platform_get_drvdata(pdev);
|
struct dummy *dum = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
|
dev_dbg (&pdev->dev, "%s\n", __func__);
|
||||||
spin_lock_irq (&dum->lock);
|
spin_lock_irq (&dum->lock);
|
||||||
dum->udc_suspended = 1;
|
dum->udc_suspended = 1;
|
||||||
set_link_state (dum);
|
set_link_state (dum);
|
||||||
spin_unlock_irq (&dum->lock);
|
spin_unlock_irq (&dum->lock);
|
||||||
|
|
||||||
pdev->dev.power.power_state = state;
|
|
||||||
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
|
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -909,13 +906,12 @@ static int dummy_udc_resume (struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct dummy *dum = platform_get_drvdata(pdev);
|
struct dummy *dum = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
|
dev_dbg (&pdev->dev, "%s\n", __func__);
|
||||||
spin_lock_irq (&dum->lock);
|
spin_lock_irq (&dum->lock);
|
||||||
dum->udc_suspended = 0;
|
dum->udc_suspended = 0;
|
||||||
set_link_state (dum);
|
set_link_state (dum);
|
||||||
spin_unlock_irq (&dum->lock);
|
spin_unlock_irq (&dum->lock);
|
||||||
|
|
||||||
pdev->dev.power.power_state = PMSG_ON;
|
|
||||||
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
|
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1711,7 +1707,7 @@ static int dummy_bus_suspend (struct usb_hcd *hcd)
|
|||||||
{
|
{
|
||||||
struct dummy *dum = hcd_to_dummy (hcd);
|
struct dummy *dum = hcd_to_dummy (hcd);
|
||||||
|
|
||||||
dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__);
|
dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__);
|
||||||
|
|
||||||
spin_lock_irq (&dum->lock);
|
spin_lock_irq (&dum->lock);
|
||||||
dum->rh_state = DUMMY_RH_SUSPENDED;
|
dum->rh_state = DUMMY_RH_SUSPENDED;
|
||||||
@ -1726,7 +1722,7 @@ static int dummy_bus_resume (struct usb_hcd *hcd)
|
|||||||
struct dummy *dum = hcd_to_dummy (hcd);
|
struct dummy *dum = hcd_to_dummy (hcd);
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__);
|
dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__);
|
||||||
|
|
||||||
spin_lock_irq (&dum->lock);
|
spin_lock_irq (&dum->lock);
|
||||||
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
|
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
|
||||||
@ -1900,7 +1896,7 @@ static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state)
|
|||||||
struct dummy *dum;
|
struct dummy *dum;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
|
dev_dbg (&pdev->dev, "%s\n", __func__);
|
||||||
|
|
||||||
hcd = platform_get_drvdata (pdev);
|
hcd = platform_get_drvdata (pdev);
|
||||||
dum = hcd_to_dummy (hcd);
|
dum = hcd_to_dummy (hcd);
|
||||||
@ -1916,7 +1912,7 @@ static int dummy_hcd_resume (struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct usb_hcd *hcd;
|
struct usb_hcd *hcd;
|
||||||
|
|
||||||
dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
|
dev_dbg (&pdev->dev, "%s\n", __func__);
|
||||||
|
|
||||||
hcd = platform_get_drvdata (pdev);
|
hcd = platform_get_drvdata (pdev);
|
||||||
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
||||||
@ -1937,69 +1933,57 @@ static struct platform_driver dummy_hcd_driver = {
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* These don't need to do anything because the pdev structures are
|
static struct platform_device *the_udc_pdev;
|
||||||
* statically allocated. */
|
static struct platform_device *the_hcd_pdev;
|
||||||
static void
|
|
||||||
dummy_udc_release (struct device *dev) {}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dummy_hcd_release (struct device *dev) {}
|
|
||||||
|
|
||||||
static struct platform_device the_udc_pdev = {
|
|
||||||
.name = (char *) gadget_name,
|
|
||||||
.id = -1,
|
|
||||||
.dev = {
|
|
||||||
.release = dummy_udc_release,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device the_hcd_pdev = {
|
|
||||||
.name = (char *) driver_name,
|
|
||||||
.id = -1,
|
|
||||||
.dev = {
|
|
||||||
.release = dummy_hcd_release,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init init (void)
|
static int __init init (void)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval = -ENOMEM;
|
||||||
|
|
||||||
if (usb_disabled ())
|
if (usb_disabled ())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
retval = platform_driver_register (&dummy_hcd_driver);
|
the_hcd_pdev = platform_device_alloc(driver_name, -1);
|
||||||
if (retval < 0)
|
if (!the_hcd_pdev)
|
||||||
return retval;
|
return retval;
|
||||||
|
the_udc_pdev = platform_device_alloc(gadget_name, -1);
|
||||||
|
if (!the_udc_pdev)
|
||||||
|
goto err_alloc_udc;
|
||||||
|
|
||||||
retval = platform_driver_register (&dummy_udc_driver);
|
retval = platform_driver_register(&dummy_hcd_driver);
|
||||||
|
if (retval < 0)
|
||||||
|
goto err_register_hcd_driver;
|
||||||
|
retval = platform_driver_register(&dummy_udc_driver);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_register_udc_driver;
|
goto err_register_udc_driver;
|
||||||
|
|
||||||
retval = platform_device_register (&the_hcd_pdev);
|
retval = platform_device_add(the_hcd_pdev);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_register_hcd;
|
goto err_add_hcd;
|
||||||
|
retval = platform_device_add(the_udc_pdev);
|
||||||
retval = platform_device_register (&the_udc_pdev);
|
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_register_udc;
|
goto err_add_udc;
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
err_register_udc:
|
err_add_udc:
|
||||||
platform_device_unregister (&the_hcd_pdev);
|
platform_device_del(the_hcd_pdev);
|
||||||
err_register_hcd:
|
err_add_hcd:
|
||||||
platform_driver_unregister (&dummy_udc_driver);
|
platform_driver_unregister(&dummy_udc_driver);
|
||||||
err_register_udc_driver:
|
err_register_udc_driver:
|
||||||
platform_driver_unregister (&dummy_hcd_driver);
|
platform_driver_unregister(&dummy_hcd_driver);
|
||||||
|
err_register_hcd_driver:
|
||||||
|
platform_device_put(the_udc_pdev);
|
||||||
|
err_alloc_udc:
|
||||||
|
platform_device_put(the_hcd_pdev);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
module_init (init);
|
module_init (init);
|
||||||
|
|
||||||
static void __exit cleanup (void)
|
static void __exit cleanup (void)
|
||||||
{
|
{
|
||||||
platform_device_unregister (&the_udc_pdev);
|
platform_device_unregister(the_udc_pdev);
|
||||||
platform_device_unregister (&the_hcd_pdev);
|
platform_device_unregister(the_hcd_pdev);
|
||||||
platform_driver_unregister (&dummy_udc_driver);
|
platform_driver_unregister(&dummy_udc_driver);
|
||||||
platform_driver_unregister (&dummy_hcd_driver);
|
platform_driver_unregister(&dummy_hcd_driver);
|
||||||
}
|
}
|
||||||
module_exit (cleanup);
|
module_exit (cleanup);
|
||||||
|
@ -34,12 +34,12 @@
|
|||||||
|
|
||||||
|
|
||||||
/* we must assign addresses for configurable endpoints (like net2280) */
|
/* we must assign addresses for configurable endpoints (like net2280) */
|
||||||
static __devinitdata unsigned epnum;
|
static __initdata unsigned epnum;
|
||||||
|
|
||||||
// #define MANY_ENDPOINTS
|
// #define MANY_ENDPOINTS
|
||||||
#ifdef MANY_ENDPOINTS
|
#ifdef MANY_ENDPOINTS
|
||||||
/* more than 15 configurable endpoints */
|
/* more than 15 configurable endpoints */
|
||||||
static __devinitdata unsigned in_epnum;
|
static __initdata unsigned in_epnum;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ static __devinitdata unsigned in_epnum;
|
|||||||
* NOTE: each endpoint is unidirectional, as specified by its USB
|
* NOTE: each endpoint is unidirectional, as specified by its USB
|
||||||
* descriptor; and isn't specific to a configuration or altsetting.
|
* descriptor; and isn't specific to a configuration or altsetting.
|
||||||
*/
|
*/
|
||||||
static int __devinit
|
static int __init
|
||||||
ep_matches (
|
ep_matches (
|
||||||
struct usb_gadget *gadget,
|
struct usb_gadget *gadget,
|
||||||
struct usb_ep *ep,
|
struct usb_ep *ep,
|
||||||
@ -186,7 +186,7 @@ ep_matches (
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_ep * __devinit
|
static struct usb_ep * __init
|
||||||
find_ep (struct usb_gadget *gadget, const char *name)
|
find_ep (struct usb_gadget *gadget, const char *name)
|
||||||
{
|
{
|
||||||
struct usb_ep *ep;
|
struct usb_ep *ep;
|
||||||
@ -228,7 +228,7 @@ find_ep (struct usb_gadget *gadget, const char *name)
|
|||||||
*
|
*
|
||||||
* On failure, this returns a null endpoint descriptor.
|
* On failure, this returns a null endpoint descriptor.
|
||||||
*/
|
*/
|
||||||
struct usb_ep * __devinit usb_ep_autoconfig (
|
struct usb_ep * __init usb_ep_autoconfig (
|
||||||
struct usb_gadget *gadget,
|
struct usb_gadget *gadget,
|
||||||
struct usb_endpoint_descriptor *desc
|
struct usb_endpoint_descriptor *desc
|
||||||
)
|
)
|
||||||
@ -295,7 +295,7 @@ struct usb_ep * __devinit usb_ep_autoconfig (
|
|||||||
* state such as ep->driver_data and the record of assigned endpoints
|
* state such as ep->driver_data and the record of assigned endpoints
|
||||||
* used by usb_ep_autoconfig().
|
* used by usb_ep_autoconfig().
|
||||||
*/
|
*/
|
||||||
void __devinit usb_ep_autoconfig_reset (struct usb_gadget *gadget)
|
void __init usb_ep_autoconfig_reset (struct usb_gadget *gadget)
|
||||||
{
|
{
|
||||||
struct usb_ep *ep;
|
struct usb_ep *ep;
|
||||||
|
|
||||||
|
@ -1102,7 +1102,7 @@ static void eth_reset_config (struct eth_dev *dev)
|
|||||||
if (dev->config == 0)
|
if (dev->config == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DEBUG (dev, "%s\n", __FUNCTION__);
|
DEBUG (dev, "%s\n", __func__);
|
||||||
|
|
||||||
netif_stop_queue (dev->net);
|
netif_stop_queue (dev->net);
|
||||||
netif_carrier_off (dev->net);
|
netif_carrier_off (dev->net);
|
||||||
@ -1263,7 +1263,7 @@ static void issue_start_status (struct eth_dev *dev)
|
|||||||
struct usb_cdc_notification *event;
|
struct usb_cdc_notification *event;
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
DEBUG (dev, "%s, flush old status first\n", __FUNCTION__);
|
DEBUG (dev, "%s, flush old status first\n", __func__);
|
||||||
|
|
||||||
/* flush old status
|
/* flush old status
|
||||||
*
|
*
|
||||||
@ -1329,7 +1329,7 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
|
|||||||
spin_lock(&dev->lock);
|
spin_lock(&dev->lock);
|
||||||
status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf);
|
status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
ERROR(dev, "%s: rndis parse error %d\n", __FUNCTION__, status);
|
ERROR(dev, "%s: rndis parse error %d\n", __func__, status);
|
||||||
spin_unlock(&dev->lock);
|
spin_unlock(&dev->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2113,7 +2113,7 @@ static int rndis_control_ack (struct net_device *net)
|
|||||||
|
|
||||||
static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
|
static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
|
||||||
{
|
{
|
||||||
DEBUG (dev, "%s\n", __FUNCTION__);
|
DEBUG (dev, "%s\n", __func__);
|
||||||
|
|
||||||
/* fill the rx queue */
|
/* fill the rx queue */
|
||||||
rx_fill (dev, gfp_flags);
|
rx_fill (dev, gfp_flags);
|
||||||
@ -2133,7 +2133,7 @@ static int eth_open (struct net_device *net)
|
|||||||
{
|
{
|
||||||
struct eth_dev *dev = netdev_priv(net);
|
struct eth_dev *dev = netdev_priv(net);
|
||||||
|
|
||||||
DEBUG (dev, "%s\n", __FUNCTION__);
|
DEBUG (dev, "%s\n", __func__);
|
||||||
if (netif_carrier_ok (dev->net))
|
if (netif_carrier_ok (dev->net))
|
||||||
eth_start (dev, GFP_KERNEL);
|
eth_start (dev, GFP_KERNEL);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2143,7 +2143,7 @@ static int eth_stop (struct net_device *net)
|
|||||||
{
|
{
|
||||||
struct eth_dev *dev = netdev_priv(net);
|
struct eth_dev *dev = netdev_priv(net);
|
||||||
|
|
||||||
VDEBUG (dev, "%s\n", __FUNCTION__);
|
VDEBUG (dev, "%s\n", __func__);
|
||||||
netif_stop_queue (net);
|
netif_stop_queue (net);
|
||||||
|
|
||||||
DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
|
DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
|
||||||
@ -2229,7 +2229,7 @@ eth_unbind (struct usb_gadget *gadget)
|
|||||||
set_gadget_data (gadget, NULL);
|
set_gadget_data (gadget, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 __devinit nibble (unsigned char c)
|
static u8 __init nibble (unsigned char c)
|
||||||
{
|
{
|
||||||
if (likely (isdigit (c)))
|
if (likely (isdigit (c)))
|
||||||
return c - '0';
|
return c - '0';
|
||||||
@ -2239,7 +2239,7 @@ static u8 __devinit nibble (unsigned char c)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit get_ether_addr(const char *str, u8 *dev_addr)
|
static int __init get_ether_addr(const char *str, u8 *dev_addr)
|
||||||
{
|
{
|
||||||
if (str) {
|
if (str) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -2260,7 +2260,7 @@ static int __devinit get_ether_addr(const char *str, u8 *dev_addr)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit
|
static int __init
|
||||||
eth_bind (struct usb_gadget *gadget)
|
eth_bind (struct usb_gadget *gadget)
|
||||||
{
|
{
|
||||||
struct eth_dev *dev;
|
struct eth_dev *dev;
|
||||||
|
@ -644,7 +644,7 @@ struct fsg_dev {
|
|||||||
|
|
||||||
unsigned long atomic_bitflags;
|
unsigned long atomic_bitflags;
|
||||||
#define REGISTERED 0
|
#define REGISTERED 0
|
||||||
#define CLEAR_BULK_HALTS 1
|
#define IGNORE_BULK_OUT 1
|
||||||
#define SUSPENDED 2
|
#define SUSPENDED 2
|
||||||
|
|
||||||
struct usb_ep *bulk_in;
|
struct usb_ep *bulk_in;
|
||||||
@ -1104,7 +1104,7 @@ static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
|
|||||||
if (req->actual > 0)
|
if (req->actual > 0)
|
||||||
dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual);
|
dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual);
|
||||||
if (req->status || req->actual != req->length)
|
if (req->status || req->actual != req->length)
|
||||||
DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
|
DBG(fsg, "%s --> %d, %u/%u\n", __func__,
|
||||||
req->status, req->actual, req->length);
|
req->status, req->actual, req->length);
|
||||||
if (req->status == -ECONNRESET) // Request was cancelled
|
if (req->status == -ECONNRESET) // Request was cancelled
|
||||||
usb_ep_fifo_flush(ep);
|
usb_ep_fifo_flush(ep);
|
||||||
@ -1125,7 +1125,7 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
|
|||||||
struct fsg_buffhd *bh = req->context;
|
struct fsg_buffhd *bh = req->context;
|
||||||
|
|
||||||
if (req->status || req->actual != req->length)
|
if (req->status || req->actual != req->length)
|
||||||
DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
|
DBG(fsg, "%s --> %d, %u/%u\n", __func__,
|
||||||
req->status, req->actual, req->length);
|
req->status, req->actual, req->length);
|
||||||
if (req->status == -ECONNRESET) // Request was cancelled
|
if (req->status == -ECONNRESET) // Request was cancelled
|
||||||
usb_ep_fifo_flush(ep);
|
usb_ep_fifo_flush(ep);
|
||||||
@ -1146,7 +1146,7 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
|
|||||||
|
|
||||||
dump_msg(fsg, "bulk-out", req->buf, req->actual);
|
dump_msg(fsg, "bulk-out", req->buf, req->actual);
|
||||||
if (req->status || req->actual != bh->bulk_out_intended_length)
|
if (req->status || req->actual != bh->bulk_out_intended_length)
|
||||||
DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
|
DBG(fsg, "%s --> %d, %u/%u\n", __func__,
|
||||||
req->status, req->actual,
|
req->status, req->actual,
|
||||||
bh->bulk_out_intended_length);
|
bh->bulk_out_intended_length);
|
||||||
if (req->status == -ECONNRESET) // Request was cancelled
|
if (req->status == -ECONNRESET) // Request was cancelled
|
||||||
@ -1169,7 +1169,7 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
|
|||||||
struct fsg_buffhd *bh = req->context;
|
struct fsg_buffhd *bh = req->context;
|
||||||
|
|
||||||
if (req->status || req->actual != req->length)
|
if (req->status || req->actual != req->length)
|
||||||
DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
|
DBG(fsg, "%s --> %d, %u/%u\n", __func__,
|
||||||
req->status, req->actual, req->length);
|
req->status, req->actual, req->length);
|
||||||
if (req->status == -ECONNRESET) // Request was cancelled
|
if (req->status == -ECONNRESET) // Request was cancelled
|
||||||
usb_ep_fifo_flush(ep);
|
usb_ep_fifo_flush(ep);
|
||||||
@ -2936,8 +2936,8 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
|
|||||||
struct usb_request *req = bh->outreq;
|
struct usb_request *req = bh->outreq;
|
||||||
struct bulk_cb_wrap *cbw = req->buf;
|
struct bulk_cb_wrap *cbw = req->buf;
|
||||||
|
|
||||||
/* Was this a real packet? */
|
/* Was this a real packet? Should it be ignored? */
|
||||||
if (req->status)
|
if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Is the CBW valid? */
|
/* Is the CBW valid? */
|
||||||
@ -2948,13 +2948,17 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
|
|||||||
req->actual,
|
req->actual,
|
||||||
le32_to_cpu(cbw->Signature));
|
le32_to_cpu(cbw->Signature));
|
||||||
|
|
||||||
/* The Bulk-only spec says we MUST stall the bulk pipes!
|
/* The Bulk-only spec says we MUST stall the IN endpoint
|
||||||
* If we want to avoid stalls, set a flag so that we will
|
* (6.6.1), so it's unavoidable. It also says we must
|
||||||
* clear the endpoint halts at the next reset. */
|
* retain this state until the next reset, but there's
|
||||||
if (!mod_data.can_stall)
|
* no way to tell the controller driver it should ignore
|
||||||
set_bit(CLEAR_BULK_HALTS, &fsg->atomic_bitflags);
|
* Clear-Feature(HALT) requests.
|
||||||
fsg_set_halt(fsg, fsg->bulk_out);
|
*
|
||||||
|
* We aren't required to halt the OUT endpoint; instead
|
||||||
|
* we can simply accept and discard any data received
|
||||||
|
* until the next reset. */
|
||||||
halt_bulk_in_endpoint(fsg);
|
halt_bulk_in_endpoint(fsg);
|
||||||
|
set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3140,6 +3144,7 @@ static int do_set_interface(struct fsg_dev *fsg, int altsetting)
|
|||||||
goto reset;
|
goto reset;
|
||||||
fsg->bulk_out_enabled = 1;
|
fsg->bulk_out_enabled = 1;
|
||||||
fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
|
fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
|
||||||
|
clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
|
||||||
|
|
||||||
if (transport_is_cbi()) {
|
if (transport_is_cbi()) {
|
||||||
d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
|
d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
|
||||||
@ -3321,11 +3326,8 @@ static void handle_exception(struct fsg_dev *fsg)
|
|||||||
/* In case we were forced against our will to halt a
|
/* In case we were forced against our will to halt a
|
||||||
* bulk endpoint, clear the halt now. (The SuperH UDC
|
* bulk endpoint, clear the halt now. (The SuperH UDC
|
||||||
* requires this.) */
|
* requires this.) */
|
||||||
if (test_and_clear_bit(CLEAR_BULK_HALTS,
|
if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
|
||||||
&fsg->atomic_bitflags)) {
|
|
||||||
usb_ep_clear_halt(fsg->bulk_in);
|
usb_ep_clear_halt(fsg->bulk_in);
|
||||||
usb_ep_clear_halt(fsg->bulk_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transport_is_bbb()) {
|
if (transport_is_bbb()) {
|
||||||
if (fsg->ep0_req_tag == exception_req_tag)
|
if (fsg->ep0_req_tag == exception_req_tag)
|
||||||
|
@ -773,11 +773,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||||||
/* catch various bogus parameters */
|
/* catch various bogus parameters */
|
||||||
if (!_req || !req->req.complete || !req->req.buf
|
if (!_req || !req->req.complete || !req->req.buf
|
||||||
|| !list_empty(&req->queue)) {
|
|| !list_empty(&req->queue)) {
|
||||||
VDBG("%s, bad params\n", __FUNCTION__);
|
VDBG("%s, bad params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (unlikely(!_ep || !ep->desc)) {
|
if (unlikely(!_ep || !ep->desc)) {
|
||||||
VDBG("%s, bad ep\n", __FUNCTION__);
|
VDBG("%s, bad ep\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||||
|
@ -512,7 +512,7 @@ struct fsl_udc {
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt "\n", \
|
#define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt "\n", \
|
||||||
__FUNCTION__, ## args)
|
__func__, ## args)
|
||||||
#else
|
#else
|
||||||
#define DBG(fmt, args...) do{}while(0)
|
#define DBG(fmt, args...) do{}while(0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1149,7 +1149,7 @@ static int gmidi_register_card(struct gmidi_device *dev)
|
|||||||
/*
|
/*
|
||||||
* Creates an output endpoint, and initializes output ports.
|
* Creates an output endpoint, and initializes output ports.
|
||||||
*/
|
*/
|
||||||
static int __devinit gmidi_bind(struct usb_gadget *gadget)
|
static int __init gmidi_bind(struct usb_gadget *gadget)
|
||||||
{
|
{
|
||||||
struct gmidi_device *dev;
|
struct gmidi_device *dev;
|
||||||
struct usb_ep *in_ep, *out_ep;
|
struct usb_ep *in_ep, *out_ep;
|
||||||
|
@ -692,7 +692,7 @@ static void abort_dma(struct goku_ep *ep, int status)
|
|||||||
req->req.actual = (curr - req->req.dma) + 1;
|
req->req.actual = (curr - req->req.dma) + 1;
|
||||||
req->req.status = status;
|
req->req.status = status;
|
||||||
|
|
||||||
VDBG(ep->dev, "%s %s %s %d/%d\n", __FUNCTION__, ep->ep.name,
|
VDBG(ep->dev, "%s %s %s %d/%d\n", __func__, ep->ep.name,
|
||||||
ep->is_in ? "IN" : "OUT",
|
ep->is_in ? "IN" : "OUT",
|
||||||
req->req.actual, req->req.length);
|
req->req.actual, req->req.length);
|
||||||
|
|
||||||
@ -826,7 +826,7 @@ static int goku_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
|||||||
if (dev->ep0state == EP0_SUSPEND)
|
if (dev->ep0state == EP0_SUSPEND)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
VDBG(dev, "%s %s %s %s %p\n", __FUNCTION__, _ep->name,
|
VDBG(dev, "%s %s %s %s %p\n", __func__, _ep->name,
|
||||||
ep->is_in ? "IN" : "OUT",
|
ep->is_in ? "IN" : "OUT",
|
||||||
ep->dma ? "dma" : "pio",
|
ep->dma ? "dma" : "pio",
|
||||||
_req);
|
_req);
|
||||||
@ -898,7 +898,7 @@ static int goku_set_halt(struct usb_ep *_ep, int value)
|
|||||||
|
|
||||||
/* don't change EPxSTATUS_EP_INVALID to READY */
|
/* don't change EPxSTATUS_EP_INVALID to READY */
|
||||||
} else if (!ep->desc) {
|
} else if (!ep->desc) {
|
||||||
DBG(ep->dev, "%s %s inactive?\n", __FUNCTION__, ep->ep.name);
|
DBG(ep->dev, "%s %s inactive?\n", __func__, ep->ep.name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,7 +940,7 @@ static int goku_fifo_status(struct usb_ep *_ep)
|
|||||||
regs = ep->dev->regs;
|
regs = ep->dev->regs;
|
||||||
size = readl(®s->EPxSizeLA[ep->num]) & DATASIZE;
|
size = readl(®s->EPxSizeLA[ep->num]) & DATASIZE;
|
||||||
size += readl(®s->EPxSizeLB[ep->num]) & DATASIZE;
|
size += readl(®s->EPxSizeLB[ep->num]) & DATASIZE;
|
||||||
VDBG(ep->dev, "%s %s %u\n", __FUNCTION__, ep->ep.name, size);
|
VDBG(ep->dev, "%s %s %u\n", __func__, ep->ep.name, size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,11 +953,11 @@ static void goku_fifo_flush(struct usb_ep *_ep)
|
|||||||
if (!_ep)
|
if (!_ep)
|
||||||
return;
|
return;
|
||||||
ep = container_of(_ep, struct goku_ep, ep);
|
ep = container_of(_ep, struct goku_ep, ep);
|
||||||
VDBG(ep->dev, "%s %s\n", __FUNCTION__, ep->ep.name);
|
VDBG(ep->dev, "%s %s\n", __func__, ep->ep.name);
|
||||||
|
|
||||||
/* don't change EPxSTATUS_EP_INVALID to READY */
|
/* don't change EPxSTATUS_EP_INVALID to READY */
|
||||||
if (!ep->desc && ep->num != 0) {
|
if (!ep->desc && ep->num != 0) {
|
||||||
DBG(ep->dev, "%s %s inactive?\n", __FUNCTION__, ep->ep.name);
|
DBG(ep->dev, "%s %s inactive?\n", __func__, ep->ep.name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1286,7 +1286,7 @@ static void ep0_start(struct goku_udc *dev)
|
|||||||
struct goku_udc_regs __iomem *regs = dev->regs;
|
struct goku_udc_regs __iomem *regs = dev->regs;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
VDBG(dev, "%s\n", __FUNCTION__);
|
VDBG(dev, "%s\n", __func__);
|
||||||
|
|
||||||
udc_reset(dev);
|
udc_reset(dev);
|
||||||
udc_reinit (dev);
|
udc_reinit (dev);
|
||||||
@ -1322,7 +1322,7 @@ static void udc_enable(struct goku_udc *dev)
|
|||||||
if (readl(&dev->regs->power_detect) & PW_DETECT)
|
if (readl(&dev->regs->power_detect) & PW_DETECT)
|
||||||
ep0_start(dev);
|
ep0_start(dev);
|
||||||
else {
|
else {
|
||||||
DBG(dev, "%s\n", __FUNCTION__);
|
DBG(dev, "%s\n", __func__);
|
||||||
dev->int_enable = INT_PWRDETECT;
|
dev->int_enable = INT_PWRDETECT;
|
||||||
writel(dev->int_enable, &dev->regs->int_enable);
|
writel(dev->int_enable, &dev->regs->int_enable);
|
||||||
}
|
}
|
||||||
@ -1387,7 +1387,7 @@ stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
DBG (dev, "%s\n", __FUNCTION__);
|
DBG (dev, "%s\n", __func__);
|
||||||
|
|
||||||
if (dev->gadget.speed == USB_SPEED_UNKNOWN)
|
if (dev->gadget.speed == USB_SPEED_UNKNOWN)
|
||||||
driver = NULL;
|
driver = NULL;
|
||||||
@ -1726,7 +1726,7 @@ static void goku_remove(struct pci_dev *pdev)
|
|||||||
{
|
{
|
||||||
struct goku_udc *dev = pci_get_drvdata(pdev);
|
struct goku_udc *dev = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
DBG(dev, "%s\n", __FUNCTION__);
|
DBG(dev, "%s\n", __func__);
|
||||||
|
|
||||||
BUG_ON(dev->driver);
|
BUG_ON(dev->driver);
|
||||||
|
|
||||||
|
@ -1107,13 +1107,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
|||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
default:
|
default:
|
||||||
DBG (dev, "fail %s, state %d\n", __FUNCTION__, state);
|
DBG (dev, "fail %s, state %d\n", __func__, state);
|
||||||
retval = -ESRCH;
|
retval = -ESRCH;
|
||||||
break;
|
break;
|
||||||
case STATE_DEV_UNCONNECTED:
|
case STATE_DEV_UNCONNECTED:
|
||||||
case STATE_DEV_CONNECTED:
|
case STATE_DEV_CONNECTED:
|
||||||
spin_unlock_irq (&dev->lock);
|
spin_unlock_irq (&dev->lock);
|
||||||
DBG (dev, "%s wait\n", __FUNCTION__);
|
DBG (dev, "%s wait\n", __func__);
|
||||||
|
|
||||||
/* wait for events */
|
/* wait for events */
|
||||||
retval = wait_event_interruptible (dev->wait,
|
retval = wait_event_interruptible (dev->wait,
|
||||||
@ -1222,7 +1222,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|||||||
DBG(dev, "bogus ep0out stall!\n");
|
DBG(dev, "bogus ep0out stall!\n");
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
DBG (dev, "fail %s, state %d\n", __FUNCTION__, dev->state);
|
DBG (dev, "fail %s, state %d\n", __func__, dev->state);
|
||||||
|
|
||||||
spin_unlock_irq (&dev->lock);
|
spin_unlock_irq (&dev->lock);
|
||||||
return retval;
|
return retval;
|
||||||
@ -1233,7 +1233,7 @@ ep0_fasync (int f, struct file *fd, int on)
|
|||||||
{
|
{
|
||||||
struct dev_data *dev = fd->private_data;
|
struct dev_data *dev = fd->private_data;
|
||||||
// caller must F_SETOWN before signal delivery happens
|
// caller must F_SETOWN before signal delivery happens
|
||||||
VDEBUG (dev, "%s %s\n", __FUNCTION__, on ? "on" : "off");
|
VDEBUG (dev, "%s %s\n", __func__, on ? "on" : "off");
|
||||||
return fasync_helper (f, fd, on, &dev->fasync);
|
return fasync_helper (f, fd, on, &dev->fasync);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1575,7 +1575,7 @@ static void destroy_ep_files (struct dev_data *dev)
|
|||||||
{
|
{
|
||||||
struct list_head *entry, *tmp;
|
struct list_head *entry, *tmp;
|
||||||
|
|
||||||
DBG (dev, "%s %d\n", __FUNCTION__, dev->state);
|
DBG (dev, "%s %d\n", __func__, dev->state);
|
||||||
|
|
||||||
/* dev->state must prevent interference */
|
/* dev->state must prevent interference */
|
||||||
restart:
|
restart:
|
||||||
@ -1662,7 +1662,7 @@ static int activate_ep_files (struct dev_data *dev)
|
|||||||
put_dev (dev);
|
put_dev (dev);
|
||||||
kfree (data);
|
kfree (data);
|
||||||
enomem0:
|
enomem0:
|
||||||
DBG (dev, "%s enomem\n", __FUNCTION__);
|
DBG (dev, "%s enomem\n", __func__);
|
||||||
destroy_ep_files (dev);
|
destroy_ep_files (dev);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -1672,7 +1672,7 @@ gadgetfs_unbind (struct usb_gadget *gadget)
|
|||||||
{
|
{
|
||||||
struct dev_data *dev = get_gadget_data (gadget);
|
struct dev_data *dev = get_gadget_data (gadget);
|
||||||
|
|
||||||
DBG (dev, "%s\n", __FUNCTION__);
|
DBG (dev, "%s\n", __func__);
|
||||||
|
|
||||||
spin_lock_irq (&dev->lock);
|
spin_lock_irq (&dev->lock);
|
||||||
dev->state = STATE_DEV_UNBOUND;
|
dev->state = STATE_DEV_UNBOUND;
|
||||||
@ -1685,7 +1685,7 @@ gadgetfs_unbind (struct usb_gadget *gadget)
|
|||||||
/* we've already been disconnected ... no i/o is active */
|
/* we've already been disconnected ... no i/o is active */
|
||||||
if (dev->req)
|
if (dev->req)
|
||||||
usb_ep_free_request (gadget->ep0, dev->req);
|
usb_ep_free_request (gadget->ep0, dev->req);
|
||||||
DBG (dev, "%s done\n", __FUNCTION__);
|
DBG (dev, "%s done\n", __func__);
|
||||||
put_dev (dev);
|
put_dev (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1933,7 +1933,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
spin_unlock_irq (&dev->lock);
|
spin_unlock_irq (&dev->lock);
|
||||||
pr_debug ("%s: %s fail %Zd, %p\n", shortname, __FUNCTION__, value, dev);
|
pr_debug ("%s: %s fail %Zd, %p\n", shortname, __func__, value, dev);
|
||||||
kfree (dev->buf);
|
kfree (dev->buf);
|
||||||
dev->buf = NULL;
|
dev->buf = NULL;
|
||||||
return value;
|
return value;
|
||||||
|
@ -253,7 +253,7 @@ udc_proc_read(char *page, char **start, off_t off, int count,
|
|||||||
*/
|
*/
|
||||||
static void udc_disable(struct lh7a40x_udc *dev)
|
static void udc_disable(struct lh7a40x_udc *dev)
|
||||||
{
|
{
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, dev);
|
DEBUG("%s, %p\n", __func__, dev);
|
||||||
|
|
||||||
udc_set_address(dev, 0);
|
udc_set_address(dev, 0);
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ static void udc_reinit(struct lh7a40x_udc *dev)
|
|||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, dev);
|
DEBUG("%s, %p\n", __func__, dev);
|
||||||
|
|
||||||
/* device/ep0 records init */
|
/* device/ep0 records init */
|
||||||
INIT_LIST_HEAD(&dev->gadget.ep_list);
|
INIT_LIST_HEAD(&dev->gadget.ep_list);
|
||||||
@ -318,7 +318,7 @@ static void udc_enable(struct lh7a40x_udc *dev)
|
|||||||
{
|
{
|
||||||
int ep;
|
int ep;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, dev);
|
DEBUG("%s, %p\n", __func__, dev);
|
||||||
|
|
||||||
dev->gadget.speed = USB_SPEED_UNKNOWN;
|
dev->gadget.speed = USB_SPEED_UNKNOWN;
|
||||||
|
|
||||||
@ -412,7 +412,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
|
|||||||
struct lh7a40x_udc *dev = the_controller;
|
struct lh7a40x_udc *dev = the_controller;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name);
|
DEBUG("%s: %s\n", __func__, driver->driver.name);
|
||||||
|
|
||||||
if (!driver
|
if (!driver
|
||||||
|| driver->speed != USB_SPEED_FULL
|
|| driver->speed != USB_SPEED_FULL
|
||||||
@ -521,7 +521,7 @@ static int write_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
|
|||||||
is_short = unlikely(max < ep_maxpacket(ep));
|
is_short = unlikely(max < ep_maxpacket(ep));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __FUNCTION__,
|
DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __func__,
|
||||||
ep->ep.name, count,
|
ep->ep.name, count,
|
||||||
is_last ? "/L" : "", is_short ? "/S" : "",
|
is_last ? "/L" : "", is_short ? "/S" : "",
|
||||||
req->req.length - req->req.actual, req);
|
req->req.length - req->req.actual, req);
|
||||||
@ -555,7 +555,7 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
|
|||||||
/* make sure there's a packet in the FIFO. */
|
/* make sure there's a packet in the FIFO. */
|
||||||
csr = usb_read(ep->csr1);
|
csr = usb_read(ep->csr1);
|
||||||
if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) {
|
if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) {
|
||||||
DEBUG("%s: Packet NOT ready!\n", __FUNCTION__);
|
DEBUG("%s: Packet NOT ready!\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,7 +614,7 @@ static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req, int status)
|
|||||||
unsigned int stopped = ep->stopped;
|
unsigned int stopped = ep->stopped;
|
||||||
u32 index;
|
u32 index;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, ep);
|
DEBUG("%s, %p\n", __func__, ep);
|
||||||
list_del_init(&req->queue);
|
list_del_init(&req->queue);
|
||||||
|
|
||||||
if (likely(req->req.status == -EINPROGRESS))
|
if (likely(req->req.status == -EINPROGRESS))
|
||||||
@ -644,7 +644,7 @@ static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req, int status)
|
|||||||
/** Enable EP interrupt */
|
/** Enable EP interrupt */
|
||||||
static void pio_irq_enable(int ep)
|
static void pio_irq_enable(int ep)
|
||||||
{
|
{
|
||||||
DEBUG("%s: %d\n", __FUNCTION__, ep);
|
DEBUG("%s: %d\n", __func__, ep);
|
||||||
|
|
||||||
switch (ep) {
|
switch (ep) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -665,7 +665,7 @@ static void pio_irq_enable(int ep)
|
|||||||
/** Disable EP interrupt */
|
/** Disable EP interrupt */
|
||||||
static void pio_irq_disable(int ep)
|
static void pio_irq_disable(int ep)
|
||||||
{
|
{
|
||||||
DEBUG("%s: %d\n", __FUNCTION__, ep);
|
DEBUG("%s: %d\n", __func__, ep);
|
||||||
|
|
||||||
switch (ep) {
|
switch (ep) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -690,7 +690,7 @@ void nuke(struct lh7a40x_ep *ep, int status)
|
|||||||
{
|
{
|
||||||
struct lh7a40x_request *req;
|
struct lh7a40x_request *req;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, ep);
|
DEBUG("%s, %p\n", __func__, ep);
|
||||||
|
|
||||||
/* Flush FIFO */
|
/* Flush FIFO */
|
||||||
flush(ep);
|
flush(ep);
|
||||||
@ -734,7 +734,7 @@ static void flush_all(struct lh7a40x_udc *dev)
|
|||||||
*/
|
*/
|
||||||
static void flush(struct lh7a40x_ep *ep)
|
static void flush(struct lh7a40x_ep *ep)
|
||||||
{
|
{
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, ep);
|
DEBUG("%s, %p\n", __func__, ep);
|
||||||
|
|
||||||
switch (ep->ep_type) {
|
switch (ep->ep_type) {
|
||||||
case ep_control:
|
case ep_control:
|
||||||
@ -766,7 +766,7 @@ static void lh7a40x_in_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
|
|||||||
usb_set_index(ep_idx);
|
usb_set_index(ep_idx);
|
||||||
|
|
||||||
csr = usb_read(ep->csr1);
|
csr = usb_read(ep->csr1);
|
||||||
DEBUG("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr);
|
DEBUG("%s: %d, csr %x\n", __func__, ep_idx, csr);
|
||||||
|
|
||||||
if (csr & USB_IN_CSR1_SENT_STALL) {
|
if (csr & USB_IN_CSR1_SENT_STALL) {
|
||||||
DEBUG("USB_IN_CSR1_SENT_STALL\n");
|
DEBUG("USB_IN_CSR1_SENT_STALL\n");
|
||||||
@ -776,7 +776,7 @@ static void lh7a40x_in_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ep->desc) {
|
if (!ep->desc) {
|
||||||
DEBUG("%s: NO EP DESC\n", __FUNCTION__);
|
DEBUG("%s: NO EP DESC\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -802,7 +802,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
|
|||||||
struct lh7a40x_ep *ep = &dev->ep[ep_idx];
|
struct lh7a40x_ep *ep = &dev->ep[ep_idx];
|
||||||
struct lh7a40x_request *req;
|
struct lh7a40x_request *req;
|
||||||
|
|
||||||
DEBUG("%s: %d\n", __FUNCTION__, ep_idx);
|
DEBUG("%s: %d\n", __func__, ep_idx);
|
||||||
|
|
||||||
usb_set_index(ep_idx);
|
usb_set_index(ep_idx);
|
||||||
|
|
||||||
@ -814,11 +814,11 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
|
|||||||
usb_read(ep->
|
usb_read(ep->
|
||||||
csr1)) & (USB_OUT_CSR1_OUT_PKT_RDY |
|
csr1)) & (USB_OUT_CSR1_OUT_PKT_RDY |
|
||||||
USB_OUT_CSR1_SENT_STALL)) {
|
USB_OUT_CSR1_SENT_STALL)) {
|
||||||
DEBUG("%s: %x\n", __FUNCTION__, csr);
|
DEBUG("%s: %x\n", __func__, csr);
|
||||||
|
|
||||||
if (csr & USB_OUT_CSR1_SENT_STALL) {
|
if (csr & USB_OUT_CSR1_SENT_STALL) {
|
||||||
DEBUG("%s: stall sent, flush fifo\n",
|
DEBUG("%s: stall sent, flush fifo\n",
|
||||||
__FUNCTION__);
|
__func__);
|
||||||
/* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */
|
/* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */
|
||||||
flush(ep);
|
flush(ep);
|
||||||
} else if (csr & USB_OUT_CSR1_OUT_PKT_RDY) {
|
} else if (csr & USB_OUT_CSR1_OUT_PKT_RDY) {
|
||||||
@ -832,7 +832,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
|
|||||||
|
|
||||||
if (!req) {
|
if (!req) {
|
||||||
printk("%s: NULL REQ %d\n",
|
printk("%s: NULL REQ %d\n",
|
||||||
__FUNCTION__, ep_idx);
|
__func__, ep_idx);
|
||||||
flush(ep);
|
flush(ep);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -844,7 +844,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Throw packet away.. */
|
/* Throw packet away.. */
|
||||||
printk("%s: No descriptor?!?\n", __FUNCTION__);
|
printk("%s: No descriptor?!?\n", __func__);
|
||||||
flush(ep);
|
flush(ep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -886,7 +886,7 @@ static void lh7a40x_reset_intr(struct lh7a40x_udc *dev)
|
|||||||
#if 0 /* def CONFIG_ARCH_LH7A404 */
|
#if 0 /* def CONFIG_ARCH_LH7A404 */
|
||||||
/* Does not work always... */
|
/* Does not work always... */
|
||||||
|
|
||||||
DEBUG("%s: %d\n", __FUNCTION__, dev->usb_address);
|
DEBUG("%s: %d\n", __func__, dev->usb_address);
|
||||||
|
|
||||||
if (!dev->usb_address) {
|
if (!dev->usb_address) {
|
||||||
/*usb_set(USB_RESET_IO, USB_RESET);
|
/*usb_set(USB_RESET_IO, USB_RESET);
|
||||||
@ -936,7 +936,7 @@ static irqreturn_t lh7a40x_udc_irq(int irq, void *_dev)
|
|||||||
if (!intr_out && !intr_in && !intr_int)
|
if (!intr_out && !intr_in && !intr_int)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
DEBUG("%s (on state %s)\n", __FUNCTION__,
|
DEBUG("%s (on state %s)\n", __func__,
|
||||||
state_names[dev->ep0state]);
|
state_names[dev->ep0state]);
|
||||||
DEBUG("intr_out = %x\n", intr_out);
|
DEBUG("intr_out = %x\n", intr_out);
|
||||||
DEBUG("intr_in = %x\n", intr_in);
|
DEBUG("intr_in = %x\n", intr_in);
|
||||||
@ -1016,14 +1016,14 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep,
|
|||||||
struct lh7a40x_udc *dev;
|
struct lh7a40x_udc *dev;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, _ep);
|
DEBUG("%s, %p\n", __func__, _ep);
|
||||||
|
|
||||||
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
||||||
if (!_ep || !desc || ep->desc || _ep->name == ep0name
|
if (!_ep || !desc || ep->desc || _ep->name == ep0name
|
||||||
|| desc->bDescriptorType != USB_DT_ENDPOINT
|
|| desc->bDescriptorType != USB_DT_ENDPOINT
|
||||||
|| ep->bEndpointAddress != desc->bEndpointAddress
|
|| ep->bEndpointAddress != desc->bEndpointAddress
|
||||||
|| ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) {
|
|| ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) {
|
||||||
DEBUG("%s, bad ep or descriptor\n", __FUNCTION__);
|
DEBUG("%s, bad ep or descriptor\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1031,7 +1031,7 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep,
|
|||||||
if (ep->bmAttributes != desc->bmAttributes
|
if (ep->bmAttributes != desc->bmAttributes
|
||||||
&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
|
&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
|
||||||
&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
|
&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
|
||||||
DEBUG("%s, %s type mismatch\n", __FUNCTION__, _ep->name);
|
DEBUG("%s, %s type mismatch\n", __func__, _ep->name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1039,13 +1039,13 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep,
|
|||||||
if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
|
if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
|
||||||
&& le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep))
|
&& le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep))
|
||||||
|| !desc->wMaxPacketSize) {
|
|| !desc->wMaxPacketSize) {
|
||||||
DEBUG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);
|
DEBUG("%s, bad %s maxpacket\n", __func__, _ep->name);
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = ep->dev;
|
dev = ep->dev;
|
||||||
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
|
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
|
||||||
DEBUG("%s, bogus device state\n", __FUNCTION__);
|
DEBUG("%s, bogus device state\n", __func__);
|
||||||
return -ESHUTDOWN;
|
return -ESHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1061,7 +1061,7 @@ static int lh7a40x_ep_enable(struct usb_ep *_ep,
|
|||||||
/* Reset halt state (does flush) */
|
/* Reset halt state (does flush) */
|
||||||
lh7a40x_set_halt(_ep, 0);
|
lh7a40x_set_halt(_ep, 0);
|
||||||
|
|
||||||
DEBUG("%s: enabled %s\n", __FUNCTION__, _ep->name);
|
DEBUG("%s: enabled %s\n", __func__, _ep->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1073,11 +1073,11 @@ static int lh7a40x_ep_disable(struct usb_ep *_ep)
|
|||||||
struct lh7a40x_ep *ep;
|
struct lh7a40x_ep *ep;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, _ep);
|
DEBUG("%s, %p\n", __func__, _ep);
|
||||||
|
|
||||||
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
||||||
if (!_ep || !ep->desc) {
|
if (!_ep || !ep->desc) {
|
||||||
DEBUG("%s, %s not enabled\n", __FUNCTION__,
|
DEBUG("%s, %s not enabled\n", __func__,
|
||||||
_ep ? ep->ep.name : NULL);
|
_ep ? ep->ep.name : NULL);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -1097,7 +1097,7 @@ static int lh7a40x_ep_disable(struct usb_ep *_ep)
|
|||||||
|
|
||||||
spin_unlock_irqrestore(&ep->dev->lock, flags);
|
spin_unlock_irqrestore(&ep->dev->lock, flags);
|
||||||
|
|
||||||
DEBUG("%s: disabled %s\n", __FUNCTION__, _ep->name);
|
DEBUG("%s: disabled %s\n", __func__, _ep->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1106,7 +1106,7 @@ static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep,
|
|||||||
{
|
{
|
||||||
struct lh7a40x_request *req;
|
struct lh7a40x_request *req;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, ep);
|
DEBUG("%s, %p\n", __func__, ep);
|
||||||
|
|
||||||
req = kzalloc(sizeof(*req), gfp_flags);
|
req = kzalloc(sizeof(*req), gfp_flags);
|
||||||
if (!req)
|
if (!req)
|
||||||
@ -1121,7 +1121,7 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req)
|
|||||||
{
|
{
|
||||||
struct lh7a40x_request *req;
|
struct lh7a40x_request *req;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, ep);
|
DEBUG("%s, %p\n", __func__, ep);
|
||||||
|
|
||||||
req = container_of(_req, struct lh7a40x_request, req);
|
req = container_of(_req, struct lh7a40x_request, req);
|
||||||
WARN_ON(!list_empty(&req->queue));
|
WARN_ON(!list_empty(&req->queue));
|
||||||
@ -1140,25 +1140,25 @@ static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req,
|
|||||||
struct lh7a40x_udc *dev;
|
struct lh7a40x_udc *dev;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DEBUG("\n\n\n%s, %p\n", __FUNCTION__, _ep);
|
DEBUG("\n\n\n%s, %p\n", __func__, _ep);
|
||||||
|
|
||||||
req = container_of(_req, struct lh7a40x_request, req);
|
req = container_of(_req, struct lh7a40x_request, req);
|
||||||
if (unlikely
|
if (unlikely
|
||||||
(!_req || !_req->complete || !_req->buf
|
(!_req || !_req->complete || !_req->buf
|
||||||
|| !list_empty(&req->queue))) {
|
|| !list_empty(&req->queue))) {
|
||||||
DEBUG("%s, bad params\n", __FUNCTION__);
|
DEBUG("%s, bad params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
||||||
if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
||||||
DEBUG("%s, bad ep\n", __FUNCTION__);
|
DEBUG("%s, bad ep\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = ep->dev;
|
dev = ep->dev;
|
||||||
if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
|
if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
|
||||||
DEBUG("%s, bogus device state %p\n", __FUNCTION__, dev->driver);
|
DEBUG("%s, bogus device state %p\n", __func__, dev->driver);
|
||||||
return -ESHUTDOWN;
|
return -ESHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1218,7 +1218,7 @@ static int lh7a40x_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
|||||||
struct lh7a40x_request *req;
|
struct lh7a40x_request *req;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, _ep);
|
DEBUG("%s, %p\n", __func__, _ep);
|
||||||
|
|
||||||
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
||||||
if (!_ep || ep->ep.name == ep0name)
|
if (!_ep || ep->ep.name == ep0name)
|
||||||
@ -1253,13 +1253,13 @@ static int lh7a40x_set_halt(struct usb_ep *_ep, int value)
|
|||||||
|
|
||||||
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
||||||
if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
||||||
DEBUG("%s, bad ep\n", __FUNCTION__);
|
DEBUG("%s, bad ep\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_set_index(ep_index(ep));
|
usb_set_index(ep_index(ep));
|
||||||
|
|
||||||
DEBUG("%s, ep %d, val %d\n", __FUNCTION__, ep_index(ep), value);
|
DEBUG("%s, ep %d, val %d\n", __func__, ep_index(ep), value);
|
||||||
|
|
||||||
spin_lock_irqsave(&ep->dev->lock, flags);
|
spin_lock_irqsave(&ep->dev->lock, flags);
|
||||||
|
|
||||||
@ -1325,11 +1325,11 @@ static int lh7a40x_fifo_status(struct usb_ep *_ep)
|
|||||||
|
|
||||||
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
||||||
if (!_ep) {
|
if (!_ep) {
|
||||||
DEBUG("%s, bad ep\n", __FUNCTION__);
|
DEBUG("%s, bad ep\n", __func__);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("%s, %d\n", __FUNCTION__, ep_index(ep));
|
DEBUG("%s, %d\n", __func__, ep_index(ep));
|
||||||
|
|
||||||
/* LPD can't report unclaimed bytes from IN fifos */
|
/* LPD can't report unclaimed bytes from IN fifos */
|
||||||
if (ep_is_in(ep))
|
if (ep_is_in(ep))
|
||||||
@ -1355,7 +1355,7 @@ static void lh7a40x_fifo_flush(struct usb_ep *_ep)
|
|||||||
|
|
||||||
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
ep = container_of(_ep, struct lh7a40x_ep, ep);
|
||||||
if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
||||||
DEBUG("%s, bad ep\n", __FUNCTION__);
|
DEBUG("%s, bad ep\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1376,7 +1376,7 @@ static int write_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
|
|||||||
|
|
||||||
max = ep_maxpacket(ep);
|
max = ep_maxpacket(ep);
|
||||||
|
|
||||||
DEBUG_EP0("%s\n", __FUNCTION__);
|
DEBUG_EP0("%s\n", __func__);
|
||||||
|
|
||||||
count = write_packet(ep, req, max);
|
count = write_packet(ep, req, max);
|
||||||
|
|
||||||
@ -1390,7 +1390,7 @@ static int write_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
|
|||||||
is_last = 1;
|
is_last = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __FUNCTION__,
|
DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __func__,
|
||||||
ep->ep.name, count,
|
ep->ep.name, count,
|
||||||
is_last ? "/L" : "", req->req.length - req->req.actual, req);
|
is_last ? "/L" : "", req->req.length - req->req.actual, req);
|
||||||
|
|
||||||
@ -1434,7 +1434,7 @@ static int read_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
|
|||||||
unsigned bufferspace, count, is_short;
|
unsigned bufferspace, count, is_short;
|
||||||
volatile u32 *fifo = (volatile u32 *)ep->fifo;
|
volatile u32 *fifo = (volatile u32 *)ep->fifo;
|
||||||
|
|
||||||
DEBUG_EP0("%s\n", __FUNCTION__);
|
DEBUG_EP0("%s\n", __func__);
|
||||||
|
|
||||||
csr = usb_read(USB_EP0_CSR);
|
csr = usb_read(USB_EP0_CSR);
|
||||||
if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY))
|
if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY))
|
||||||
@ -1492,7 +1492,7 @@ static int read_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
|
|||||||
*/
|
*/
|
||||||
static void udc_set_address(struct lh7a40x_udc *dev, unsigned char address)
|
static void udc_set_address(struct lh7a40x_udc *dev, unsigned char address)
|
||||||
{
|
{
|
||||||
DEBUG_EP0("%s: %d\n", __FUNCTION__, address);
|
DEBUG_EP0("%s: %d\n", __func__, address);
|
||||||
/* c.f. 15.1.2.2 Table 15-4 address will be used after DATA_END is set */
|
/* c.f. 15.1.2.2 Table 15-4 address will be used after DATA_END is set */
|
||||||
dev->usb_address = address;
|
dev->usb_address = address;
|
||||||
usb_set((address & USB_FA_FUNCTION_ADDR), USB_FA);
|
usb_set((address & USB_FA_FUNCTION_ADDR), USB_FA);
|
||||||
@ -1514,7 +1514,7 @@ static void lh7a40x_ep0_out(struct lh7a40x_udc *dev, u32 csr)
|
|||||||
struct lh7a40x_ep *ep = &dev->ep[0];
|
struct lh7a40x_ep *ep = &dev->ep[0];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DEBUG_EP0("%s: %x\n", __FUNCTION__, csr);
|
DEBUG_EP0("%s: %x\n", __func__, csr);
|
||||||
|
|
||||||
if (list_empty(&ep->queue))
|
if (list_empty(&ep->queue))
|
||||||
req = 0;
|
req = 0;
|
||||||
@ -1533,13 +1533,13 @@ static void lh7a40x_ep0_out(struct lh7a40x_udc *dev, u32 csr)
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
/* Done! */
|
/* Done! */
|
||||||
DEBUG_EP0("%s: finished, waiting for status\n",
|
DEBUG_EP0("%s: finished, waiting for status\n",
|
||||||
__FUNCTION__);
|
__func__);
|
||||||
|
|
||||||
usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR);
|
usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR);
|
||||||
dev->ep0state = WAIT_FOR_SETUP;
|
dev->ep0state = WAIT_FOR_SETUP;
|
||||||
} else {
|
} else {
|
||||||
/* Not done yet.. */
|
/* Not done yet.. */
|
||||||
DEBUG_EP0("%s: not finished\n", __FUNCTION__);
|
DEBUG_EP0("%s: not finished\n", __func__);
|
||||||
usb_set(EP0_CLR_OUT, USB_EP0_CSR);
|
usb_set(EP0_CLR_OUT, USB_EP0_CSR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1556,7 +1556,7 @@ static int lh7a40x_ep0_in(struct lh7a40x_udc *dev, u32 csr)
|
|||||||
struct lh7a40x_ep *ep = &dev->ep[0];
|
struct lh7a40x_ep *ep = &dev->ep[0];
|
||||||
int ret, need_zlp = 0;
|
int ret, need_zlp = 0;
|
||||||
|
|
||||||
DEBUG_EP0("%s: %x\n", __FUNCTION__, csr);
|
DEBUG_EP0("%s: %x\n", __func__, csr);
|
||||||
|
|
||||||
if (list_empty(&ep->queue))
|
if (list_empty(&ep->queue))
|
||||||
req = 0;
|
req = 0;
|
||||||
@ -1564,7 +1564,7 @@ static int lh7a40x_ep0_in(struct lh7a40x_udc *dev, u32 csr)
|
|||||||
req = list_entry(ep->queue.next, struct lh7a40x_request, queue);
|
req = list_entry(ep->queue.next, struct lh7a40x_request, queue);
|
||||||
|
|
||||||
if (!req) {
|
if (!req) {
|
||||||
DEBUG_EP0("%s: NULL REQ\n", __FUNCTION__);
|
DEBUG_EP0("%s: NULL REQ\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1585,17 +1585,17 @@ static int lh7a40x_ep0_in(struct lh7a40x_udc *dev, u32 csr)
|
|||||||
|
|
||||||
if (ret == 1 && !need_zlp) {
|
if (ret == 1 && !need_zlp) {
|
||||||
/* Last packet */
|
/* Last packet */
|
||||||
DEBUG_EP0("%s: finished, waiting for status\n", __FUNCTION__);
|
DEBUG_EP0("%s: finished, waiting for status\n", __func__);
|
||||||
|
|
||||||
usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR);
|
usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR);
|
||||||
dev->ep0state = WAIT_FOR_SETUP;
|
dev->ep0state = WAIT_FOR_SETUP;
|
||||||
} else {
|
} else {
|
||||||
DEBUG_EP0("%s: not finished\n", __FUNCTION__);
|
DEBUG_EP0("%s: not finished\n", __func__);
|
||||||
usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR);
|
usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_zlp) {
|
if (need_zlp) {
|
||||||
DEBUG_EP0("%s: Need ZLP!\n", __FUNCTION__);
|
DEBUG_EP0("%s: Need ZLP!\n", __func__);
|
||||||
usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR);
|
usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR);
|
||||||
dev->ep0state = DATA_STATE_NEED_ZLP;
|
dev->ep0state = DATA_STATE_NEED_ZLP;
|
||||||
}
|
}
|
||||||
@ -1694,7 +1694,7 @@ static void lh7a40x_ep0_setup(struct lh7a40x_udc *dev, u32 csr)
|
|||||||
struct usb_ctrlrequest ctrl;
|
struct usb_ctrlrequest ctrl;
|
||||||
int i, bytes, is_in;
|
int i, bytes, is_in;
|
||||||
|
|
||||||
DEBUG_SETUP("%s: %x\n", __FUNCTION__, csr);
|
DEBUG_SETUP("%s: %x\n", __func__, csr);
|
||||||
|
|
||||||
/* Nuke all previous transfers */
|
/* Nuke all previous transfers */
|
||||||
nuke(ep, -EPROTO);
|
nuke(ep, -EPROTO);
|
||||||
@ -1799,7 +1799,7 @@ static void lh7a40x_ep0_setup(struct lh7a40x_udc *dev, u32 csr)
|
|||||||
*/
|
*/
|
||||||
static void lh7a40x_ep0_in_zlp(struct lh7a40x_udc *dev, u32 csr)
|
static void lh7a40x_ep0_in_zlp(struct lh7a40x_udc *dev, u32 csr)
|
||||||
{
|
{
|
||||||
DEBUG_EP0("%s: %x\n", __FUNCTION__, csr);
|
DEBUG_EP0("%s: %x\n", __func__, csr);
|
||||||
|
|
||||||
/* c.f. Table 15-14 */
|
/* c.f. Table 15-14 */
|
||||||
usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR);
|
usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR);
|
||||||
@ -1818,7 +1818,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr)
|
|||||||
usb_set_index(0);
|
usb_set_index(0);
|
||||||
csr = usb_read(USB_EP0_CSR);
|
csr = usb_read(USB_EP0_CSR);
|
||||||
|
|
||||||
DEBUG_EP0("%s: csr = %x\n", __FUNCTION__, csr);
|
DEBUG_EP0("%s: csr = %x\n", __func__, csr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For overview of what we should be doing see c.f. Chapter 18.1.2.4
|
* For overview of what we should be doing see c.f. Chapter 18.1.2.4
|
||||||
@ -1832,7 +1832,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr)
|
|||||||
* - clear the SENT_STALL bit
|
* - clear the SENT_STALL bit
|
||||||
*/
|
*/
|
||||||
if (csr & EP0_SENT_STALL) {
|
if (csr & EP0_SENT_STALL) {
|
||||||
DEBUG_EP0("%s: EP0_SENT_STALL is set: %x\n", __FUNCTION__, csr);
|
DEBUG_EP0("%s: EP0_SENT_STALL is set: %x\n", __func__, csr);
|
||||||
usb_clear((EP0_SENT_STALL | EP0_SEND_STALL), USB_EP0_CSR);
|
usb_clear((EP0_SENT_STALL | EP0_SEND_STALL), USB_EP0_CSR);
|
||||||
nuke(ep, -ECONNABORTED);
|
nuke(ep, -ECONNABORTED);
|
||||||
dev->ep0state = WAIT_FOR_SETUP;
|
dev->ep0state = WAIT_FOR_SETUP;
|
||||||
@ -1849,7 +1849,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr)
|
|||||||
*/
|
*/
|
||||||
if (!(csr & (EP0_IN_PKT_RDY | EP0_OUT_PKT_RDY))) {
|
if (!(csr & (EP0_IN_PKT_RDY | EP0_OUT_PKT_RDY))) {
|
||||||
DEBUG_EP0("%s: IN_PKT_RDY and OUT_PKT_RDY are clear\n",
|
DEBUG_EP0("%s: IN_PKT_RDY and OUT_PKT_RDY are clear\n",
|
||||||
__FUNCTION__);
|
__func__);
|
||||||
|
|
||||||
switch (dev->ep0state) {
|
switch (dev->ep0state) {
|
||||||
case DATA_STATE_XMIT:
|
case DATA_STATE_XMIT:
|
||||||
@ -1877,7 +1877,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr)
|
|||||||
* - set SERVICED_SETUP_END_BIT
|
* - set SERVICED_SETUP_END_BIT
|
||||||
*/
|
*/
|
||||||
if (csr & EP0_SETUP_END) {
|
if (csr & EP0_SETUP_END) {
|
||||||
DEBUG_EP0("%s: EP0_SETUP_END is set: %x\n", __FUNCTION__, csr);
|
DEBUG_EP0("%s: EP0_SETUP_END is set: %x\n", __func__, csr);
|
||||||
|
|
||||||
usb_set(EP0_CLR_SETUP_END, USB_EP0_CSR);
|
usb_set(EP0_CLR_SETUP_END, USB_EP0_CSR);
|
||||||
|
|
||||||
@ -1896,7 +1896,7 @@ static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr)
|
|||||||
*/
|
*/
|
||||||
if (csr & EP0_OUT_PKT_RDY) {
|
if (csr & EP0_OUT_PKT_RDY) {
|
||||||
|
|
||||||
DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __FUNCTION__,
|
DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __func__,
|
||||||
csr);
|
csr);
|
||||||
|
|
||||||
switch (dev->ep0state) {
|
switch (dev->ep0state) {
|
||||||
@ -1926,7 +1926,7 @@ static void lh7a40x_ep0_kick(struct lh7a40x_udc *dev, struct lh7a40x_ep *ep)
|
|||||||
usb_set_index(0);
|
usb_set_index(0);
|
||||||
csr = usb_read(USB_EP0_CSR);
|
csr = usb_read(USB_EP0_CSR);
|
||||||
|
|
||||||
DEBUG_EP0("%s: %x\n", __FUNCTION__, csr);
|
DEBUG_EP0("%s: %x\n", __func__, csr);
|
||||||
|
|
||||||
/* Clear "out packet ready" */
|
/* Clear "out packet ready" */
|
||||||
usb_set(EP0_CLR_OUT, USB_EP0_CSR);
|
usb_set(EP0_CLR_OUT, USB_EP0_CSR);
|
||||||
@ -1949,7 +1949,7 @@ static int lh7a40x_udc_get_frame(struct usb_gadget *_gadget)
|
|||||||
{
|
{
|
||||||
u32 frame1 = usb_read(USB_FRM_NUM1); /* Least significant 8 bits */
|
u32 frame1 = usb_read(USB_FRM_NUM1); /* Least significant 8 bits */
|
||||||
u32 frame2 = usb_read(USB_FRM_NUM2); /* Most significant 3 bits */
|
u32 frame2 = usb_read(USB_FRM_NUM2); /* Most significant 3 bits */
|
||||||
DEBUG("%s, %p\n", __FUNCTION__, _gadget);
|
DEBUG("%s, %p\n", __func__, _gadget);
|
||||||
return ((frame2 & 0x07) << 8) | (frame1 & 0xff);
|
return ((frame2 & 0x07) << 8) | (frame1 & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1970,7 +1970,7 @@ static const struct usb_gadget_ops lh7a40x_udc_ops = {
|
|||||||
|
|
||||||
static void nop_release(struct device *dev)
|
static void nop_release(struct device *dev)
|
||||||
{
|
{
|
||||||
DEBUG("%s %s\n", __FUNCTION__, dev->bus_id);
|
DEBUG("%s %s\n", __func__, dev->bus_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct lh7a40x_udc memory = {
|
static struct lh7a40x_udc memory = {
|
||||||
@ -2065,7 +2065,7 @@ static int lh7a40x_udc_probe(struct platform_device *pdev)
|
|||||||
struct lh7a40x_udc *dev = &memory;
|
struct lh7a40x_udc *dev = &memory;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
DEBUG("%s: %p\n", __FUNCTION__, pdev);
|
DEBUG("%s: %p\n", __func__, pdev);
|
||||||
|
|
||||||
spin_lock_init(&dev->lock);
|
spin_lock_init(&dev->lock);
|
||||||
dev->dev = &pdev->dev;
|
dev->dev = &pdev->dev;
|
||||||
@ -2098,7 +2098,7 @@ static int lh7a40x_udc_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct lh7a40x_udc *dev = platform_get_drvdata(pdev);
|
struct lh7a40x_udc *dev = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
DEBUG("%s: %p\n", __FUNCTION__, pdev);
|
DEBUG("%s: %p\n", __func__, pdev);
|
||||||
|
|
||||||
if (dev->driver)
|
if (dev->driver)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
@ -2131,7 +2131,7 @@ static struct platform_driver udc_driver = {
|
|||||||
|
|
||||||
static int __init udc_init(void)
|
static int __init udc_init(void)
|
||||||
{
|
{
|
||||||
DEBUG("%s: %s version %s\n", __FUNCTION__, driver_name, DRIVER_VERSION);
|
DEBUG("%s: %s version %s\n", __func__, driver_name, DRIVER_VERSION);
|
||||||
return platform_driver_register(&udc_driver);
|
return platform_driver_register(&udc_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,10 +486,10 @@ struct m66592 {
|
|||||||
|
|
||||||
struct usb_request *ep0_req; /* for internal request */
|
struct usb_request *ep0_req; /* for internal request */
|
||||||
u16 ep0_data; /* for internal request */
|
u16 ep0_data; /* for internal request */
|
||||||
|
u16 old_vbus;
|
||||||
|
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
|
|
||||||
u16 old_vbus;
|
|
||||||
int scount;
|
int scount;
|
||||||
|
|
||||||
int old_dvsq;
|
int old_dvsq;
|
||||||
|
@ -299,7 +299,7 @@ static inline void assert_out_naking (struct net2280_ep *ep, const char *where)
|
|||||||
&ep->regs->ep_rsp);
|
&ep->regs->ep_rsp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__FUNCTION__)
|
#define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__func__)
|
||||||
#else
|
#else
|
||||||
#define ASSERT_OUT_NAKING(ep) do {} while (0)
|
#define ASSERT_OUT_NAKING(ep) do {} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -163,7 +163,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
|
|||||||
|| ep->bEndpointAddress != desc->bEndpointAddress
|
|| ep->bEndpointAddress != desc->bEndpointAddress
|
||||||
|| ep->maxpacket < le16_to_cpu
|
|| ep->maxpacket < le16_to_cpu
|
||||||
(desc->wMaxPacketSize)) {
|
(desc->wMaxPacketSize)) {
|
||||||
DBG("%s, bad ep or descriptor\n", __FUNCTION__);
|
DBG("%s, bad ep or descriptor\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
maxp = le16_to_cpu (desc->wMaxPacketSize);
|
maxp = le16_to_cpu (desc->wMaxPacketSize);
|
||||||
@ -171,7 +171,7 @@ static int omap_ep_enable(struct usb_ep *_ep,
|
|||||||
&& maxp != ep->maxpacket)
|
&& maxp != ep->maxpacket)
|
||||||
|| le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket
|
|| le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket
|
||||||
|| !desc->wMaxPacketSize) {
|
|| !desc->wMaxPacketSize) {
|
||||||
DBG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);
|
DBG("%s, bad %s maxpacket\n", __func__, _ep->name);
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,13 +194,13 @@ static int omap_ep_enable(struct usb_ep *_ep,
|
|||||||
if (ep->bmAttributes != desc->bmAttributes
|
if (ep->bmAttributes != desc->bmAttributes
|
||||||
&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
|
&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
|
||||||
&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
|
&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
|
||||||
DBG("%s, %s type mismatch\n", __FUNCTION__, _ep->name);
|
DBG("%s, %s type mismatch\n", __func__, _ep->name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
udc = ep->udc;
|
udc = ep->udc;
|
||||||
if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
|
if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
|
||||||
DBG("%s, bogus device state\n", __FUNCTION__);
|
DBG("%s, bogus device state\n", __func__);
|
||||||
return -ESHUTDOWN;
|
return -ESHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ static int omap_ep_disable(struct usb_ep *_ep)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!_ep || !ep->desc) {
|
if (!_ep || !ep->desc) {
|
||||||
DBG("%s, %s not enabled\n", __FUNCTION__,
|
DBG("%s, %s not enabled\n", __func__,
|
||||||
_ep ? ep->ep.name : NULL);
|
_ep ? ep->ep.name : NULL);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -936,11 +936,11 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||||||
/* catch various bogus parameters */
|
/* catch various bogus parameters */
|
||||||
if (!_req || !req->req.complete || !req->req.buf
|
if (!_req || !req->req.complete || !req->req.buf
|
||||||
|| !list_empty(&req->queue)) {
|
|| !list_empty(&req->queue)) {
|
||||||
DBG("%s, bad params\n", __FUNCTION__);
|
DBG("%s, bad params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (!_ep || (!ep->desc && ep->bEndpointAddress)) {
|
if (!_ep || (!ep->desc && ep->bEndpointAddress)) {
|
||||||
DBG("%s, bad ep\n", __FUNCTION__);
|
DBG("%s, bad ep\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||||
@ -959,7 +959,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||||||
&& (ep->bEndpointAddress & USB_DIR_IN) == 0
|
&& (ep->bEndpointAddress & USB_DIR_IN) == 0
|
||||||
&& !cpu_class_is_omap2()
|
&& !cpu_class_is_omap2()
|
||||||
&& (req->req.length % ep->ep.maxpacket) != 0) {
|
&& (req->req.length % ep->ep.maxpacket) != 0) {
|
||||||
DBG("%s, no partial packet OUT reads\n", __FUNCTION__);
|
DBG("%s, no partial packet OUT reads\n", __func__);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1265,8 +1265,6 @@ static int can_pullup(struct omap_udc *udc)
|
|||||||
|
|
||||||
static void pullup_enable(struct omap_udc *udc)
|
static void pullup_enable(struct omap_udc *udc)
|
||||||
{
|
{
|
||||||
udc->gadget.dev.parent->power.power_state = PMSG_ON;
|
|
||||||
udc->gadget.dev.power.power_state = PMSG_ON;
|
|
||||||
UDC_SYSCON1_REG |= UDC_PULLUP_EN;
|
UDC_SYSCON1_REG |= UDC_PULLUP_EN;
|
||||||
if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx())
|
if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx())
|
||||||
OTG_CTRL_REG |= OTG_BSESSVLD;
|
OTG_CTRL_REG |= OTG_BSESSVLD;
|
||||||
@ -3061,8 +3059,6 @@ static int omap_udc_suspend(struct platform_device *dev, pm_message_t message)
|
|||||||
omap_pullup(&udc->gadget, 0);
|
omap_pullup(&udc->gadget, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
udc->gadget.dev.power.power_state = PMSG_SUSPEND;
|
|
||||||
udc->gadget.dev.parent->power.power_state = PMSG_SUSPEND;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,9 +390,12 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req)
|
|||||||
|
|
||||||
/* normal completion */
|
/* normal completion */
|
||||||
case 0:
|
case 0:
|
||||||
list_add_tail(&req->list, &dev->rx_buffers);
|
if (req->actual > 0) {
|
||||||
wake_up_interruptible(&dev->rx_wait);
|
list_add_tail(&req->list, &dev->rx_buffers);
|
||||||
DBG(dev, "G_Printer : rx length %d\n", req->actual);
|
DBG(dev, "G_Printer : rx length %d\n", req->actual);
|
||||||
|
} else {
|
||||||
|
list_add(&req->list, &dev->rx_reqs);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* software-driven interface shutdown */
|
/* software-driven interface shutdown */
|
||||||
@ -417,6 +420,8 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req)
|
|||||||
list_add(&req->list, &dev->rx_reqs);
|
list_add(&req->list, &dev->rx_reqs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wake_up_interruptible(&dev->rx_wait);
|
||||||
spin_unlock_irqrestore(&dev->lock, flags);
|
spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,6 +499,39 @@ printer_close(struct inode *inode, struct file *fd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function must be called with interrupts turned off. */
|
||||||
|
static void
|
||||||
|
setup_rx_reqs(struct printer_dev *dev)
|
||||||
|
{
|
||||||
|
struct usb_request *req;
|
||||||
|
|
||||||
|
while (likely(!list_empty(&dev->rx_reqs))) {
|
||||||
|
int error;
|
||||||
|
|
||||||
|
req = container_of(dev->rx_reqs.next,
|
||||||
|
struct usb_request, list);
|
||||||
|
list_del_init(&req->list);
|
||||||
|
|
||||||
|
/* The USB Host sends us whatever amount of data it wants to
|
||||||
|
* so we always set the length field to the full USB_BUFSIZE.
|
||||||
|
* If the amount of data is more than the read() caller asked
|
||||||
|
* for it will be stored in the request buffer until it is
|
||||||
|
* asked for by read().
|
||||||
|
*/
|
||||||
|
req->length = USB_BUFSIZE;
|
||||||
|
req->complete = rx_complete;
|
||||||
|
|
||||||
|
error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC);
|
||||||
|
if (error) {
|
||||||
|
DBG(dev, "rx submit --> %d\n", error);
|
||||||
|
list_add(&req->list, &dev->rx_reqs);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
list_add(&req->list, &dev->rx_reqs_active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
||||||
{
|
{
|
||||||
@ -522,31 +560,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
|||||||
*/
|
*/
|
||||||
dev->reset_printer = 0;
|
dev->reset_printer = 0;
|
||||||
|
|
||||||
while (likely(!list_empty(&dev->rx_reqs))) {
|
setup_rx_reqs(dev);
|
||||||
int error;
|
|
||||||
|
|
||||||
req = container_of(dev->rx_reqs.next,
|
|
||||||
struct usb_request, list);
|
|
||||||
list_del_init(&req->list);
|
|
||||||
|
|
||||||
/* The USB Host sends us whatever amount of data it wants to
|
|
||||||
* so we always set the length field to the full USB_BUFSIZE.
|
|
||||||
* If the amount of data is more than the read() caller asked
|
|
||||||
* for it will be stored in the request buffer until it is
|
|
||||||
* asked for by read().
|
|
||||||
*/
|
|
||||||
req->length = USB_BUFSIZE;
|
|
||||||
req->complete = rx_complete;
|
|
||||||
|
|
||||||
error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC);
|
|
||||||
if (error) {
|
|
||||||
DBG(dev, "rx submit --> %d\n", error);
|
|
||||||
list_add(&req->list, &dev->rx_reqs);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
list_add(&req->list, &dev->rx_reqs_active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes_copied = 0;
|
bytes_copied = 0;
|
||||||
current_rx_req = dev->current_rx_req;
|
current_rx_req = dev->current_rx_req;
|
||||||
@ -615,9 +629,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
|||||||
|
|
||||||
spin_lock_irqsave(&dev->lock, flags);
|
spin_lock_irqsave(&dev->lock, flags);
|
||||||
|
|
||||||
/* We've disconnected or reset free the req and buffer */
|
/* We've disconnected or reset so return. */
|
||||||
if (dev->reset_printer) {
|
if (dev->reset_printer) {
|
||||||
printer_req_free(dev->out_ep, current_rx_req);
|
list_add(¤t_rx_req->list, &dev->rx_reqs);
|
||||||
spin_unlock_irqrestore(&dev->lock, flags);
|
spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
spin_unlock(&dev->lock_printer_io);
|
spin_unlock(&dev->lock_printer_io);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
@ -735,7 +749,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
|||||||
|
|
||||||
/* We've disconnected or reset so free the req and buffer */
|
/* We've disconnected or reset so free the req and buffer */
|
||||||
if (dev->reset_printer) {
|
if (dev->reset_printer) {
|
||||||
printer_req_free(dev->in_ep, req);
|
list_add(&req->list, &dev->tx_reqs);
|
||||||
spin_unlock_irqrestore(&dev->lock, flags);
|
spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
spin_unlock(&dev->lock_printer_io);
|
spin_unlock(&dev->lock_printer_io);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
@ -791,6 +805,12 @@ printer_poll(struct file *fd, poll_table *wait)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
|
spin_lock(&dev->lock_printer_io);
|
||||||
|
spin_lock_irqsave(&dev->lock, flags);
|
||||||
|
setup_rx_reqs(dev);
|
||||||
|
spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
|
spin_unlock(&dev->lock_printer_io);
|
||||||
|
|
||||||
poll_wait(fd, &dev->rx_wait, wait);
|
poll_wait(fd, &dev->rx_wait, wait);
|
||||||
poll_wait(fd, &dev->tx_wait, wait);
|
poll_wait(fd, &dev->tx_wait, wait);
|
||||||
|
|
||||||
@ -798,7 +818,8 @@ printer_poll(struct file *fd, poll_table *wait)
|
|||||||
if (likely(!list_empty(&dev->tx_reqs)))
|
if (likely(!list_empty(&dev->tx_reqs)))
|
||||||
status |= POLLOUT | POLLWRNORM;
|
status |= POLLOUT | POLLWRNORM;
|
||||||
|
|
||||||
if (likely(!list_empty(&dev->rx_buffers)))
|
if (likely(dev->current_rx_bytes) ||
|
||||||
|
likely(!list_empty(&dev->rx_buffers)))
|
||||||
status |= POLLIN | POLLRDNORM;
|
status |= POLLIN | POLLRDNORM;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dev->lock, flags);
|
spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
@ -894,7 +915,7 @@ static void printer_reset_interface(struct printer_dev *dev)
|
|||||||
if (dev->interface < 0)
|
if (dev->interface < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DBG(dev, "%s\n", __FUNCTION__);
|
DBG(dev, "%s\n", __func__);
|
||||||
|
|
||||||
if (dev->in)
|
if (dev->in)
|
||||||
usb_ep_disable(dev->in_ep);
|
usb_ep_disable(dev->in_ep);
|
||||||
@ -1084,6 +1105,7 @@ static void printer_soft_reset(struct printer_dev *dev)
|
|||||||
if (usb_ep_enable(dev->out_ep, dev->out))
|
if (usb_ep_enable(dev->out_ep, dev->out))
|
||||||
DBG(dev, "Failed to enable USB out_ep\n");
|
DBG(dev, "Failed to enable USB out_ep\n");
|
||||||
|
|
||||||
|
wake_up_interruptible(&dev->rx_wait);
|
||||||
wake_up_interruptible(&dev->tx_wait);
|
wake_up_interruptible(&dev->tx_wait);
|
||||||
wake_up_interruptible(&dev->tx_flush_wait);
|
wake_up_interruptible(&dev->tx_flush_wait);
|
||||||
}
|
}
|
||||||
@ -1262,7 +1284,7 @@ printer_disconnect(struct usb_gadget *gadget)
|
|||||||
struct printer_dev *dev = get_gadget_data(gadget);
|
struct printer_dev *dev = get_gadget_data(gadget);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DBG(dev, "%s\n", __FUNCTION__);
|
DBG(dev, "%s\n", __func__);
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->lock, flags);
|
spin_lock_irqsave(&dev->lock, flags);
|
||||||
|
|
||||||
@ -1278,7 +1300,7 @@ printer_unbind(struct usb_gadget *gadget)
|
|||||||
struct usb_request *req;
|
struct usb_request *req;
|
||||||
|
|
||||||
|
|
||||||
DBG(dev, "%s\n", __FUNCTION__);
|
DBG(dev, "%s\n", __func__);
|
||||||
|
|
||||||
/* Remove sysfs files */
|
/* Remove sysfs files */
|
||||||
device_destroy(usb_gadget_class, g_printer_devno);
|
device_destroy(usb_gadget_class, g_printer_devno);
|
||||||
|
@ -235,7 +235,7 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep,
|
|||||||
|| ep->bEndpointAddress != desc->bEndpointAddress
|
|| ep->bEndpointAddress != desc->bEndpointAddress
|
||||||
|| ep->fifo_size < le16_to_cpu
|
|| ep->fifo_size < le16_to_cpu
|
||||||
(desc->wMaxPacketSize)) {
|
(desc->wMaxPacketSize)) {
|
||||||
DMSG("%s, bad ep or descriptor\n", __FUNCTION__);
|
DMSG("%s, bad ep or descriptor\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep,
|
|||||||
if (ep->bmAttributes != desc->bmAttributes
|
if (ep->bmAttributes != desc->bmAttributes
|
||||||
&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
|
&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
|
||||||
&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
|
&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
|
||||||
DMSG("%s, %s type mismatch\n", __FUNCTION__, _ep->name);
|
DMSG("%s, %s type mismatch\n", __func__, _ep->name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,13 +252,13 @@ static int pxa2xx_ep_enable (struct usb_ep *_ep,
|
|||||||
&& le16_to_cpu (desc->wMaxPacketSize)
|
&& le16_to_cpu (desc->wMaxPacketSize)
|
||||||
!= BULK_FIFO_SIZE)
|
!= BULK_FIFO_SIZE)
|
||||||
|| !desc->wMaxPacketSize) {
|
|| !desc->wMaxPacketSize) {
|
||||||
DMSG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);
|
DMSG("%s, bad %s maxpacket\n", __func__, _ep->name);
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = ep->dev;
|
dev = ep->dev;
|
||||||
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
|
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
|
||||||
DMSG("%s, bogus device state\n", __FUNCTION__);
|
DMSG("%s, bogus device state\n", __func__);
|
||||||
return -ESHUTDOWN;
|
return -ESHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep)
|
|||||||
|
|
||||||
ep = container_of (_ep, struct pxa2xx_ep, ep);
|
ep = container_of (_ep, struct pxa2xx_ep, ep);
|
||||||
if (!_ep || !ep->desc) {
|
if (!_ep || !ep->desc) {
|
||||||
DMSG("%s, %s not enabled\n", __FUNCTION__,
|
DMSG("%s, %s not enabled\n", __func__,
|
||||||
_ep ? ep->ep.name : NULL);
|
_ep ? ep->ep.name : NULL);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -461,7 +461,7 @@ void ep0start(struct pxa2xx_udc *dev, u32 flags, const char *tag)
|
|||||||
USIR0 = USIR0_IR0;
|
USIR0 = USIR0_IR0;
|
||||||
dev->req_pending = 0;
|
dev->req_pending = 0;
|
||||||
DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n",
|
DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n",
|
||||||
__FUNCTION__, tag, UDCCS0, flags);
|
__func__, tag, UDCCS0, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -651,20 +651,20 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
|
|||||||
req = container_of(_req, struct pxa2xx_request, req);
|
req = container_of(_req, struct pxa2xx_request, req);
|
||||||
if (unlikely (!_req || !_req->complete || !_req->buf
|
if (unlikely (!_req || !_req->complete || !_req->buf
|
||||||
|| !list_empty(&req->queue))) {
|
|| !list_empty(&req->queue))) {
|
||||||
DMSG("%s, bad params\n", __FUNCTION__);
|
DMSG("%s, bad params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep = container_of(_ep, struct pxa2xx_ep, ep);
|
ep = container_of(_ep, struct pxa2xx_ep, ep);
|
||||||
if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
|
||||||
DMSG("%s, bad ep\n", __FUNCTION__);
|
DMSG("%s, bad ep\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = ep->dev;
|
dev = ep->dev;
|
||||||
if (unlikely (!dev->driver
|
if (unlikely (!dev->driver
|
||||||
|| dev->gadget.speed == USB_SPEED_UNKNOWN)) {
|
|| dev->gadget.speed == USB_SPEED_UNKNOWN)) {
|
||||||
DMSG("%s, bogus device state\n", __FUNCTION__);
|
DMSG("%s, bogus device state\n", __func__);
|
||||||
return -ESHUTDOWN;
|
return -ESHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,7 +807,7 @@ static int pxa2xx_ep_set_halt(struct usb_ep *_ep, int value)
|
|||||||
if (unlikely (!_ep
|
if (unlikely (!_ep
|
||||||
|| (!ep->desc && ep->ep.name != ep0name))
|
|| (!ep->desc && ep->ep.name != ep0name))
|
||||||
|| ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
|| ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
|
||||||
DMSG("%s, bad ep\n", __FUNCTION__);
|
DMSG("%s, bad ep\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
@ -859,7 +859,7 @@ static int pxa2xx_ep_fifo_status(struct usb_ep *_ep)
|
|||||||
|
|
||||||
ep = container_of(_ep, struct pxa2xx_ep, ep);
|
ep = container_of(_ep, struct pxa2xx_ep, ep);
|
||||||
if (!_ep) {
|
if (!_ep) {
|
||||||
DMSG("%s, bad ep\n", __FUNCTION__);
|
DMSG("%s, bad ep\n", __func__);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
/* pxa can't report unclaimed bytes from IN fifos */
|
/* pxa can't report unclaimed bytes from IN fifos */
|
||||||
@ -878,7 +878,7 @@ static void pxa2xx_ep_fifo_flush(struct usb_ep *_ep)
|
|||||||
|
|
||||||
ep = container_of(_ep, struct pxa2xx_ep, ep);
|
ep = container_of(_ep, struct pxa2xx_ep, ep);
|
||||||
if (!_ep || ep->ep.name == ep0name || !list_empty(&ep->queue)) {
|
if (!_ep || ep->ep.name == ep0name || !list_empty(&ep->queue)) {
|
||||||
DMSG("%s, bad ep\n", __FUNCTION__);
|
DMSG("%s, bad ep\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1813,7 +1813,7 @@ pxa2xx_udc_irq(int irq, void *_dev)
|
|||||||
|
|
||||||
static void nop_release (struct device *dev)
|
static void nop_release (struct device *dev)
|
||||||
{
|
{
|
||||||
DMSG("%s %s\n", __FUNCTION__, dev->bus_id);
|
DMSG("%s %s\n", __func__, dev->bus_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this uses load-time allocation and initialization (instead of
|
/* this uses load-time allocation and initialization (instead of
|
||||||
|
@ -204,7 +204,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_SUPPORTED_LIST:
|
case OID_GEN_SUPPORTED_LIST:
|
||||||
DBG("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
|
DBG("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
|
||||||
length = sizeof (oid_supported_list);
|
length = sizeof (oid_supported_list);
|
||||||
count = length / sizeof (u32);
|
count = length / sizeof (u32);
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
@ -214,7 +214,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_HARDWARE_STATUS:
|
case OID_GEN_HARDWARE_STATUS:
|
||||||
DBG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
|
DBG("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
|
||||||
/* Bogus question!
|
/* Bogus question!
|
||||||
* Hardware must be ready to receive high level protocols.
|
* Hardware must be ready to receive high level protocols.
|
||||||
* BTW:
|
* BTW:
|
||||||
@ -227,14 +227,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_MEDIA_SUPPORTED:
|
case OID_GEN_MEDIA_SUPPORTED:
|
||||||
DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_MEDIA_IN_USE:
|
case OID_GEN_MEDIA_IN_USE:
|
||||||
DBG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
|
||||||
/* one medium, one transport... (maybe you do it better) */
|
/* one medium, one transport... (maybe you do it better) */
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
@ -242,7 +242,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||||||
DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].dev) {
|
if (rndis_per_dev_params [configNr].dev) {
|
||||||
*outbuf = cpu_to_le32 (
|
*outbuf = cpu_to_le32 (
|
||||||
rndis_per_dev_params [configNr].dev->mtu);
|
rndis_per_dev_params [configNr].dev->mtu);
|
||||||
@ -253,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_LINK_SPEED:
|
case OID_GEN_LINK_SPEED:
|
||||||
if (rndis_debug > 1)
|
if (rndis_debug > 1)
|
||||||
DBG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
|
DBG("%s: OID_GEN_LINK_SPEED\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].media_state
|
if (rndis_per_dev_params [configNr].media_state
|
||||||
== NDIS_MEDIA_STATE_DISCONNECTED)
|
== NDIS_MEDIA_STATE_DISCONNECTED)
|
||||||
*outbuf = __constant_cpu_to_le32 (0);
|
*outbuf = __constant_cpu_to_le32 (0);
|
||||||
@ -265,7 +265,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||||||
DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
|
DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].dev) {
|
if (rndis_per_dev_params [configNr].dev) {
|
||||||
*outbuf = cpu_to_le32 (
|
*outbuf = cpu_to_le32 (
|
||||||
rndis_per_dev_params [configNr].dev->mtu);
|
rndis_per_dev_params [configNr].dev->mtu);
|
||||||
@ -275,7 +275,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||||||
DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
|
DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].dev) {
|
if (rndis_per_dev_params [configNr].dev) {
|
||||||
*outbuf = cpu_to_le32 (
|
*outbuf = cpu_to_le32 (
|
||||||
rndis_per_dev_params [configNr].dev->mtu);
|
rndis_per_dev_params [configNr].dev->mtu);
|
||||||
@ -285,7 +285,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_VENDOR_ID:
|
case OID_GEN_VENDOR_ID:
|
||||||
DBG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
|
DBG("%s: OID_GEN_VENDOR_ID\n", __func__);
|
||||||
*outbuf = cpu_to_le32 (
|
*outbuf = cpu_to_le32 (
|
||||||
rndis_per_dev_params [configNr].vendorID);
|
rndis_per_dev_params [configNr].vendorID);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
@ -293,7 +293,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_VENDOR_DESCRIPTION:
|
case OID_GEN_VENDOR_DESCRIPTION:
|
||||||
DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
|
DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
|
||||||
length = strlen (rndis_per_dev_params [configNr].vendorDescr);
|
length = strlen (rndis_per_dev_params [configNr].vendorDescr);
|
||||||
memcpy (outbuf,
|
memcpy (outbuf,
|
||||||
rndis_per_dev_params [configNr].vendorDescr, length);
|
rndis_per_dev_params [configNr].vendorDescr, length);
|
||||||
@ -301,7 +301,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_VENDOR_DRIVER_VERSION:
|
case OID_GEN_VENDOR_DRIVER_VERSION:
|
||||||
DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
|
DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
|
||||||
/* Created as LE */
|
/* Created as LE */
|
||||||
*outbuf = rndis_driver_version;
|
*outbuf = rndis_driver_version;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
@ -309,14 +309,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||||
DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
|
DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
|
||||||
*outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
|
*outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||||
DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
|
||||||
*outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
|
*outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
@ -324,14 +324,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||||
if (rndis_debug > 1)
|
if (rndis_debug > 1)
|
||||||
DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.media_state);
|
.media_state);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_PHYSICAL_MEDIUM:
|
case OID_GEN_PHYSICAL_MEDIUM:
|
||||||
DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
|
DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
|
||||||
*outbuf = __constant_cpu_to_le32 (0);
|
*outbuf = __constant_cpu_to_le32 (0);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
@ -341,7 +341,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
* versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
|
* versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
|
||||||
*/
|
*/
|
||||||
case OID_GEN_MAC_OPTIONS: /* from WinME */
|
case OID_GEN_MAC_OPTIONS: /* from WinME */
|
||||||
DBG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MAC_OPTIONS\n", __func__);
|
||||||
*outbuf = __constant_cpu_to_le32(
|
*outbuf = __constant_cpu_to_le32(
|
||||||
NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
NDIS_MAC_OPTION_RECEIVE_SERIALIZED
|
||||||
| NDIS_MAC_OPTION_FULL_DUPLEX);
|
| NDIS_MAC_OPTION_FULL_DUPLEX);
|
||||||
@ -353,7 +353,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_XMIT_OK:
|
case OID_GEN_XMIT_OK:
|
||||||
if (rndis_debug > 1)
|
if (rndis_debug > 1)
|
||||||
DBG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
|
DBG("%s: OID_GEN_XMIT_OK\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (
|
*outbuf = cpu_to_le32 (
|
||||||
rndis_per_dev_params [configNr].stats->tx_packets -
|
rndis_per_dev_params [configNr].stats->tx_packets -
|
||||||
@ -366,7 +366,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_RCV_OK:
|
case OID_GEN_RCV_OK:
|
||||||
if (rndis_debug > 1)
|
if (rndis_debug > 1)
|
||||||
DBG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
|
DBG("%s: OID_GEN_RCV_OK\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (
|
*outbuf = cpu_to_le32 (
|
||||||
rndis_per_dev_params [configNr].stats->rx_packets -
|
rndis_per_dev_params [configNr].stats->rx_packets -
|
||||||
@ -379,7 +379,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_XMIT_ERROR:
|
case OID_GEN_XMIT_ERROR:
|
||||||
if (rndis_debug > 1)
|
if (rndis_debug > 1)
|
||||||
DBG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
|
DBG("%s: OID_GEN_XMIT_ERROR\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->tx_errors);
|
.stats->tx_errors);
|
||||||
@ -390,7 +390,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_RCV_ERROR:
|
case OID_GEN_RCV_ERROR:
|
||||||
if (rndis_debug > 1)
|
if (rndis_debug > 1)
|
||||||
DBG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
|
DBG("%s: OID_GEN_RCV_ERROR\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->rx_errors);
|
.stats->rx_errors);
|
||||||
@ -400,7 +400,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_GEN_RCV_NO_BUFFER:
|
case OID_GEN_RCV_NO_BUFFER:
|
||||||
DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
|
DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->rx_dropped);
|
.stats->rx_dropped);
|
||||||
@ -410,7 +410,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
#ifdef RNDIS_OPTIONAL_STATS
|
#ifdef RNDIS_OPTIONAL_STATS
|
||||||
case OID_GEN_DIRECTED_BYTES_XMIT:
|
case OID_GEN_DIRECTED_BYTES_XMIT:
|
||||||
DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
|
DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __func__);
|
||||||
/*
|
/*
|
||||||
* Aunt Tilly's size of shoes
|
* Aunt Tilly's size of shoes
|
||||||
* minus antarctica count of penguins
|
* minus antarctica count of penguins
|
||||||
@ -430,7 +430,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_DIRECTED_FRAMES_XMIT:
|
case OID_GEN_DIRECTED_FRAMES_XMIT:
|
||||||
DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
|
DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __func__);
|
||||||
/* dito */
|
/* dito */
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (
|
*outbuf = cpu_to_le32 (
|
||||||
@ -446,7 +446,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_MULTICAST_BYTES_XMIT:
|
case OID_GEN_MULTICAST_BYTES_XMIT:
|
||||||
DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->multicast*1234);
|
.stats->multicast*1234);
|
||||||
@ -455,7 +455,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_MULTICAST_FRAMES_XMIT:
|
case OID_GEN_MULTICAST_FRAMES_XMIT:
|
||||||
DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->multicast);
|
.stats->multicast);
|
||||||
@ -464,7 +464,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_BROADCAST_BYTES_XMIT:
|
case OID_GEN_BROADCAST_BYTES_XMIT:
|
||||||
DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
|
DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->tx_packets/42*255);
|
.stats->tx_packets/42*255);
|
||||||
@ -473,7 +473,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_BROADCAST_FRAMES_XMIT:
|
case OID_GEN_BROADCAST_FRAMES_XMIT:
|
||||||
DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
|
DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->tx_packets/42);
|
.stats->tx_packets/42);
|
||||||
@ -482,19 +482,19 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_DIRECTED_BYTES_RCV:
|
case OID_GEN_DIRECTED_BYTES_RCV:
|
||||||
DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
|
DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __func__);
|
||||||
*outbuf = __constant_cpu_to_le32 (0);
|
*outbuf = __constant_cpu_to_le32 (0);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_DIRECTED_FRAMES_RCV:
|
case OID_GEN_DIRECTED_FRAMES_RCV:
|
||||||
DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
|
DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __func__);
|
||||||
*outbuf = __constant_cpu_to_le32 (0);
|
*outbuf = __constant_cpu_to_le32 (0);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_MULTICAST_BYTES_RCV:
|
case OID_GEN_MULTICAST_BYTES_RCV:
|
||||||
DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->multicast * 1111);
|
.stats->multicast * 1111);
|
||||||
@ -503,7 +503,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_MULTICAST_FRAMES_RCV:
|
case OID_GEN_MULTICAST_FRAMES_RCV:
|
||||||
DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
|
DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->multicast);
|
.stats->multicast);
|
||||||
@ -512,7 +512,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_BROADCAST_BYTES_RCV:
|
case OID_GEN_BROADCAST_BYTES_RCV:
|
||||||
DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
|
DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->rx_packets/42*255);
|
.stats->rx_packets/42*255);
|
||||||
@ -521,7 +521,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_BROADCAST_FRAMES_RCV:
|
case OID_GEN_BROADCAST_FRAMES_RCV:
|
||||||
DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
|
DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->rx_packets/42);
|
.stats->rx_packets/42);
|
||||||
@ -530,7 +530,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_RCV_CRC_ERROR:
|
case OID_GEN_RCV_CRC_ERROR:
|
||||||
DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
|
DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->rx_crc_errors);
|
.stats->rx_crc_errors);
|
||||||
@ -539,7 +539,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_GEN_TRANSMIT_QUEUE_LENGTH:
|
case OID_GEN_TRANSMIT_QUEUE_LENGTH:
|
||||||
DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
|
DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __func__);
|
||||||
*outbuf = __constant_cpu_to_le32 (0);
|
*outbuf = __constant_cpu_to_le32 (0);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
@ -549,7 +549,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_802_3_PERMANENT_ADDRESS:
|
case OID_802_3_PERMANENT_ADDRESS:
|
||||||
DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
|
DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].dev) {
|
if (rndis_per_dev_params [configNr].dev) {
|
||||||
length = ETH_ALEN;
|
length = ETH_ALEN;
|
||||||
memcpy (outbuf,
|
memcpy (outbuf,
|
||||||
@ -561,7 +561,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_802_3_CURRENT_ADDRESS:
|
case OID_802_3_CURRENT_ADDRESS:
|
||||||
DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
|
DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].dev) {
|
if (rndis_per_dev_params [configNr].dev) {
|
||||||
length = ETH_ALEN;
|
length = ETH_ALEN;
|
||||||
memcpy (outbuf,
|
memcpy (outbuf,
|
||||||
@ -573,7 +573,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_802_3_MULTICAST_LIST:
|
case OID_802_3_MULTICAST_LIST:
|
||||||
DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
|
DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
|
||||||
/* Multicast base address only */
|
/* Multicast base address only */
|
||||||
*outbuf = __constant_cpu_to_le32 (0xE0000000);
|
*outbuf = __constant_cpu_to_le32 (0xE0000000);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
@ -581,21 +581,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||||
DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
|
DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
|
||||||
/* Multicast base address only */
|
/* Multicast base address only */
|
||||||
*outbuf = __constant_cpu_to_le32 (1);
|
*outbuf = __constant_cpu_to_le32 (1);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_MAC_OPTIONS:
|
case OID_802_3_MAC_OPTIONS:
|
||||||
DBG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
|
DBG("%s: OID_802_3_MAC_OPTIONS\n", __func__);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* ieee802.3 statistics OIDs (table 4-4) */
|
/* ieee802.3 statistics OIDs (table 4-4) */
|
||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
||||||
DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
|
DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
|
||||||
if (rndis_per_dev_params [configNr].stats) {
|
if (rndis_per_dev_params [configNr].stats) {
|
||||||
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
|
||||||
.stats->rx_frame_errors);
|
.stats->rx_frame_errors);
|
||||||
@ -605,51 +605,51 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_802_3_XMIT_ONE_COLLISION:
|
case OID_802_3_XMIT_ONE_COLLISION:
|
||||||
DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
|
DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
|
||||||
*outbuf = __constant_cpu_to_le32 (0);
|
*outbuf = __constant_cpu_to_le32 (0);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
case OID_802_3_XMIT_MORE_COLLISIONS:
|
case OID_802_3_XMIT_MORE_COLLISIONS:
|
||||||
DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
|
DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
|
||||||
*outbuf = __constant_cpu_to_le32 (0);
|
*outbuf = __constant_cpu_to_le32 (0);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef RNDIS_OPTIONAL_STATS
|
#ifdef RNDIS_OPTIONAL_STATS
|
||||||
case OID_802_3_XMIT_DEFERRED:
|
case OID_802_3_XMIT_DEFERRED:
|
||||||
DBG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
|
DBG("%s: OID_802_3_XMIT_DEFERRED\n", __func__);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_XMIT_MAX_COLLISIONS:
|
case OID_802_3_XMIT_MAX_COLLISIONS:
|
||||||
DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
|
DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __func__);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_RCV_OVERRUN:
|
case OID_802_3_RCV_OVERRUN:
|
||||||
DBG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
|
DBG("%s: OID_802_3_RCV_OVERRUN\n", __func__);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_XMIT_UNDERRUN:
|
case OID_802_3_XMIT_UNDERRUN:
|
||||||
DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
|
DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __func__);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_XMIT_HEARTBEAT_FAILURE:
|
case OID_802_3_XMIT_HEARTBEAT_FAILURE:
|
||||||
DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
|
DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __func__);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_XMIT_TIMES_CRS_LOST:
|
case OID_802_3_XMIT_TIMES_CRS_LOST:
|
||||||
DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
|
DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __func__);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OID_802_3_XMIT_LATE_COLLISIONS:
|
case OID_802_3_XMIT_LATE_COLLISIONS:
|
||||||
DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
|
DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __func__);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
break;
|
break;
|
||||||
#endif /* RNDIS_OPTIONAL_STATS */
|
#endif /* RNDIS_OPTIONAL_STATS */
|
||||||
@ -657,7 +657,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
#ifdef RNDIS_PM
|
#ifdef RNDIS_PM
|
||||||
/* power management OIDs (table 4-5) */
|
/* power management OIDs (table 4-5) */
|
||||||
case OID_PNP_CAPABILITIES:
|
case OID_PNP_CAPABILITIES:
|
||||||
DBG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
|
DBG("%s: OID_PNP_CAPABILITIES\n", __func__);
|
||||||
|
|
||||||
/* for now, no wakeup capabilities */
|
/* for now, no wakeup capabilities */
|
||||||
length = sizeof (struct NDIS_PNP_CAPABILITIES);
|
length = sizeof (struct NDIS_PNP_CAPABILITIES);
|
||||||
@ -665,7 +665,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
case OID_PNP_QUERY_POWER:
|
case OID_PNP_QUERY_POWER:
|
||||||
DBG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__,
|
DBG("%s: OID_PNP_QUERY_POWER D%d\n", __func__,
|
||||||
le32_to_cpu(get_unaligned((__le32 *)buf)) - 1);
|
le32_to_cpu(get_unaligned((__le32 *)buf)) - 1);
|
||||||
/* only suspend is a real power state, and
|
/* only suspend is a real power state, and
|
||||||
* it can't be entered by OID_PNP_SET_POWER...
|
* it can't be entered by OID_PNP_SET_POWER...
|
||||||
@ -677,7 +677,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
pr_warning("%s: query unknown OID 0x%08X\n",
|
pr_warning("%s: query unknown OID 0x%08X\n",
|
||||||
__FUNCTION__, OID);
|
__func__, OID);
|
||||||
}
|
}
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
length = 0;
|
length = 0;
|
||||||
@ -729,7 +729,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
|
|||||||
*params->filter = (u16) le32_to_cpu(get_unaligned(
|
*params->filter = (u16) le32_to_cpu(get_unaligned(
|
||||||
(__le32 *)buf));
|
(__le32 *)buf));
|
||||||
DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
|
DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
|
||||||
__FUNCTION__, *params->filter);
|
__func__, *params->filter);
|
||||||
|
|
||||||
/* this call has a significant side effect: it's
|
/* this call has a significant side effect: it's
|
||||||
* what makes the packet flow start and stop, like
|
* what makes the packet flow start and stop, like
|
||||||
@ -753,7 +753,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
|
|||||||
|
|
||||||
case OID_802_3_MULTICAST_LIST:
|
case OID_802_3_MULTICAST_LIST:
|
||||||
/* I think we can ignore this */
|
/* I think we can ignore this */
|
||||||
DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
|
DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
break;
|
break;
|
||||||
#if 0
|
#if 0
|
||||||
@ -762,7 +762,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
|
|||||||
struct rndis_config_parameter *param;
|
struct rndis_config_parameter *param;
|
||||||
param = (struct rndis_config_parameter *) buf;
|
param = (struct rndis_config_parameter *) buf;
|
||||||
DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
|
DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
|
||||||
__FUNCTION__,
|
__func__,
|
||||||
min(cpu_to_le32(param->ParameterNameLength),80),
|
min(cpu_to_le32(param->ParameterNameLength),80),
|
||||||
buf + param->ParameterNameOffset);
|
buf + param->ParameterNameOffset);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
@ -778,7 +778,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
|
|||||||
* FIXME ... then things go batty; Windows wedges itself.
|
* FIXME ... then things go batty; Windows wedges itself.
|
||||||
*/
|
*/
|
||||||
i = le32_to_cpu(get_unaligned((__le32 *)buf));
|
i = le32_to_cpu(get_unaligned((__le32 *)buf));
|
||||||
DBG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1);
|
DBG("%s: OID_PNP_SET_POWER D%d\n", __func__, i - 1);
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case NdisDeviceStateD0:
|
case NdisDeviceStateD0:
|
||||||
*params->filter = params->saved_filter;
|
*params->filter = params->saved_filter;
|
||||||
@ -802,7 +802,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
pr_warning("%s: set unknown OID 0x%08X, size %d\n",
|
pr_warning("%s: set unknown OID 0x%08X, size %d\n",
|
||||||
__FUNCTION__, OID, buf_len);
|
__func__, OID, buf_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -855,7 +855,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
|
|||||||
rndis_query_cmplt_type *resp;
|
rndis_query_cmplt_type *resp;
|
||||||
rndis_resp_t *r;
|
rndis_resp_t *r;
|
||||||
|
|
||||||
// DBG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
|
// DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID));
|
||||||
if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
|
if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -908,9 +908,9 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
|
|||||||
BufOffset = le32_to_cpu (buf->InformationBufferOffset);
|
BufOffset = le32_to_cpu (buf->InformationBufferOffset);
|
||||||
|
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
DBG("%s: Length: %d\n", __FUNCTION__, BufLength);
|
DBG("%s: Length: %d\n", __func__, BufLength);
|
||||||
DBG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
|
DBG("%s: Offset: %d\n", __func__, BufOffset);
|
||||||
DBG("%s: InfoBuffer: ", __FUNCTION__);
|
DBG("%s: InfoBuffer: ", __func__);
|
||||||
|
|
||||||
for (i = 0; i < BufLength; i++) {
|
for (i = 0; i < BufLength; i++) {
|
||||||
DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
|
DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
|
||||||
@ -1080,14 +1080,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
|
|||||||
switch (MsgType) {
|
switch (MsgType) {
|
||||||
case REMOTE_NDIS_INITIALIZE_MSG:
|
case REMOTE_NDIS_INITIALIZE_MSG:
|
||||||
DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
|
DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
|
||||||
__FUNCTION__ );
|
__func__ );
|
||||||
params->state = RNDIS_INITIALIZED;
|
params->state = RNDIS_INITIALIZED;
|
||||||
return rndis_init_response (configNr,
|
return rndis_init_response (configNr,
|
||||||
(rndis_init_msg_type *) buf);
|
(rndis_init_msg_type *) buf);
|
||||||
|
|
||||||
case REMOTE_NDIS_HALT_MSG:
|
case REMOTE_NDIS_HALT_MSG:
|
||||||
DBG("%s: REMOTE_NDIS_HALT_MSG\n",
|
DBG("%s: REMOTE_NDIS_HALT_MSG\n",
|
||||||
__FUNCTION__ );
|
__func__ );
|
||||||
params->state = RNDIS_UNINITIALIZED;
|
params->state = RNDIS_UNINITIALIZED;
|
||||||
if (params->dev) {
|
if (params->dev) {
|
||||||
netif_carrier_off (params->dev);
|
netif_carrier_off (params->dev);
|
||||||
@ -1105,7 +1105,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
|
|||||||
|
|
||||||
case REMOTE_NDIS_RESET_MSG:
|
case REMOTE_NDIS_RESET_MSG:
|
||||||
DBG("%s: REMOTE_NDIS_RESET_MSG\n",
|
DBG("%s: REMOTE_NDIS_RESET_MSG\n",
|
||||||
__FUNCTION__ );
|
__func__ );
|
||||||
return rndis_reset_response (configNr,
|
return rndis_reset_response (configNr,
|
||||||
(rndis_reset_msg_type *) buf);
|
(rndis_reset_msg_type *) buf);
|
||||||
|
|
||||||
@ -1113,7 +1113,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
|
|||||||
/* For USB: host does this every 5 seconds */
|
/* For USB: host does this every 5 seconds */
|
||||||
if (rndis_debug > 1)
|
if (rndis_debug > 1)
|
||||||
DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
|
DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
|
||||||
__FUNCTION__ );
|
__func__ );
|
||||||
return rndis_keepalive_response (configNr,
|
return rndis_keepalive_response (configNr,
|
||||||
(rndis_keepalive_msg_type *)
|
(rndis_keepalive_msg_type *)
|
||||||
buf);
|
buf);
|
||||||
@ -1124,7 +1124,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
|
|||||||
* suspending itself.
|
* suspending itself.
|
||||||
*/
|
*/
|
||||||
pr_warning("%s: unknown RNDIS message 0x%08X len %d\n",
|
pr_warning("%s: unknown RNDIS message 0x%08X len %d\n",
|
||||||
__FUNCTION__ , MsgType, MsgLength);
|
__func__ , MsgType, MsgLength);
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < MsgLength; i += 16) {
|
for (i = 0; i < MsgLength; i += 16) {
|
||||||
@ -1159,7 +1159,7 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *))
|
|||||||
if (!rndis_per_dev_params [i].used) {
|
if (!rndis_per_dev_params [i].used) {
|
||||||
rndis_per_dev_params [i].used = 1;
|
rndis_per_dev_params [i].used = 1;
|
||||||
rndis_per_dev_params [i].ack = rndis_control_ack;
|
rndis_per_dev_params [i].ack = rndis_control_ack;
|
||||||
DBG("%s: configNr = %d\n", __FUNCTION__, i);
|
DBG("%s: configNr = %d\n", __func__, i);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1170,7 +1170,7 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *))
|
|||||||
|
|
||||||
void rndis_deregister (int configNr)
|
void rndis_deregister (int configNr)
|
||||||
{
|
{
|
||||||
DBG("%s: \n", __FUNCTION__ );
|
DBG("%s: \n", __func__ );
|
||||||
|
|
||||||
if (configNr >= RNDIS_MAX_CONFIGS) return;
|
if (configNr >= RNDIS_MAX_CONFIGS) return;
|
||||||
rndis_per_dev_params [configNr].used = 0;
|
rndis_per_dev_params [configNr].used = 0;
|
||||||
@ -1182,7 +1182,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev,
|
|||||||
struct net_device_stats *stats,
|
struct net_device_stats *stats,
|
||||||
u16 *cdc_filter)
|
u16 *cdc_filter)
|
||||||
{
|
{
|
||||||
DBG("%s:\n", __FUNCTION__ );
|
DBG("%s:\n", __func__ );
|
||||||
if (!dev || !stats) return -1;
|
if (!dev || !stats) return -1;
|
||||||
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
|
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
|
||||||
|
|
||||||
@ -1195,7 +1195,7 @@ int rndis_set_param_dev (u8 configNr, struct net_device *dev,
|
|||||||
|
|
||||||
int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
|
int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
|
||||||
{
|
{
|
||||||
DBG("%s:\n", __FUNCTION__ );
|
DBG("%s:\n", __func__ );
|
||||||
if (!vendorDescr) return -1;
|
if (!vendorDescr) return -1;
|
||||||
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
|
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
|
||||||
|
|
||||||
@ -1207,7 +1207,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
|
|||||||
|
|
||||||
int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
|
int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
|
||||||
{
|
{
|
||||||
DBG("%s: %u %u\n", __FUNCTION__, medium, speed);
|
DBG("%s: %u %u\n", __func__, medium, speed);
|
||||||
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
|
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
|
||||||
|
|
||||||
rndis_per_dev_params [configNr].medium = medium;
|
rndis_per_dev_params [configNr].medium = medium;
|
||||||
@ -1403,7 +1403,7 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
|
|||||||
#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
|
#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
|
||||||
|
|
||||||
|
|
||||||
int __devinit rndis_init (void)
|
int __init rndis_init (void)
|
||||||
{
|
{
|
||||||
u8 i;
|
u8 i;
|
||||||
|
|
||||||
@ -1415,7 +1415,7 @@ int __devinit rndis_init (void)
|
|||||||
if (!(rndis_connect_state [i]
|
if (!(rndis_connect_state [i]
|
||||||
= create_proc_entry (name, 0660, NULL)))
|
= create_proc_entry (name, 0660, NULL)))
|
||||||
{
|
{
|
||||||
DBG("%s :remove entries", __FUNCTION__);
|
DBG("%s :remove entries", __func__);
|
||||||
while (i) {
|
while (i) {
|
||||||
sprintf (name, NAME_TEMPLATE, --i);
|
sprintf (name, NAME_TEMPLATE, --i);
|
||||||
remove_proc_entry (name, NULL);
|
remove_proc_entry (name, NULL);
|
||||||
|
@ -2163,8 +2163,7 @@ static void gs_free_ports(struct gs_dev *dev)
|
|||||||
port->port_dev = NULL;
|
port->port_dev = NULL;
|
||||||
wake_up_interruptible(&port->port_write_wait);
|
wake_up_interruptible(&port->port_write_wait);
|
||||||
if (port->port_tty) {
|
if (port->port_tty) {
|
||||||
wake_up_interruptible(&port->port_tty->read_wait);
|
tty_hangup(port->port_tty);
|
||||||
wake_up_interruptible(&port->port_tty->write_wait);
|
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&port->port_lock, flags);
|
spin_unlock_irqrestore(&port->port_lock, flags);
|
||||||
} else {
|
} else {
|
||||||
|
@ -30,8 +30,8 @@ config USB_EHCI_HCD
|
|||||||
module will be called ehci-hcd.
|
module will be called ehci-hcd.
|
||||||
|
|
||||||
config USB_EHCI_ROOT_HUB_TT
|
config USB_EHCI_ROOT_HUB_TT
|
||||||
bool "Root Hub Transaction Translators (EXPERIMENTAL)"
|
bool "Root Hub Transaction Translators"
|
||||||
depends on USB_EHCI_HCD && EXPERIMENTAL
|
depends on USB_EHCI_HCD
|
||||||
---help---
|
---help---
|
||||||
Some EHCI chips have vendor-specific extensions to integrate
|
Some EHCI chips have vendor-specific extensions to integrate
|
||||||
transaction translators, so that no OHCI or UHCI companion
|
transaction translators, so that no OHCI or UHCI companion
|
||||||
@ -260,3 +260,9 @@ config USB_R8A66597_HCD
|
|||||||
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 r8a66597-hcd.
|
module will be called r8a66597-hcd.
|
||||||
|
|
||||||
|
config SUPERH_ON_CHIP_R8A66597
|
||||||
|
boolean "Enable SuperH on-chip USB like the R8A66597"
|
||||||
|
depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366
|
||||||
|
help
|
||||||
|
Renesas SuperH processor has USB like the R8A66597.
|
||||||
|
This driver supported processor is SH7366.
|
||||||
|
@ -237,6 +237,7 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
|
|||||||
if (usb_disabled())
|
if (usb_disabled())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* FIXME we only want one one probe() not two */
|
||||||
ret = usb_ehci_au1xxx_probe(&ehci_au1xxx_hc_driver, &hcd, pdev);
|
ret = usb_ehci_au1xxx_probe(&ehci_au1xxx_hc_driver, &hcd, pdev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -245,6 +246,7 @@ static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
/* FIXME we only want one one remove() not two */
|
||||||
usb_ehci_au1xxx_remove(hcd, pdev);
|
usb_ehci_au1xxx_remove(hcd, pdev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -265,7 +267,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
MODULE_ALIAS("au1xxx-ehci");
|
MODULE_ALIAS("platform:au1xxx-ehci");
|
||||||
static struct platform_driver ehci_hcd_au1xxx_driver = {
|
static struct platform_driver ehci_hcd_au1xxx_driver = {
|
||||||
.probe = ehci_hcd_au1xxx_drv_probe,
|
.probe = ehci_hcd_au1xxx_drv_probe,
|
||||||
.remove = ehci_hcd_au1xxx_drv_remove,
|
.remove = ehci_hcd_au1xxx_drv_remove,
|
||||||
@ -274,6 +276,5 @@ static struct platform_driver ehci_hcd_au1xxx_driver = {
|
|||||||
/*.resume = ehci_hcd_au1xxx_drv_resume, */
|
/*.resume = ehci_hcd_au1xxx_drv_resume, */
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "au1xxx-ehci",
|
.name = "au1xxx-ehci",
|
||||||
.bus = &platform_bus_type
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#define ehci_warn(ehci, fmt, args...) \
|
#define ehci_warn(ehci, fmt, args...) \
|
||||||
dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
|
dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
|
||||||
|
|
||||||
#ifdef EHCI_VERBOSE_DEBUG
|
#ifdef VERBOSE_DEBUG
|
||||||
# define vdbg dbg
|
# define vdbg dbg
|
||||||
# define ehci_vdbg ehci_dbg
|
# define ehci_vdbg ehci_dbg
|
||||||
#else
|
#else
|
||||||
@ -670,7 +670,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
|
|||||||
|
|
||||||
spin_lock_irqsave (&ehci->lock, flags);
|
spin_lock_irqsave (&ehci->lock, flags);
|
||||||
|
|
||||||
if (buf->bus->controller->power.power_state.event) {
|
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
|
||||||
size = scnprintf (next, size,
|
size = scnprintf (next, size,
|
||||||
"bus %s, device %s (driver " DRIVER_VERSION ")\n"
|
"bus %s, device %s (driver " DRIVER_VERSION ")\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* (C) Copyright David Brownell 2000-2002
|
|
||||||
* Copyright (c) 2005 MontaVista Software
|
* Copyright (c) 2005 MontaVista Software
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@ -28,7 +27,6 @@
|
|||||||
/* FIXME: Power Management is un-ported so temporarily disable it */
|
/* FIXME: Power Management is un-ported so temporarily disable it */
|
||||||
#undef CONFIG_PM
|
#undef CONFIG_PM
|
||||||
|
|
||||||
/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */
|
|
||||||
|
|
||||||
/* configure so an HC device and id are always provided */
|
/* configure so an HC device and id are always provided */
|
||||||
/* always called with process context; sleeping is OK */
|
/* always called with process context; sleeping is OK */
|
||||||
@ -331,6 +329,7 @@ static int ehci_fsl_drv_probe(struct platform_device *pdev)
|
|||||||
if (usb_disabled())
|
if (usb_disabled())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* FIXME we only want one one probe() not two */
|
||||||
return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev);
|
return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,12 +337,12 @@ static int ehci_fsl_drv_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
/* FIXME we only want one one remove() not two */
|
||||||
usb_hcd_fsl_remove(hcd, pdev);
|
usb_hcd_fsl_remove(hcd, pdev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_ALIAS("fsl-ehci");
|
MODULE_ALIAS("platform:fsl-ehci");
|
||||||
|
|
||||||
static struct platform_driver ehci_fsl_driver = {
|
static struct platform_driver ehci_fsl_driver = {
|
||||||
.probe = ehci_fsl_drv_probe,
|
.probe = ehci_fsl_drv_probe,
|
||||||
@ -351,5 +350,5 @@ static struct platform_driver ehci_fsl_driver = {
|
|||||||
.shutdown = usb_hcd_platform_shutdown,
|
.shutdown = usb_hcd_platform_shutdown,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "fsl-ehci",
|
.name = "fsl-ehci",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -57,35 +57,6 @@
|
|||||||
* Special thanks to Intel and VIA for providing host controllers to
|
* Special thanks to Intel and VIA for providing host controllers to
|
||||||
* test this driver on, and Cypress (including In-System Design) for
|
* test this driver on, and Cypress (including In-System Design) for
|
||||||
* providing early devices for those host controllers to talk to!
|
* providing early devices for those host controllers to talk to!
|
||||||
*
|
|
||||||
* HISTORY:
|
|
||||||
*
|
|
||||||
* 2004-05-10 Root hub and PCI suspend/resume support; remote wakeup. (db)
|
|
||||||
* 2004-02-24 Replace pci_* with generic dma_* API calls (dsaxena@plexity.net)
|
|
||||||
* 2003-12-29 Rewritten high speed iso transfer support (by Michal Sojka,
|
|
||||||
* <sojkam@centrum.cz>, updates by DB).
|
|
||||||
*
|
|
||||||
* 2002-11-29 Correct handling for hw async_next register.
|
|
||||||
* 2002-08-06 Handling for bulk and interrupt transfers is mostly shared;
|
|
||||||
* only scheduling is different, no arbitrary limitations.
|
|
||||||
* 2002-07-25 Sanity check PCI reads, mostly for better cardbus support,
|
|
||||||
* clean up HC run state handshaking.
|
|
||||||
* 2002-05-24 Preliminary FS/LS interrupts, using scheduling shortcuts
|
|
||||||
* 2002-05-11 Clear TT errors for FS/LS ctrl/bulk. Fill in some other
|
|
||||||
* missing pieces: enabling 64bit dma, handoff from BIOS/SMM.
|
|
||||||
* 2002-05-07 Some error path cleanups to report better errors; wmb();
|
|
||||||
* use non-CVS version id; better iso bandwidth claim.
|
|
||||||
* 2002-04-19 Control/bulk/interrupt submit no longer uses giveback() on
|
|
||||||
* errors in submit path. Bugfixes to interrupt scheduling/processing.
|
|
||||||
* 2002-03-05 Initial high-speed ISO support; reduce ITD memory; shift
|
|
||||||
* more checking to generic hcd framework (db). Make it work with
|
|
||||||
* Philips EHCI; reduce PCI traffic; shorten IRQ path (Rory Bolt).
|
|
||||||
* 2002-01-14 Minor cleanup; version synch.
|
|
||||||
* 2002-01-08 Fix roothub handoff of FS/LS to companion controllers.
|
|
||||||
* 2002-01-04 Control/Bulk queuing behaves.
|
|
||||||
*
|
|
||||||
* 2001-12-12 Initial patch version for Linux 2.5.1 kernel.
|
|
||||||
* 2001-June Works with usb-storage and NEC EHCI on 2.4
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DRIVER_VERSION "10 Dec 2004"
|
#define DRIVER_VERSION "10 Dec 2004"
|
||||||
@ -95,7 +66,7 @@
|
|||||||
static const char hcd_name [] = "ehci_hcd";
|
static const char hcd_name [] = "ehci_hcd";
|
||||||
|
|
||||||
|
|
||||||
#undef EHCI_VERBOSE_DEBUG
|
#undef VERBOSE_DEBUG
|
||||||
#undef EHCI_URB_TRACE
|
#undef EHCI_URB_TRACE
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -174,6 +145,16 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
|
|||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
|
||||||
|
u32 mask, u32 done, int usec)
|
||||||
|
{
|
||||||
|
int error = handshake(ehci, ptr, mask, done, usec);
|
||||||
|
if (error)
|
||||||
|
ehci_to_hcd(ehci)->state = HC_STATE_HALT;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
/* force HC to halt state from unknown (EHCI spec section 2.3) */
|
/* force HC to halt state from unknown (EHCI spec section 2.3) */
|
||||||
static int ehci_halt (struct ehci_hcd *ehci)
|
static int ehci_halt (struct ehci_hcd *ehci)
|
||||||
{
|
{
|
||||||
@ -246,11 +227,9 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
|
|||||||
/* wait for any schedule enables/disables to take effect */
|
/* wait for any schedule enables/disables to take effect */
|
||||||
temp = ehci_readl(ehci, &ehci->regs->command) << 10;
|
temp = ehci_readl(ehci, &ehci->regs->command) << 10;
|
||||||
temp &= STS_ASS | STS_PSS;
|
temp &= STS_ASS | STS_PSS;
|
||||||
if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS,
|
if (handshake_on_error_set_halt(ehci, &ehci->regs->status,
|
||||||
temp, 16 * 125) != 0) {
|
STS_ASS | STS_PSS, temp, 16 * 125))
|
||||||
ehci_to_hcd(ehci)->state = HC_STATE_HALT;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* then disable anything that's still active */
|
/* then disable anything that's still active */
|
||||||
temp = ehci_readl(ehci, &ehci->regs->command);
|
temp = ehci_readl(ehci, &ehci->regs->command);
|
||||||
@ -258,11 +237,8 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
|
|||||||
ehci_writel(ehci, temp, &ehci->regs->command);
|
ehci_writel(ehci, temp, &ehci->regs->command);
|
||||||
|
|
||||||
/* hardware can take 16 microframes to turn off ... */
|
/* hardware can take 16 microframes to turn off ... */
|
||||||
if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS,
|
handshake_on_error_set_halt(ehci, &ehci->regs->status,
|
||||||
0, 16 * 125) != 0) {
|
STS_ASS | STS_PSS, 0, 16 * 125);
|
||||||
ehci_to_hcd(ehci)->state = HC_STATE_HALT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -355,17 +331,13 @@ static void ehci_turn_off_all_ports(struct ehci_hcd *ehci)
|
|||||||
&ehci->regs->port_status[port]);
|
&ehci->regs->port_status[port]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
|
/*
|
||||||
* This forcibly disables dma and IRQs, helping kexec and other cases
|
* Halt HC, turn off all ports, and let the BIOS use the companion controllers.
|
||||||
* where the next system software may expect clean state.
|
* Should be called with ehci->lock held.
|
||||||
*/
|
*/
|
||||||
static void
|
static void ehci_silence_controller(struct ehci_hcd *ehci)
|
||||||
ehci_shutdown (struct usb_hcd *hcd)
|
|
||||||
{
|
{
|
||||||
struct ehci_hcd *ehci;
|
ehci_halt(ehci);
|
||||||
|
|
||||||
ehci = hcd_to_ehci (hcd);
|
|
||||||
(void) ehci_halt (ehci);
|
|
||||||
ehci_turn_off_all_ports(ehci);
|
ehci_turn_off_all_ports(ehci);
|
||||||
|
|
||||||
/* make BIOS/etc use companion controller during reboot */
|
/* make BIOS/etc use companion controller during reboot */
|
||||||
@ -375,6 +347,22 @@ ehci_shutdown (struct usb_hcd *hcd)
|
|||||||
ehci_readl(ehci, &ehci->regs->configured_flag);
|
ehci_readl(ehci, &ehci->regs->configured_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
|
||||||
|
* This forcibly disables dma and IRQs, helping kexec and other cases
|
||||||
|
* where the next system software may expect clean state.
|
||||||
|
*/
|
||||||
|
static void ehci_shutdown(struct usb_hcd *hcd)
|
||||||
|
{
|
||||||
|
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||||
|
|
||||||
|
del_timer_sync(&ehci->watchdog);
|
||||||
|
del_timer_sync(&ehci->iaa_watchdog);
|
||||||
|
|
||||||
|
spin_lock_irq(&ehci->lock);
|
||||||
|
ehci_silence_controller(ehci);
|
||||||
|
spin_unlock_irq(&ehci->lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
|
static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
|
||||||
{
|
{
|
||||||
unsigned port;
|
unsigned port;
|
||||||
@ -425,15 +413,15 @@ static void ehci_work (struct ehci_hcd *ehci)
|
|||||||
timer_action (ehci, TIMER_IO_WATCHDOG);
|
timer_action (ehci, TIMER_IO_WATCHDOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when the ehci_hcd module is removed.
|
||||||
|
*/
|
||||||
static void ehci_stop (struct usb_hcd *hcd)
|
static void ehci_stop (struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
|
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
|
||||||
|
|
||||||
ehci_dbg (ehci, "stop\n");
|
ehci_dbg (ehci, "stop\n");
|
||||||
|
|
||||||
/* Turn off port power on all root hub ports. */
|
|
||||||
ehci_port_power (ehci, 0);
|
|
||||||
|
|
||||||
/* no more interrupts ... */
|
/* no more interrupts ... */
|
||||||
del_timer_sync (&ehci->watchdog);
|
del_timer_sync (&ehci->watchdog);
|
||||||
del_timer_sync(&ehci->iaa_watchdog);
|
del_timer_sync(&ehci->iaa_watchdog);
|
||||||
@ -442,13 +430,10 @@ static void ehci_stop (struct usb_hcd *hcd)
|
|||||||
if (HC_IS_RUNNING (hcd->state))
|
if (HC_IS_RUNNING (hcd->state))
|
||||||
ehci_quiesce (ehci);
|
ehci_quiesce (ehci);
|
||||||
|
|
||||||
|
ehci_silence_controller(ehci);
|
||||||
ehci_reset (ehci);
|
ehci_reset (ehci);
|
||||||
ehci_writel(ehci, 0, &ehci->regs->intr_enable);
|
|
||||||
spin_unlock_irq(&ehci->lock);
|
spin_unlock_irq(&ehci->lock);
|
||||||
|
|
||||||
/* let companion controllers work when we aren't */
|
|
||||||
ehci_writel(ehci, 0, &ehci->regs->configured_flag);
|
|
||||||
|
|
||||||
remove_companion_file(ehci);
|
remove_companion_file(ehci);
|
||||||
remove_debug_files (ehci);
|
remove_debug_files (ehci);
|
||||||
|
|
||||||
@ -676,7 +661,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||||||
cmd = ehci_readl(ehci, &ehci->regs->command);
|
cmd = ehci_readl(ehci, &ehci->regs->command);
|
||||||
bh = 0;
|
bh = 0;
|
||||||
|
|
||||||
#ifdef EHCI_VERBOSE_DEBUG
|
#ifdef VERBOSE_DEBUG
|
||||||
/* unrequested/ignored: Frame List Rollover */
|
/* unrequested/ignored: Frame List Rollover */
|
||||||
dbg_status (ehci, "irq", status);
|
dbg_status (ehci, "irq", status);
|
||||||
#endif
|
#endif
|
||||||
@ -710,6 +695,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||||||
/* remote wakeup [4.3.1] */
|
/* remote wakeup [4.3.1] */
|
||||||
if (status & STS_PCD) {
|
if (status & STS_PCD) {
|
||||||
unsigned i = HCS_N_PORTS (ehci->hcs_params);
|
unsigned i = HCS_N_PORTS (ehci->hcs_params);
|
||||||
|
|
||||||
|
/* kick root hub later */
|
||||||
pcd_status = status;
|
pcd_status = status;
|
||||||
|
|
||||||
/* resume root hub? */
|
/* resume root hub? */
|
||||||
@ -738,8 +725,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||||||
|
|
||||||
/* PCI errors [4.15.2.4] */
|
/* PCI errors [4.15.2.4] */
|
||||||
if (unlikely ((status & STS_FATAL) != 0)) {
|
if (unlikely ((status & STS_FATAL) != 0)) {
|
||||||
/* bogus "fatal" IRQs appear on some chips... why? */
|
|
||||||
status = ehci_readl(ehci, &ehci->regs->status);
|
|
||||||
dbg_cmd (ehci, "fatal", ehci_readl(ehci,
|
dbg_cmd (ehci, "fatal", ehci_readl(ehci,
|
||||||
&ehci->regs->command));
|
&ehci->regs->command));
|
||||||
dbg_status (ehci, "fatal", status);
|
dbg_status (ehci, "fatal", status);
|
||||||
@ -758,7 +743,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
|||||||
if (bh)
|
if (bh)
|
||||||
ehci_work (ehci);
|
ehci_work (ehci);
|
||||||
spin_unlock (&ehci->lock);
|
spin_unlock (&ehci->lock);
|
||||||
if (pcd_status & STS_PCD)
|
if (pcd_status)
|
||||||
usb_hcd_poll_rh_status(hcd);
|
usb_hcd_poll_rh_status(hcd);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
@ -788,8 +773,14 @@ static int ehci_urb_enqueue (
|
|||||||
INIT_LIST_HEAD (&qtd_list);
|
INIT_LIST_HEAD (&qtd_list);
|
||||||
|
|
||||||
switch (usb_pipetype (urb->pipe)) {
|
switch (usb_pipetype (urb->pipe)) {
|
||||||
// case PIPE_CONTROL:
|
case PIPE_CONTROL:
|
||||||
// case PIPE_BULK:
|
/* qh_completions() code doesn't handle all the fault cases
|
||||||
|
* in multi-TD control transfers. Even 1KB is rare anyway.
|
||||||
|
*/
|
||||||
|
if (urb->transfer_buffer_length > (16 * 1024))
|
||||||
|
return -EMSGSIZE;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
/* case PIPE_BULK: */
|
||||||
default:
|
default:
|
||||||
if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
|
if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -28,7 +28,9 @@
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef CONFIG_USB_PERSIST
|
#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
static int ehci_hub_control(
|
static int ehci_hub_control(
|
||||||
struct usb_hcd *hcd,
|
struct usb_hcd *hcd,
|
||||||
@ -104,15 +106,6 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
|
|||||||
ehci->owned_ports = 0;
|
ehci->owned_ports = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_USB_PERSIST */
|
|
||||||
|
|
||||||
static inline void ehci_handover_companion_ports(struct ehci_hcd *ehci)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
|
|
||||||
static int ehci_bus_suspend (struct usb_hcd *hcd)
|
static int ehci_bus_suspend (struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
|
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
|
||||||
@ -158,10 +151,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* enable remote wakeup on all ports */
|
/* enable remote wakeup on all ports */
|
||||||
if (device_may_wakeup(&hcd->self.root_hub->dev))
|
if (hcd->self.root_hub->do_remote_wakeup)
|
||||||
t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
|
t2 |= PORT_WAKE_BITS;
|
||||||
else
|
else
|
||||||
t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
|
t2 &= ~PORT_WAKE_BITS;
|
||||||
|
|
||||||
if (t1 != t2) {
|
if (t1 != t2) {
|
||||||
ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
|
ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
|
||||||
@ -183,7 +176,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||||||
|
|
||||||
/* allow remote wakeup */
|
/* allow remote wakeup */
|
||||||
mask = INTR_MASK;
|
mask = INTR_MASK;
|
||||||
if (!device_may_wakeup(&hcd->self.root_hub->dev))
|
if (!hcd->self.root_hub->do_remote_wakeup)
|
||||||
mask &= ~STS_PCD;
|
mask &= ~STS_PCD;
|
||||||
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
|
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
|
||||||
ehci_readl(ehci, &ehci->regs->intr_enable);
|
ehci_readl(ehci, &ehci->regs->intr_enable);
|
||||||
@ -241,8 +234,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
|||||||
i = HCS_N_PORTS (ehci->hcs_params);
|
i = HCS_N_PORTS (ehci->hcs_params);
|
||||||
while (i--) {
|
while (i--) {
|
||||||
temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
|
temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
|
||||||
temp &= ~(PORT_RWC_BITS
|
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
|
||||||
| PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
|
|
||||||
if (test_bit(i, &ehci->bus_suspended) &&
|
if (test_bit(i, &ehci->bus_suspended) &&
|
||||||
(temp & PORT_SUSPEND)) {
|
(temp & PORT_SUSPEND)) {
|
||||||
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
|
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
|
||||||
@ -281,9 +273,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
|||||||
ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
|
ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
|
||||||
|
|
||||||
spin_unlock_irq (&ehci->lock);
|
spin_unlock_irq (&ehci->lock);
|
||||||
|
ehci_handover_companion_ports(ehci);
|
||||||
if (!power_okay)
|
|
||||||
ehci_handover_companion_ports(ehci);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,8 +535,6 @@ ehci_hub_descriptor (
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
|
|
||||||
|
|
||||||
static int ehci_hub_control (
|
static int ehci_hub_control (
|
||||||
struct usb_hcd *hcd,
|
struct usb_hcd *hcd,
|
||||||
u16 typeReq,
|
u16 typeReq,
|
||||||
@ -778,7 +766,7 @@ static int ehci_hub_control (
|
|||||||
if (temp & PORT_POWER)
|
if (temp & PORT_POWER)
|
||||||
status |= 1 << USB_PORT_FEAT_POWER;
|
status |= 1 << USB_PORT_FEAT_POWER;
|
||||||
|
|
||||||
#ifndef EHCI_VERBOSE_DEBUG
|
#ifndef VERBOSE_DEBUG
|
||||||
if (status & ~0xffff) /* only if wPortChange is interesting */
|
if (status & ~0xffff) /* only if wPortChange is interesting */
|
||||||
#endif
|
#endif
|
||||||
dbg_port (ehci, "GetStatus", wIndex + 1, temp);
|
dbg_port (ehci, "GetStatus", wIndex + 1, temp);
|
||||||
@ -812,8 +800,6 @@ static int ehci_hub_control (
|
|||||||
if ((temp & PORT_PE) == 0
|
if ((temp & PORT_PE) == 0
|
||||||
|| (temp & PORT_RESET) != 0)
|
|| (temp & PORT_RESET) != 0)
|
||||||
goto error;
|
goto error;
|
||||||
if (device_may_wakeup(&hcd->self.root_hub->dev))
|
|
||||||
temp |= PORT_WAKE_BITS;
|
|
||||||
ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
|
ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
|
||||||
break;
|
break;
|
||||||
case USB_PORT_FEAT_POWER:
|
case USB_PORT_FEAT_POWER:
|
||||||
|
@ -140,13 +140,12 @@ static int ixp4xx_ehci_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_ALIAS("ixp4xx-ehci");
|
MODULE_ALIAS("platform:ixp4xx-ehci");
|
||||||
|
|
||||||
static struct platform_driver ixp4xx_ehci_driver = {
|
static struct platform_driver ixp4xx_ehci_driver = {
|
||||||
.probe = ixp4xx_ehci_probe,
|
.probe = ixp4xx_ehci_probe,
|
||||||
.remove = ixp4xx_ehci_remove,
|
.remove = ixp4xx_ehci_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "ixp4xx-ehci",
|
.name = "ixp4xx-ehci",
|
||||||
.bus = &platform_bus_type
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -130,6 +130,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
|
|||||||
case PCI_VENDOR_ID_TDI:
|
case PCI_VENDOR_ID_TDI:
|
||||||
if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
|
if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
|
||||||
ehci->is_tdi_rh_tt = 1;
|
ehci->is_tdi_rh_tt = 1;
|
||||||
|
hcd->has_tt = 1;
|
||||||
tdi_reset(ehci);
|
tdi_reset(ehci);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -221,6 +222,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
|
|||||||
ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
|
ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ehci_port_power(ehci, 1);
|
||||||
retval = ehci_pci_reinit(ehci, pdev);
|
retval = ehci_pci_reinit(ehci, pdev);
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
@ -299,7 +301,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
|
|||||||
if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
|
if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
|
||||||
int mask = INTR_MASK;
|
int mask = INTR_MASK;
|
||||||
|
|
||||||
if (!device_may_wakeup(&hcd->self.root_hub->dev))
|
if (!hcd->self.root_hub->do_remote_wakeup)
|
||||||
mask &= ~STS_PCD;
|
mask &= ~STS_PCD;
|
||||||
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
|
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
|
||||||
ehci_readl(ehci, &ehci->regs->intr_enable);
|
ehci_readl(ehci, &ehci->regs->intr_enable);
|
||||||
@ -329,7 +331,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
|
|||||||
|
|
||||||
/* here we "know" root ports should always stay powered */
|
/* here we "know" root ports should always stay powered */
|
||||||
ehci_port_power(ehci, 1);
|
ehci_port_power(ehci, 1);
|
||||||
ehci_handover_companion_ports(ehci);
|
|
||||||
|
|
||||||
hcd->state = HC_STATE_SUSPENDED;
|
hcd->state = HC_STATE_SUSPENDED;
|
||||||
return 0;
|
return 0;
|
||||||
@ -353,8 +354,8 @@ static const struct hc_driver ehci_pci_hc_driver = {
|
|||||||
.reset = ehci_pci_setup,
|
.reset = ehci_pci_setup,
|
||||||
.start = ehci_run,
|
.start = ehci_run,
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.suspend = ehci_pci_suspend,
|
.pci_suspend = ehci_pci_suspend,
|
||||||
.resume = ehci_pci_resume,
|
.pci_resume = ehci_pci_resume,
|
||||||
#endif
|
#endif
|
||||||
.stop = ehci_stop,
|
.stop = ehci_stop,
|
||||||
.shutdown = ehci_shutdown,
|
.shutdown = ehci_shutdown,
|
||||||
|
@ -175,6 +175,7 @@ static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)
|
|||||||
if (usb_disabled())
|
if (usb_disabled())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* FIXME we only want one one probe() not two */
|
||||||
ret = usb_ehci_ppc_soc_probe(&ehci_ppc_soc_hc_driver, &hcd, pdev);
|
ret = usb_ehci_ppc_soc_probe(&ehci_ppc_soc_hc_driver, &hcd, pdev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -183,17 +184,17 @@ static int ehci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
/* FIXME we only want one one remove() not two */
|
||||||
usb_ehci_ppc_soc_remove(hcd, pdev);
|
usb_ehci_ppc_soc_remove(hcd, pdev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_ALIAS("ppc-soc-ehci");
|
MODULE_ALIAS("platform:ppc-soc-ehci");
|
||||||
static struct platform_driver ehci_ppc_soc_driver = {
|
static struct platform_driver ehci_ppc_soc_driver = {
|
||||||
.probe = ehci_hcd_ppc_soc_drv_probe,
|
.probe = ehci_hcd_ppc_soc_drv_probe,
|
||||||
.remove = ehci_hcd_ppc_soc_drv_remove,
|
.remove = ehci_hcd_ppc_soc_drv_remove,
|
||||||
.shutdown = usb_hcd_platform_shutdown,
|
.shutdown = usb_hcd_platform_shutdown,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "ppc-soc-ehci",
|
.name = "ppc-soc-ehci",
|
||||||
.bus = &platform_bus_type
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -125,7 +125,6 @@ static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
|
|||||||
goto fail_irq;
|
goto fail_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->core.power.power_state = PMSG_ON;
|
|
||||||
dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */
|
dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */
|
||||||
|
|
||||||
hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev->core.bus_id);
|
hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev->core.bus_id);
|
||||||
|
@ -242,7 +242,8 @@ __acquires(ehci->lock)
|
|||||||
if (unlikely(urb->unlinked)) {
|
if (unlikely(urb->unlinked)) {
|
||||||
COUNT(ehci->stats.unlink);
|
COUNT(ehci->stats.unlink);
|
||||||
} else {
|
} else {
|
||||||
if (likely(status == -EINPROGRESS))
|
/* report non-error and short read status as zero */
|
||||||
|
if (status == -EINPROGRESS || status == -EREMOTEIO)
|
||||||
status = 0;
|
status = 0;
|
||||||
COUNT(ehci->stats.complete);
|
COUNT(ehci->stats.complete);
|
||||||
}
|
}
|
||||||
@ -250,7 +251,7 @@ __acquires(ehci->lock)
|
|||||||
#ifdef EHCI_URB_TRACE
|
#ifdef EHCI_URB_TRACE
|
||||||
ehci_dbg (ehci,
|
ehci_dbg (ehci,
|
||||||
"%s %s urb %p ep%d%s status %d len %d/%d\n",
|
"%s %s urb %p ep%d%s status %d len %d/%d\n",
|
||||||
__FUNCTION__, urb->dev->devpath, urb,
|
__func__, urb->dev->devpath, urb,
|
||||||
usb_pipeendpoint (urb->pipe),
|
usb_pipeendpoint (urb->pipe),
|
||||||
usb_pipein (urb->pipe) ? "in" : "out",
|
usb_pipein (urb->pipe) ? "in" : "out",
|
||||||
status,
|
status,
|
||||||
@ -283,7 +284,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|||||||
int last_status = -EINPROGRESS;
|
int last_status = -EINPROGRESS;
|
||||||
int stopped;
|
int stopped;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
int do_status = 0;
|
|
||||||
u8 state;
|
u8 state;
|
||||||
u32 halt = HALT_BIT(ehci);
|
u32 halt = HALT_BIT(ehci);
|
||||||
|
|
||||||
@ -309,7 +309,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|||||||
struct ehci_qtd *qtd;
|
struct ehci_qtd *qtd;
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
u32 token = 0;
|
u32 token = 0;
|
||||||
int qtd_status;
|
|
||||||
|
|
||||||
qtd = list_entry (entry, struct ehci_qtd, qtd_list);
|
qtd = list_entry (entry, struct ehci_qtd, qtd_list);
|
||||||
urb = qtd->urb;
|
urb = qtd->urb;
|
||||||
@ -336,11 +335,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|||||||
/* always clean up qtds the hc de-activated */
|
/* always clean up qtds the hc de-activated */
|
||||||
if ((token & QTD_STS_ACTIVE) == 0) {
|
if ((token & QTD_STS_ACTIVE) == 0) {
|
||||||
|
|
||||||
|
/* on STALL, error, and short reads this urb must
|
||||||
|
* complete and all its qtds must be recycled.
|
||||||
|
*/
|
||||||
if ((token & QTD_STS_HALT) != 0) {
|
if ((token & QTD_STS_HALT) != 0) {
|
||||||
stopped = 1;
|
stopped = 1;
|
||||||
|
|
||||||
/* magic dummy for some short reads; qh won't advance.
|
/* magic dummy for some short reads; qh won't advance.
|
||||||
* that silicon quirk can kick in with this dummy too.
|
* that silicon quirk can kick in with this dummy too.
|
||||||
|
*
|
||||||
|
* other short reads won't stop the queue, including
|
||||||
|
* control transfers (status stage handles that) or
|
||||||
|
* most other single-qtd reads ... the queue stops if
|
||||||
|
* URB_SHORT_NOT_OK was set so the driver submitting
|
||||||
|
* the urbs could clean it up.
|
||||||
*/
|
*/
|
||||||
} else if (IS_SHORT_READ (token)
|
} else if (IS_SHORT_READ (token)
|
||||||
&& !(qtd->hw_alt_next
|
&& !(qtd->hw_alt_next
|
||||||
@ -354,28 +362,21 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|||||||
&& HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) {
|
&& HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* scan the whole queue for unlinks whenever it stops */
|
||||||
} else {
|
} else {
|
||||||
stopped = 1;
|
stopped = 1;
|
||||||
|
|
||||||
if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)))
|
/* cancel everything if we halt, suspend, etc */
|
||||||
|
if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))
|
||||||
last_status = -ESHUTDOWN;
|
last_status = -ESHUTDOWN;
|
||||||
|
|
||||||
/* ignore active urbs unless some previous qtd
|
/* this qtd is active; skip it unless a previous qtd
|
||||||
* for the urb faulted (including short read) or
|
* for its urb faulted, or its urb was canceled.
|
||||||
* its urb was canceled. we may patch qh or qtds.
|
|
||||||
*/
|
*/
|
||||||
if (likely(last_status == -EINPROGRESS &&
|
else if (last_status == -EINPROGRESS && !urb->unlinked)
|
||||||
!urb->unlinked))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* issue status after short control reads */
|
/* qh unlinked; token in overlay may be most current */
|
||||||
if (unlikely (do_status != 0)
|
|
||||||
&& QTD_PID (token) == 0 /* OUT */) {
|
|
||||||
do_status = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* token in overlay may be most current */
|
|
||||||
if (state == QH_STATE_IDLE
|
if (state == QH_STATE_IDLE
|
||||||
&& cpu_to_hc32(ehci, qtd->qtd_dma)
|
&& cpu_to_hc32(ehci, qtd->qtd_dma)
|
||||||
== qh->hw_current)
|
== qh->hw_current)
|
||||||
@ -392,21 +393,32 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove it from the queue */
|
/* unless we already know the urb's status, collect qtd status
|
||||||
qtd_status = qtd_copy_status(ehci, urb, qtd->length, token);
|
* and update count of bytes transferred. in common short read
|
||||||
if (unlikely(qtd_status == -EREMOTEIO)) {
|
* cases with only one data qtd (including control transfers),
|
||||||
do_status = (!urb->unlinked &&
|
* queue processing won't halt. but with two or more qtds (for
|
||||||
usb_pipecontrol(urb->pipe));
|
* example, with a 32 KB transfer), when the first qtd gets a
|
||||||
qtd_status = 0;
|
* short read the second must be removed by hand.
|
||||||
|
*/
|
||||||
|
if (last_status == -EINPROGRESS) {
|
||||||
|
last_status = qtd_copy_status(ehci, urb,
|
||||||
|
qtd->length, token);
|
||||||
|
if (last_status == -EREMOTEIO
|
||||||
|
&& (qtd->hw_alt_next
|
||||||
|
& EHCI_LIST_END(ehci)))
|
||||||
|
last_status = -EINPROGRESS;
|
||||||
}
|
}
|
||||||
if (likely(last_status == -EINPROGRESS))
|
|
||||||
last_status = qtd_status;
|
|
||||||
|
|
||||||
|
/* if we're removing something not at the queue head,
|
||||||
|
* patch the hardware queue pointer.
|
||||||
|
*/
|
||||||
if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
|
if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
|
||||||
last = list_entry (qtd->qtd_list.prev,
|
last = list_entry (qtd->qtd_list.prev,
|
||||||
struct ehci_qtd, qtd_list);
|
struct ehci_qtd, qtd_list);
|
||||||
last->hw_next = qtd->hw_next;
|
last->hw_next = qtd->hw_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove qtd; it's recycled after possible urb completion */
|
||||||
list_del (&qtd->qtd_list);
|
list_del (&qtd->qtd_list);
|
||||||
last = qtd;
|
last = qtd;
|
||||||
}
|
}
|
||||||
@ -431,7 +443,15 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|||||||
qh_refresh(ehci, qh);
|
qh_refresh(ehci, qh);
|
||||||
break;
|
break;
|
||||||
case QH_STATE_LINKED:
|
case QH_STATE_LINKED:
|
||||||
/* should be rare for periodic transfers,
|
/* We won't refresh a QH that's linked (after the HC
|
||||||
|
* stopped the queue). That avoids a race:
|
||||||
|
* - HC reads first part of QH;
|
||||||
|
* - CPU updates that first part and the token;
|
||||||
|
* - HC reads rest of that QH, including token
|
||||||
|
* Result: HC gets an inconsistent image, and then
|
||||||
|
* DMAs to/from the wrong memory (corrupting it).
|
||||||
|
*
|
||||||
|
* That should be rare for interrupt transfers,
|
||||||
* except maybe high bandwidth ...
|
* except maybe high bandwidth ...
|
||||||
*/
|
*/
|
||||||
if ((cpu_to_hc32(ehci, QH_SMASK)
|
if ((cpu_to_hc32(ehci, QH_SMASK)
|
||||||
@ -549,6 +569,12 @@ qh_urb_transaction (
|
|||||||
this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket);
|
this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket);
|
||||||
len -= this_qtd_len;
|
len -= this_qtd_len;
|
||||||
buf += this_qtd_len;
|
buf += this_qtd_len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* short reads advance to a "magic" dummy instead of the next
|
||||||
|
* qtd ... that forces the queue to stop, for manual cleanup.
|
||||||
|
* (this will usually be overridden later.)
|
||||||
|
*/
|
||||||
if (is_input)
|
if (is_input)
|
||||||
qtd->hw_alt_next = ehci->async->hw_alt_next;
|
qtd->hw_alt_next = ehci->async->hw_alt_next;
|
||||||
|
|
||||||
@ -568,8 +594,10 @@ qh_urb_transaction (
|
|||||||
list_add_tail (&qtd->qtd_list, head);
|
list_add_tail (&qtd->qtd_list, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unless the bulk/interrupt caller wants a chance to clean
|
/*
|
||||||
* up after short reads, hc should advance qh past this urb
|
* unless the caller requires manual cleanup after short reads,
|
||||||
|
* have the alt_next mechanism keep the queue running after the
|
||||||
|
* last data qtd (the only one, for control and most other cases).
|
||||||
*/
|
*/
|
||||||
if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
|
if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
|
||||||
|| usb_pipecontrol (urb->pipe)))
|
|| usb_pipecontrol (urb->pipe)))
|
||||||
@ -657,6 +685,14 @@ qh_make (
|
|||||||
type = usb_pipetype (urb->pipe);
|
type = usb_pipetype (urb->pipe);
|
||||||
maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input);
|
maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input);
|
||||||
|
|
||||||
|
/* 1024 byte maxpacket is a hardware ceiling. High bandwidth
|
||||||
|
* acts like up to 3KB, but is built from smaller packets.
|
||||||
|
*/
|
||||||
|
if (max_packet(maxp) > 1024) {
|
||||||
|
ehci_dbg(ehci, "bogus qh maxpacket %d\n", max_packet(maxp));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute interrupt scheduling parameters just once, and save.
|
/* Compute interrupt scheduling parameters just once, and save.
|
||||||
* - allowing for high bandwidth, how many nsec/uframe are used?
|
* - allowing for high bandwidth, how many nsec/uframe are used?
|
||||||
* - split transactions need a second CSPLIT uframe; same question
|
* - split transactions need a second CSPLIT uframe; same question
|
||||||
@ -757,7 +793,13 @@ qh_make (
|
|||||||
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||||
} else if (type == PIPE_BULK) {
|
} else if (type == PIPE_BULK) {
|
||||||
info1 |= (EHCI_TUNE_RL_HS << 28);
|
info1 |= (EHCI_TUNE_RL_HS << 28);
|
||||||
info1 |= 512 << 16; /* usb2 fixed maxpacket */
|
/* The USB spec says that high speed bulk endpoints
|
||||||
|
* always use 512 byte maxpacket. But some device
|
||||||
|
* vendors decided to ignore that, and MSFT is happy
|
||||||
|
* to help them do so. So now people expect to use
|
||||||
|
* such nonconformant devices with Linux too; sigh.
|
||||||
|
*/
|
||||||
|
info1 |= max_packet(maxp) << 16;
|
||||||
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||||
} else { /* PIPE_INTERRUPT */
|
} else { /* PIPE_INTERRUPT */
|
||||||
info1 |= max_packet (maxp) << 16;
|
info1 |= max_packet (maxp) << 16;
|
||||||
@ -932,7 +974,7 @@ submit_async (
|
|||||||
#ifdef EHCI_URB_TRACE
|
#ifdef EHCI_URB_TRACE
|
||||||
ehci_dbg (ehci,
|
ehci_dbg (ehci,
|
||||||
"%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
|
"%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
|
||||||
__FUNCTION__, urb->dev->devpath, urb,
|
__func__, urb->dev->devpath, urb,
|
||||||
epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
|
epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
|
||||||
urb->transfer_buffer_length,
|
urb->transfer_buffer_length,
|
||||||
qtd, urb->ep->hcpriv);
|
qtd, urb->ep->hcpriv);
|
||||||
|
@ -440,11 +440,10 @@ static int enable_periodic (struct ehci_hcd *ehci)
|
|||||||
/* did clearing PSE did take effect yet?
|
/* did clearing PSE did take effect yet?
|
||||||
* takes effect only at frame boundaries...
|
* takes effect only at frame boundaries...
|
||||||
*/
|
*/
|
||||||
status = handshake(ehci, &ehci->regs->status, STS_PSS, 0, 9 * 125);
|
status = handshake_on_error_set_halt(ehci, &ehci->regs->status,
|
||||||
if (status != 0) {
|
STS_PSS, 0, 9 * 125);
|
||||||
ehci_to_hcd(ehci)->state = HC_STATE_HALT;
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;
|
cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;
|
||||||
ehci_writel(ehci, cmd, &ehci->regs->command);
|
ehci_writel(ehci, cmd, &ehci->regs->command);
|
||||||
@ -465,11 +464,10 @@ static int disable_periodic (struct ehci_hcd *ehci)
|
|||||||
/* did setting PSE not take effect yet?
|
/* did setting PSE not take effect yet?
|
||||||
* takes effect only at frame boundaries...
|
* takes effect only at frame boundaries...
|
||||||
*/
|
*/
|
||||||
status = handshake(ehci, &ehci->regs->status, STS_PSS, STS_PSS, 9 * 125);
|
status = handshake_on_error_set_halt(ehci, &ehci->regs->status,
|
||||||
if (status != 0) {
|
STS_PSS, STS_PSS, 9 * 125);
|
||||||
ehci_to_hcd(ehci)->state = HC_STATE_HALT;
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE;
|
cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE;
|
||||||
ehci_writel(ehci, cmd, &ehci->regs->command);
|
ehci_writel(ehci, cmd, &ehci->regs->command);
|
||||||
@ -1183,21 +1181,18 @@ itd_urb_transaction (
|
|||||||
struct ehci_itd, itd_list);
|
struct ehci_itd, itd_list);
|
||||||
list_del (&itd->itd_list);
|
list_del (&itd->itd_list);
|
||||||
itd_dma = itd->itd_dma;
|
itd_dma = itd->itd_dma;
|
||||||
} else
|
} else {
|
||||||
itd = NULL;
|
|
||||||
|
|
||||||
if (!itd) {
|
|
||||||
spin_unlock_irqrestore (&ehci->lock, flags);
|
spin_unlock_irqrestore (&ehci->lock, flags);
|
||||||
itd = dma_pool_alloc (ehci->itd_pool, mem_flags,
|
itd = dma_pool_alloc (ehci->itd_pool, mem_flags,
|
||||||
&itd_dma);
|
&itd_dma);
|
||||||
spin_lock_irqsave (&ehci->lock, flags);
|
spin_lock_irqsave (&ehci->lock, flags);
|
||||||
|
if (!itd) {
|
||||||
|
iso_sched_free(stream, sched);
|
||||||
|
spin_unlock_irqrestore(&ehci->lock, flags);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely (NULL == itd)) {
|
|
||||||
iso_sched_free (stream, sched);
|
|
||||||
spin_unlock_irqrestore (&ehci->lock, flags);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memset (itd, 0, sizeof *itd);
|
memset (itd, 0, sizeof *itd);
|
||||||
itd->itd_dma = itd_dma;
|
itd->itd_dma = itd_dma;
|
||||||
list_add (&itd->itd_list, &sched->td_list);
|
list_add (&itd->itd_list, &sched->td_list);
|
||||||
@ -1682,7 +1677,7 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
|
|||||||
#ifdef EHCI_URB_TRACE
|
#ifdef EHCI_URB_TRACE
|
||||||
ehci_dbg (ehci,
|
ehci_dbg (ehci,
|
||||||
"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
|
"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
|
||||||
__FUNCTION__, urb->dev->devpath, urb,
|
__func__, urb->dev->devpath, urb,
|
||||||
usb_pipeendpoint (urb->pipe),
|
usb_pipeendpoint (urb->pipe),
|
||||||
usb_pipein (urb->pipe) ? "in" : "out",
|
usb_pipein (urb->pipe) ? "in" : "out",
|
||||||
urb->transfer_buffer_length,
|
urb->transfer_buffer_length,
|
||||||
@ -1816,21 +1811,18 @@ sitd_urb_transaction (
|
|||||||
struct ehci_sitd, sitd_list);
|
struct ehci_sitd, sitd_list);
|
||||||
list_del (&sitd->sitd_list);
|
list_del (&sitd->sitd_list);
|
||||||
sitd_dma = sitd->sitd_dma;
|
sitd_dma = sitd->sitd_dma;
|
||||||
} else
|
} else {
|
||||||
sitd = NULL;
|
|
||||||
|
|
||||||
if (!sitd) {
|
|
||||||
spin_unlock_irqrestore (&ehci->lock, flags);
|
spin_unlock_irqrestore (&ehci->lock, flags);
|
||||||
sitd = dma_pool_alloc (ehci->sitd_pool, mem_flags,
|
sitd = dma_pool_alloc (ehci->sitd_pool, mem_flags,
|
||||||
&sitd_dma);
|
&sitd_dma);
|
||||||
spin_lock_irqsave (&ehci->lock, flags);
|
spin_lock_irqsave (&ehci->lock, flags);
|
||||||
|
if (!sitd) {
|
||||||
|
iso_sched_free(stream, iso_sched);
|
||||||
|
spin_unlock_irqrestore(&ehci->lock, flags);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sitd) {
|
|
||||||
iso_sched_free (stream, iso_sched);
|
|
||||||
spin_unlock_irqrestore (&ehci->lock, flags);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memset (sitd, 0, sizeof *sitd);
|
memset (sitd, 0, sizeof *sitd);
|
||||||
sitd->sitd_dma = sitd_dma;
|
sitd->sitd_dma = sitd_dma;
|
||||||
list_add (&sitd->sitd_list, &iso_sched->td_list);
|
list_add (&sitd->sitd_list, &iso_sched->td_list);
|
||||||
|
@ -1400,7 +1400,7 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd)
|
|||||||
spin_unlock_irqrestore(&isp116x->lock, flags);
|
spin_unlock_irqrestore(&isp116x->lock, flags);
|
||||||
val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
|
val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
|
||||||
val |= HCCONTROL_USB_SUSPEND;
|
val |= HCCONTROL_USB_SUSPEND;
|
||||||
if (device_may_wakeup(&hcd->self.root_hub->dev))
|
if (hcd->self.root_hub->do_remote_wakeup)
|
||||||
val |= HCCONTROL_RWE;
|
val |= HCCONTROL_RWE;
|
||||||
/* Wait for usb transfers to finish */
|
/* Wait for usb transfers to finish */
|
||||||
msleep(2);
|
msleep(2);
|
||||||
@ -1442,11 +1442,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
|
|||||||
break;
|
break;
|
||||||
case HCCONTROL_USB_OPER:
|
case HCCONTROL_USB_OPER:
|
||||||
spin_unlock_irq(&isp116x->lock);
|
spin_unlock_irq(&isp116x->lock);
|
||||||
/* Without setting power_state here the
|
|
||||||
SUSPENDED state won't be removed from
|
|
||||||
sysfs/usbN/power.state as a response to remote
|
|
||||||
wakeup. Maybe in the future. */
|
|
||||||
hcd->self.root_hub->dev.power.power_state = PMSG_ON;
|
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* HCCONTROL_USB_RESET: this may happen, when during
|
/* HCCONTROL_USB_RESET: this may happen, when during
|
||||||
@ -1460,7 +1455,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
|
|||||||
if ((isp116x->rhdesca & RH_A_NDP) == 2)
|
if ((isp116x->rhdesca & RH_A_NDP) == 2)
|
||||||
isp116x_hub_control(hcd, SetPortFeature,
|
isp116x_hub_control(hcd, SetPortFeature,
|
||||||
USB_PORT_FEAT_POWER, 2, NULL, 0);
|
USB_PORT_FEAT_POWER, 2, NULL, 0);
|
||||||
hcd->self.root_hub->dev.power.power_state = PMSG_ON;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1486,8 +1480,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
|
|||||||
isp116x_write_reg32(isp116x, HCCONTROL,
|
isp116x_write_reg32(isp116x, HCCONTROL,
|
||||||
(val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
|
(val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
|
||||||
spin_unlock_irq(&isp116x->lock);
|
spin_unlock_irq(&isp116x->lock);
|
||||||
/* see analogous comment above */
|
|
||||||
hcd->self.root_hub->dev.power.power_state = PMSG_ON;
|
|
||||||
hcd->state = HC_STATE_RUNNING;
|
hcd->state = HC_STATE_RUNNING;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1663,7 +1655,6 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
|
|||||||
static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
|
static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
|
||||||
{
|
{
|
||||||
VDBG("%s: state %x\n", __func__, state.event);
|
VDBG("%s: state %x\n", __func__, state.event);
|
||||||
dev->dev.power.power_state = state;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1672,8 +1663,7 @@ static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
|
|||||||
*/
|
*/
|
||||||
static int isp116x_resume(struct platform_device *dev)
|
static int isp116x_resume(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
VDBG("%s: state %x\n", __func__, dev->power.power_state.event);
|
VDBG("%s\n", __func__);
|
||||||
dev->dev.power.power_state = PMSG_ON;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +261,6 @@ static const struct hc_driver ohci_at91_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
@ -348,6 +347,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
|
|||||||
if (!clocked)
|
if (!clocked)
|
||||||
at91_start_clock();
|
at91_start_clock();
|
||||||
|
|
||||||
|
ohci_finish_controller_resume(hcd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -288,7 +288,6 @@ static const struct hc_driver ohci_au1xxx_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -655,7 +655,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
|
|||||||
hcd->product_desc,
|
hcd->product_desc,
|
||||||
hcd_name);
|
hcd_name);
|
||||||
|
|
||||||
if (bus->controller->power.power_state.event) {
|
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
|
||||||
size -= scnprintf (next, size,
|
size -= scnprintf (next, size,
|
||||||
"SUSPENDED (no register access)\n");
|
"SUSPENDED (no register access)\n");
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -135,7 +135,6 @@ static struct hc_driver ohci_ep93xx_hc_driver = {
|
|||||||
.get_frame_number = ohci_get_frame,
|
.get_frame_number = ohci_get_frame,
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
@ -177,7 +176,6 @@ static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_
|
|||||||
|
|
||||||
ep93xx_stop_hc(&pdev->dev);
|
ep93xx_stop_hc(&pdev->dev);
|
||||||
hcd->state = HC_STATE_SUSPENDED;
|
hcd->state = HC_STATE_SUSPENDED;
|
||||||
pdev->dev.power.power_state = PMSG_SUSPEND;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -193,9 +191,8 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
|
|||||||
ohci->next_statechange = jiffies;
|
ohci->next_statechange = jiffies;
|
||||||
|
|
||||||
ep93xx_start_hc(&pdev->dev);
|
ep93xx_start_hc(&pdev->dev);
|
||||||
pdev->dev.power.power_state = PMSG_ON;
|
|
||||||
usb_hcd_resume_root_hub(hcd);
|
|
||||||
|
|
||||||
|
ohci_finish_controller_resume(hcd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,18 +36,6 @@
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* hcd->hub_irq_enable() */
|
|
||||||
static void ohci_rhsc_enable (struct usb_hcd *hcd)
|
|
||||||
{
|
|
||||||
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
|
||||||
|
|
||||||
spin_lock_irq(&ohci->lock);
|
|
||||||
if (!ohci->autostop)
|
|
||||||
del_timer(&hcd->rh_timer); /* Prevent next poll */
|
|
||||||
ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
|
|
||||||
spin_unlock_irq(&ohci->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OHCI_SCHED_ENABLES \
|
#define OHCI_SCHED_ENABLES \
|
||||||
(OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
|
(OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
|
||||||
|
|
||||||
@ -103,11 +91,11 @@ __acquires(ohci->lock)
|
|||||||
finish_unlinks (ohci, ohci_frame_no(ohci));
|
finish_unlinks (ohci, ohci_frame_no(ohci));
|
||||||
|
|
||||||
/* maybe resume can wake root hub */
|
/* maybe resume can wake root hub */
|
||||||
if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev) ||
|
if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) {
|
||||||
autostop)
|
|
||||||
ohci->hc_control |= OHCI_CTRL_RWE;
|
ohci->hc_control |= OHCI_CTRL_RWE;
|
||||||
else {
|
} else {
|
||||||
ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable);
|
ohci_writel(ohci, OHCI_INTR_RHSC | OHCI_INTR_RD,
|
||||||
|
&ohci->regs->intrdisable);
|
||||||
ohci->hc_control &= ~OHCI_CTRL_RWE;
|
ohci->hc_control &= ~OHCI_CTRL_RWE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,23 +314,76 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Carry out the final steps of resuming the controller device */
|
||||||
|
static void ohci_finish_controller_resume(struct usb_hcd *hcd)
|
||||||
|
{
|
||||||
|
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||||
|
int port;
|
||||||
|
bool need_reinit = false;
|
||||||
|
|
||||||
|
/* See if the controller is already running or has been reset */
|
||||||
|
ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
|
||||||
|
if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
|
||||||
|
need_reinit = true;
|
||||||
|
} else {
|
||||||
|
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
|
||||||
|
case OHCI_USB_OPER:
|
||||||
|
case OHCI_USB_RESET:
|
||||||
|
need_reinit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If needed, reinitialize and suspend the root hub */
|
||||||
|
if (need_reinit) {
|
||||||
|
spin_lock_irq(&ohci->lock);
|
||||||
|
hcd->state = HC_STATE_RESUMING;
|
||||||
|
ohci_rh_resume(ohci);
|
||||||
|
hcd->state = HC_STATE_QUIESCING;
|
||||||
|
ohci_rh_suspend(ohci, 0);
|
||||||
|
hcd->state = HC_STATE_SUSPENDED;
|
||||||
|
spin_unlock_irq(&ohci->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Normally just turn on port power and enable interrupts */
|
||||||
|
else {
|
||||||
|
ohci_dbg(ohci, "powerup ports\n");
|
||||||
|
for (port = 0; port < ohci->num_ports; port++)
|
||||||
|
ohci_writel(ohci, RH_PS_PPS,
|
||||||
|
&ohci->regs->roothub.portstatus[port]);
|
||||||
|
|
||||||
|
ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
|
||||||
|
ohci_readl(ohci, &ohci->regs->intrenable);
|
||||||
|
msleep(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Carry out polling-, autostop-, and autoresume-related state changes */
|
/* Carry out polling-, autostop-, and autoresume-related state changes */
|
||||||
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
||||||
int any_connected)
|
int any_connected)
|
||||||
{
|
{
|
||||||
int poll_rh = 1;
|
int poll_rh = 1;
|
||||||
|
int rhsc;
|
||||||
|
|
||||||
|
rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC;
|
||||||
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
|
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
|
||||||
|
|
||||||
case OHCI_USB_OPER:
|
case OHCI_USB_OPER:
|
||||||
/* keep on polling until we know a device is connected
|
/* If no status changes are pending, enable status-change
|
||||||
* and RHSC is enabled */
|
* interrupts.
|
||||||
|
*/
|
||||||
|
if (!rhsc && !changed) {
|
||||||
|
rhsc = OHCI_INTR_RHSC;
|
||||||
|
ohci_writel(ohci, rhsc, &ohci->regs->intrenable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep on polling until we know a device is connected
|
||||||
|
* and RHSC is enabled, or until we autostop.
|
||||||
|
*/
|
||||||
if (!ohci->autostop) {
|
if (!ohci->autostop) {
|
||||||
if (any_connected ||
|
if (any_connected ||
|
||||||
!device_may_wakeup(&ohci_to_hcd(ohci)
|
!device_may_wakeup(&ohci_to_hcd(ohci)
|
||||||
->self.root_hub->dev)) {
|
->self.root_hub->dev)) {
|
||||||
if (ohci_readl(ohci, &ohci->regs->intrenable) &
|
if (rhsc)
|
||||||
OHCI_INTR_RHSC)
|
|
||||||
poll_rh = 0;
|
poll_rh = 0;
|
||||||
} else {
|
} else {
|
||||||
ohci->autostop = 1;
|
ohci->autostop = 1;
|
||||||
@ -355,12 +396,13 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
|||||||
ohci->autostop = 0;
|
ohci->autostop = 0;
|
||||||
ohci->next_statechange = jiffies +
|
ohci->next_statechange = jiffies +
|
||||||
STATECHANGE_DELAY;
|
STATECHANGE_DELAY;
|
||||||
} else if (time_after_eq(jiffies,
|
} else if (rhsc && time_after_eq(jiffies,
|
||||||
ohci->next_statechange)
|
ohci->next_statechange)
|
||||||
&& !ohci->ed_rm_list
|
&& !ohci->ed_rm_list
|
||||||
&& !(ohci->hc_control &
|
&& !(ohci->hc_control &
|
||||||
OHCI_SCHED_ENABLES)) {
|
OHCI_SCHED_ENABLES)) {
|
||||||
ohci_rh_suspend(ohci, 1);
|
ohci_rh_suspend(ohci, 1);
|
||||||
|
poll_rh = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -374,6 +416,12 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
|||||||
else
|
else
|
||||||
usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
|
usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
|
||||||
} else {
|
} else {
|
||||||
|
if (!rhsc && (ohci->autostop ||
|
||||||
|
ohci_to_hcd(ohci)->self.root_hub->
|
||||||
|
do_remote_wakeup))
|
||||||
|
ohci_writel(ohci, OHCI_INTR_RHSC,
|
||||||
|
&ohci->regs->intrenable);
|
||||||
|
|
||||||
/* everything is idle, no need for polling */
|
/* everything is idle, no need for polling */
|
||||||
poll_rh = 0;
|
poll_rh = 0;
|
||||||
}
|
}
|
||||||
@ -395,12 +443,16 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci)
|
|||||||
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
|
||||||
int any_connected)
|
int any_connected)
|
||||||
{
|
{
|
||||||
int poll_rh = 1;
|
/* If RHSC is enabled, don't poll */
|
||||||
|
|
||||||
/* keep on polling until RHSC is enabled */
|
|
||||||
if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
|
if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
|
||||||
poll_rh = 0;
|
return 0;
|
||||||
return poll_rh;
|
|
||||||
|
/* If no status changes are pending, enable status-change interrupts */
|
||||||
|
if (!changed) {
|
||||||
|
ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
@ -564,14 +616,18 @@ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
|
|||||||
u32 temp;
|
u32 temp;
|
||||||
u16 now = ohci_readl(ohci, &ohci->regs->fmnumber);
|
u16 now = ohci_readl(ohci, &ohci->regs->fmnumber);
|
||||||
u16 reset_done = now + PORT_RESET_MSEC;
|
u16 reset_done = now + PORT_RESET_MSEC;
|
||||||
|
int limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC);
|
||||||
|
|
||||||
/* build a "continuous enough" reset signal, with up to
|
/* build a "continuous enough" reset signal, with up to
|
||||||
* 3msec gap between pulses. scheduler HZ==100 must work;
|
* 3msec gap between pulses. scheduler HZ==100 must work;
|
||||||
* this might need to be deadline-scheduled.
|
* this might need to be deadline-scheduled.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
|
int limit_2;
|
||||||
|
|
||||||
/* spin until any current reset finishes */
|
/* spin until any current reset finishes */
|
||||||
for (;;) {
|
limit_2 = PORT_RESET_HW_MSEC * 2;
|
||||||
|
while (--limit_2 >= 0) {
|
||||||
temp = ohci_readl (ohci, portstat);
|
temp = ohci_readl (ohci, portstat);
|
||||||
/* handle e.g. CardBus eject */
|
/* handle e.g. CardBus eject */
|
||||||
if (temp == ~(u32)0)
|
if (temp == ~(u32)0)
|
||||||
@ -581,6 +637,17 @@ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
|
|||||||
udelay (500);
|
udelay (500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* timeout (a hardware error) has been observed when
|
||||||
|
* EHCI sets CF while this driver is resetting a port;
|
||||||
|
* presumably other disconnect paths might do it too.
|
||||||
|
*/
|
||||||
|
if (limit_2 < 0) {
|
||||||
|
ohci_dbg(ohci,
|
||||||
|
"port[%d] reset timeout, stat %08x\n",
|
||||||
|
port, temp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(temp & RH_PS_CCS))
|
if (!(temp & RH_PS_CCS))
|
||||||
break;
|
break;
|
||||||
if (temp & RH_PS_PRSC)
|
if (temp & RH_PS_PRSC)
|
||||||
@ -590,8 +657,11 @@ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
|
|||||||
ohci_writel (ohci, RH_PS_PRS, portstat);
|
ohci_writel (ohci, RH_PS_PRS, portstat);
|
||||||
msleep(PORT_RESET_HW_MSEC);
|
msleep(PORT_RESET_HW_MSEC);
|
||||||
now = ohci_readl(ohci, &ohci->regs->fmnumber);
|
now = ohci_readl(ohci, &ohci->regs->fmnumber);
|
||||||
} while (tick_before(now, reset_done));
|
} while (tick_before(now, reset_done) && --limit_1 >= 0);
|
||||||
/* caller synchronizes using PRSC */
|
|
||||||
|
/* caller synchronizes using PRSC ... and handles PRS
|
||||||
|
* still being set when this returns.
|
||||||
|
*/
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,6 @@ static const struct hc_driver ohci_lh7a404_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -466,7 +466,6 @@ static const struct hc_driver ohci_omap_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
@ -505,21 +504,20 @@ static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message)
|
|||||||
|
|
||||||
omap_ohci_clock_power(0);
|
omap_ohci_clock_power(0);
|
||||||
ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
|
ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
|
||||||
dev->dev.power.power_state = PMSG_SUSPEND;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ohci_omap_resume(struct platform_device *dev)
|
static int ohci_omap_resume(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev));
|
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||||
|
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||||
|
|
||||||
if (time_before(jiffies, ohci->next_statechange))
|
if (time_before(jiffies, ohci->next_statechange))
|
||||||
msleep(5);
|
msleep(5);
|
||||||
ohci->next_statechange = jiffies;
|
ohci->next_statechange = jiffies;
|
||||||
|
|
||||||
omap_ohci_clock_power(1);
|
omap_ohci_clock_power(1);
|
||||||
dev->dev.power.power_state = PMSG_ON;
|
ohci_finish_controller_resume(hcd);
|
||||||
usb_hcd_resume_root_hub(platform_get_drvdata(dev));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,42 +238,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \
|
|
||||||
defined(CONFIG_USB_EHCI_HCD_MODULE))
|
|
||||||
|
|
||||||
/* Following a power loss, we must prepare to regain control of the ports
|
|
||||||
* we used to own. This means turning on the port power before ehci-hcd
|
|
||||||
* tries to switch ownership.
|
|
||||||
*
|
|
||||||
* This isn't a 100% perfect solution. On most systems the OHCI controllers
|
|
||||||
* lie at lower PCI addresses than the EHCI controller, so they will be
|
|
||||||
* discovered (and hence resumed) first. But there is no guarantee things
|
|
||||||
* will always work this way. If the EHCI controller is resumed first and
|
|
||||||
* the OHCI ports are unpowered, then the handover will fail.
|
|
||||||
*/
|
|
||||||
static void prepare_for_handover(struct usb_hcd *hcd)
|
|
||||||
{
|
|
||||||
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
|
||||||
int port;
|
|
||||||
|
|
||||||
/* Here we "know" root ports should always stay powered */
|
|
||||||
ohci_dbg(ohci, "powerup ports\n");
|
|
||||||
for (port = 0; port < ohci->num_ports; port++)
|
|
||||||
ohci_writel(ohci, RH_PS_PPS,
|
|
||||||
&ohci->regs->roothub.portstatus[port]);
|
|
||||||
|
|
||||||
/* Flush those writes */
|
|
||||||
ohci_readl(ohci, &ohci->regs->control);
|
|
||||||
msleep(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline void prepare_for_handover(struct usb_hcd *hcd)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#endif /* CONFIG_USB_PERSIST etc. */
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
|
static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
|
||||||
@ -313,10 +277,7 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
|
|||||||
static int ohci_pci_resume (struct usb_hcd *hcd)
|
static int ohci_pci_resume (struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
||||||
|
ohci_finish_controller_resume(hcd);
|
||||||
/* FIXME: we should try to detect loss of VBUS power here */
|
|
||||||
prepare_for_handover(hcd);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,9 +306,8 @@ static const struct hc_driver ohci_pci_hc_driver = {
|
|||||||
.shutdown = ohci_shutdown,
|
.shutdown = ohci_shutdown,
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
/* these suspend/resume entries are for upstream PCI glue ONLY */
|
.pci_suspend = ohci_pci_suspend,
|
||||||
.suspend = ohci_pci_suspend,
|
.pci_resume = ohci_pci_resume,
|
||||||
.resume = ohci_pci_resume,
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -367,7 +327,6 @@ static const struct hc_driver ohci_pci_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -280,7 +280,6 @@ static const struct hc_driver ohci_pnx4008_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -201,7 +201,6 @@ static const struct hc_driver ohci_pnx8550_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -72,7 +72,6 @@ static const struct hc_driver ohci_ppc_of_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -172,7 +172,6 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -68,7 +68,6 @@ static const struct hc_driver ps3_ohci_hc_driver = {
|
|||||||
.get_frame_number = ohci_get_frame,
|
.get_frame_number = ohci_get_frame,
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
.start_port_reset = ohci_start_port_reset,
|
.start_port_reset = ohci_start_port_reset,
|
||||||
#if defined(CONFIG_PM)
|
#if defined(CONFIG_PM)
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
@ -127,7 +126,6 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
|
|||||||
goto fail_irq;
|
goto fail_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->core.power.power_state = PMSG_ON;
|
|
||||||
dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */
|
dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */
|
||||||
|
|
||||||
hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev->core.bus_id);
|
hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev->core.bus_id);
|
||||||
|
@ -298,7 +298,6 @@ static const struct hc_driver ohci_pxa27x_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
@ -339,7 +338,6 @@ static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_
|
|||||||
|
|
||||||
pxa27x_stop_hc(&pdev->dev);
|
pxa27x_stop_hc(&pdev->dev);
|
||||||
hcd->state = HC_STATE_SUSPENDED;
|
hcd->state = HC_STATE_SUSPENDED;
|
||||||
pdev->dev.power.power_state = PMSG_SUSPEND;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -357,9 +355,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
|
|||||||
if ((status = pxa27x_start_hc(&pdev->dev)) < 0)
|
if ((status = pxa27x_start_hc(&pdev->dev)) < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
pdev->dev.power.power_state = PMSG_ON;
|
ohci_finish_controller_resume(hcd);
|
||||||
usb_hcd_resume_root_hub(hcd);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -466,7 +466,6 @@ static const struct hc_driver ohci_s3c2410_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_s3c2410_hub_status_data,
|
.hub_status_data = ohci_s3c2410_hub_status_data,
|
||||||
.hub_control = ohci_s3c2410_hub_control,
|
.hub_control = ohci_s3c2410_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -231,7 +231,6 @@ static const struct hc_driver ohci_sa1111_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -68,7 +68,6 @@ static const struct hc_driver ohci_sh_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
|
@ -75,7 +75,6 @@ static const struct hc_driver ohci_sm501_hc_driver = {
|
|||||||
*/
|
*/
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
@ -199,7 +198,8 @@ static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev)
|
|||||||
usb_put_hcd(hcd);
|
usb_put_hcd(hcd);
|
||||||
dma_release_declared_memory(&pdev->dev);
|
dma_release_declared_memory(&pdev->dev);
|
||||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||||
release_mem_region(mem->start, mem->end - mem->start + 1);
|
if (mem)
|
||||||
|
release_mem_region(mem->start, mem->end - mem->start + 1);
|
||||||
|
|
||||||
/* mask interrupts and disable power */
|
/* mask interrupts and disable power */
|
||||||
|
|
||||||
@ -224,24 +224,26 @@ static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg)
|
|||||||
|
|
||||||
sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0);
|
sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0);
|
||||||
ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
|
ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
|
||||||
dev->power.power_state = PMSG_SUSPEND;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ohci_sm501_resume(struct platform_device *pdev)
|
static int ohci_sm501_resume(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(pdev));
|
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||||
|
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||||
|
|
||||||
if (time_before(jiffies, ohci->next_statechange))
|
if (time_before(jiffies, ohci->next_statechange))
|
||||||
msleep(5);
|
msleep(5);
|
||||||
ohci->next_statechange = jiffies;
|
ohci->next_statechange = jiffies;
|
||||||
|
|
||||||
sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1);
|
sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1);
|
||||||
dev->power.power_state = PMSG_ON;
|
ohci_finish_controller_resume(hcd);
|
||||||
usb_hcd_resume_root_hub(platform_get_drvdata(pdev));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#define ohci_sm501_suspend NULL
|
||||||
|
#define ohci_sm501_resume NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -253,10 +255,8 @@ static struct platform_driver ohci_hcd_sm501_driver = {
|
|||||||
.probe = ohci_hcd_sm501_drv_probe,
|
.probe = ohci_hcd_sm501_drv_probe,
|
||||||
.remove = ohci_hcd_sm501_drv_remove,
|
.remove = ohci_hcd_sm501_drv_remove,
|
||||||
.shutdown = usb_hcd_platform_shutdown,
|
.shutdown = usb_hcd_platform_shutdown,
|
||||||
#ifdef CONFIG_PM
|
|
||||||
.suspend = ohci_sm501_suspend,
|
.suspend = ohci_sm501_suspend,
|
||||||
.resume = ohci_sm501_resume,
|
.resume = ohci_sm501_resume,
|
||||||
#endif
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "sm501-usb",
|
.name = "sm501-usb",
|
||||||
|
@ -60,36 +60,6 @@ static int ssb_ohci_start(struct usb_hcd *hcd)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
static int ssb_ohci_hcd_suspend(struct usb_hcd *hcd, pm_message_t message)
|
|
||||||
{
|
|
||||||
struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
|
|
||||||
struct ohci_hcd *ohci = &ohcidev->ohci;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ohci->lock, flags);
|
|
||||||
|
|
||||||
ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
|
|
||||||
ohci_readl(ohci, &ohci->regs->intrdisable); /* commit write */
|
|
||||||
|
|
||||||
/* make sure snapshot being resumed re-enumerates everything */
|
|
||||||
if (message.event == PM_EVENT_PRETHAW)
|
|
||||||
ohci_usb_reset(ohci);
|
|
||||||
|
|
||||||
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ohci->lock, flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ssb_ohci_hcd_resume(struct usb_hcd *hcd)
|
|
||||||
{
|
|
||||||
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
|
||||||
usb_hcd_resume_root_hub(hcd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_PM */
|
|
||||||
|
|
||||||
static const struct hc_driver ssb_ohci_hc_driver = {
|
static const struct hc_driver ssb_ohci_hc_driver = {
|
||||||
.description = "ssb-usb-ohci",
|
.description = "ssb-usb-ohci",
|
||||||
.product_desc = "SSB OHCI Controller",
|
.product_desc = "SSB OHCI Controller",
|
||||||
@ -103,11 +73,6 @@ static const struct hc_driver ssb_ohci_hc_driver = {
|
|||||||
.stop = ohci_stop,
|
.stop = ohci_stop,
|
||||||
.shutdown = ohci_shutdown,
|
.shutdown = ohci_shutdown,
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
.suspend = ssb_ohci_hcd_suspend,
|
|
||||||
.resume = ssb_ohci_hcd_resume,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.urb_enqueue = ohci_urb_enqueue,
|
.urb_enqueue = ohci_urb_enqueue,
|
||||||
.urb_dequeue = ohci_urb_dequeue,
|
.urb_dequeue = ohci_urb_dequeue,
|
||||||
.endpoint_disable = ohci_endpoint_disable,
|
.endpoint_disable = ohci_endpoint_disable,
|
||||||
@ -116,7 +81,6 @@ static const struct hc_driver ssb_ohci_hc_driver = {
|
|||||||
|
|
||||||
.hub_status_data = ohci_hub_status_data,
|
.hub_status_data = ohci_hub_status_data,
|
||||||
.hub_control = ohci_hub_control,
|
.hub_control = ohci_hub_control,
|
||||||
.hub_irq_enable = ohci_rhsc_enable,
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.bus_suspend = ohci_bus_suspend,
|
.bus_suspend = ohci_bus_suspend,
|
||||||
.bus_resume = ohci_bus_resume,
|
.bus_resume = ohci_bus_resume,
|
||||||
@ -224,6 +188,7 @@ static int ssb_ohci_resume(struct ssb_device *dev)
|
|||||||
|
|
||||||
ssb_device_enable(dev, ohcidev->enable_flags);
|
ssb_device_enable(dev, ohcidev->enable_flags);
|
||||||
|
|
||||||
|
ohci_finish_controller_resume(hcd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
|
|||||||
pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup);
|
pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup);
|
||||||
if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
|
if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
|
||||||
dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n",
|
dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n",
|
||||||
__FUNCTION__, legsup);
|
__func__, legsup);
|
||||||
goto reset_needed;
|
goto reset_needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,14 +114,14 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
|
|||||||
if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) ||
|
if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) ||
|
||||||
!(cmd & UHCI_USBCMD_EGSM)) {
|
!(cmd & UHCI_USBCMD_EGSM)) {
|
||||||
dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n",
|
dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n",
|
||||||
__FUNCTION__, cmd);
|
__func__, cmd);
|
||||||
goto reset_needed;
|
goto reset_needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
intr = inw(base + UHCI_USBINTR);
|
intr = inw(base + UHCI_USBINTR);
|
||||||
if (intr & (~UHCI_USBINTR_RESUME)) {
|
if (intr & (~UHCI_USBINTR_RESUME)) {
|
||||||
dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n",
|
dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n",
|
||||||
__FUNCTION__, intr);
|
__func__, intr);
|
||||||
goto reset_needed;
|
goto reset_needed;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -46,15 +46,17 @@ MODULE_LICENSE("GPL");
|
|||||||
MODULE_AUTHOR("Yoshihiro Shimoda");
|
MODULE_AUTHOR("Yoshihiro Shimoda");
|
||||||
MODULE_ALIAS("platform:r8a66597_hcd");
|
MODULE_ALIAS("platform:r8a66597_hcd");
|
||||||
|
|
||||||
#define DRIVER_VERSION "29 May 2007"
|
#define DRIVER_VERSION "10 Apr 2008"
|
||||||
|
|
||||||
static const char hcd_name[] = "r8a66597_hcd";
|
static const char hcd_name[] = "r8a66597_hcd";
|
||||||
|
|
||||||
/* module parameters */
|
/* module parameters */
|
||||||
|
#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||||
static unsigned short clock = XTAL12;
|
static unsigned short clock = XTAL12;
|
||||||
module_param(clock, ushort, 0644);
|
module_param(clock, ushort, 0644);
|
||||||
MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
|
MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
|
||||||
"(default=0)");
|
"(default=0)");
|
||||||
|
#endif
|
||||||
|
|
||||||
static unsigned short vif = LDRV;
|
static unsigned short vif = LDRV;
|
||||||
module_param(vif, ushort, 0644);
|
module_param(vif, ushort, 0644);
|
||||||
@ -106,11 +108,22 @@ static void set_devadd_reg(struct r8a66597 *r8a66597, u8 r8a66597_address,
|
|||||||
r8a66597_write(r8a66597, val, devadd_reg);
|
r8a66597_write(r8a66597, val, devadd_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enable_controller(struct r8a66597 *r8a66597)
|
static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
|
||||||
{
|
{
|
||||||
u16 tmp;
|
u16 tmp;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||||
|
do {
|
||||||
|
r8a66597_write(r8a66597, SCKE, SYSCFG0);
|
||||||
|
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||||
|
if (i++ > 1000) {
|
||||||
|
err("register access fail.");
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
} while ((tmp & SCKE) != SCKE);
|
||||||
|
r8a66597_write(r8a66597, 0x04, 0x02);
|
||||||
|
#else
|
||||||
do {
|
do {
|
||||||
r8a66597_write(r8a66597, USBE, SYSCFG0);
|
r8a66597_write(r8a66597, USBE, SYSCFG0);
|
||||||
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
tmp = r8a66597_read(r8a66597, SYSCFG0);
|
||||||
@ -132,13 +145,63 @@ static int enable_controller(struct r8a66597 *r8a66597)
|
|||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
} while ((tmp & SCKE) != SCKE);
|
} while ((tmp & SCKE) != SCKE);
|
||||||
|
#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
|
||||||
|
|
||||||
r8a66597_bset(r8a66597, DCFM | DRPD, SYSCFG0);
|
return 0;
|
||||||
r8a66597_bset(r8a66597, DRPD, SYSCFG1);
|
}
|
||||||
|
|
||||||
|
static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
|
||||||
|
{
|
||||||
|
r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
|
||||||
|
udelay(1);
|
||||||
|
#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||||
|
r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
|
||||||
|
r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
|
||||||
|
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
|
||||||
|
{
|
||||||
|
u16 val;
|
||||||
|
|
||||||
|
val = port ? DRPD : DCFM | DRPD;
|
||||||
|
r8a66597_bset(r8a66597, val, get_syscfg_reg(port));
|
||||||
|
r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
|
||||||
|
|
||||||
|
r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port));
|
||||||
|
r8a66597_bclr(r8a66597, DTCHE, get_intenb_reg(port));
|
||||||
|
r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port)
|
||||||
|
{
|
||||||
|
u16 val, tmp;
|
||||||
|
|
||||||
|
r8a66597_write(r8a66597, 0, get_intenb_reg(port));
|
||||||
|
r8a66597_write(r8a66597, 0, get_intsts_reg(port));
|
||||||
|
|
||||||
|
r8a66597_port_power(r8a66597, port, 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS;
|
||||||
|
udelay(640);
|
||||||
|
} while (tmp == EDGESTS);
|
||||||
|
|
||||||
|
val = port ? DRPD : DCFM | DRPD;
|
||||||
|
r8a66597_bclr(r8a66597, val, get_syscfg_reg(port));
|
||||||
|
r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int enable_controller(struct r8a66597 *r8a66597)
|
||||||
|
{
|
||||||
|
int ret, port;
|
||||||
|
|
||||||
|
ret = r8a66597_clock_enable(r8a66597);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
r8a66597_bset(r8a66597, vif & LDRV, PINCFG);
|
r8a66597_bset(r8a66597, vif & LDRV, PINCFG);
|
||||||
r8a66597_bset(r8a66597, HSE, SYSCFG0);
|
|
||||||
r8a66597_bset(r8a66597, HSE, SYSCFG1);
|
|
||||||
r8a66597_bset(r8a66597, USBE, SYSCFG0);
|
r8a66597_bset(r8a66597, USBE, SYSCFG0);
|
||||||
|
|
||||||
r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
|
r8a66597_bset(r8a66597, BEMPE | NRDYE | BRDYE, INTENB0);
|
||||||
@ -146,53 +209,30 @@ static int enable_controller(struct r8a66597 *r8a66597)
|
|||||||
r8a66597_bset(r8a66597, BRDY0, BRDYENB);
|
r8a66597_bset(r8a66597, BRDY0, BRDYENB);
|
||||||
r8a66597_bset(r8a66597, BEMP0, BEMPENB);
|
r8a66597_bset(r8a66597, BEMP0, BEMPENB);
|
||||||
|
|
||||||
r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA0CFG);
|
|
||||||
r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, DMA1CFG);
|
|
||||||
|
|
||||||
r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL);
|
r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL);
|
||||||
r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL);
|
r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL);
|
||||||
r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL);
|
r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL);
|
||||||
|
|
||||||
r8a66597_bset(r8a66597, TRNENSEL, SOFCFG);
|
r8a66597_bset(r8a66597, TRNENSEL, SOFCFG);
|
||||||
|
|
||||||
r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
|
r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
|
||||||
r8a66597_bclr(r8a66597, DTCHE, INTENB1);
|
|
||||||
r8a66597_bset(r8a66597, ATTCHE, INTENB1);
|
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
|
||||||
r8a66597_bclr(r8a66597, DTCHE, INTENB2);
|
r8a66597_enable_port(r8a66597, port);
|
||||||
r8a66597_bset(r8a66597, ATTCHE, INTENB2);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disable_controller(struct r8a66597 *r8a66597)
|
static void disable_controller(struct r8a66597 *r8a66597)
|
||||||
{
|
{
|
||||||
u16 tmp;
|
int port;
|
||||||
|
|
||||||
r8a66597_write(r8a66597, 0, INTENB0);
|
r8a66597_write(r8a66597, 0, INTENB0);
|
||||||
r8a66597_write(r8a66597, 0, INTENB1);
|
|
||||||
r8a66597_write(r8a66597, 0, INTENB2);
|
|
||||||
r8a66597_write(r8a66597, 0, INTSTS0);
|
r8a66597_write(r8a66597, 0, INTSTS0);
|
||||||
r8a66597_write(r8a66597, 0, INTSTS1);
|
|
||||||
r8a66597_write(r8a66597, 0, INTSTS2);
|
|
||||||
|
|
||||||
r8a66597_port_power(r8a66597, 0, 0);
|
for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
|
||||||
r8a66597_port_power(r8a66597, 1, 0);
|
r8a66597_disable_port(r8a66597, port);
|
||||||
|
|
||||||
do {
|
r8a66597_clock_disable(r8a66597);
|
||||||
tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS;
|
|
||||||
udelay(640);
|
|
||||||
} while (tmp == EDGESTS);
|
|
||||||
|
|
||||||
r8a66597_bclr(r8a66597, DCFM | DRPD, SYSCFG0);
|
|
||||||
r8a66597_bclr(r8a66597, DRPD, SYSCFG1);
|
|
||||||
r8a66597_bclr(r8a66597, HSE, SYSCFG0);
|
|
||||||
r8a66597_bclr(r8a66597, HSE, SYSCFG1);
|
|
||||||
|
|
||||||
r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
|
|
||||||
udelay(1);
|
|
||||||
r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
|
|
||||||
r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
|
|
||||||
r8a66597_bclr(r8a66597, USBE, SYSCFG0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_parent_r8a66597_address(struct r8a66597 *r8a66597,
|
static int get_parent_r8a66597_address(struct r8a66597 *r8a66597,
|
||||||
@ -577,13 +617,9 @@ static void pipe_buffer_setting(struct r8a66597 *r8a66597,
|
|||||||
PIPEBUF);
|
PIPEBUF);
|
||||||
r8a66597_write(r8a66597, make_devsel(info->address) | info->maxpacket,
|
r8a66597_write(r8a66597, make_devsel(info->address) | info->maxpacket,
|
||||||
PIPEMAXP);
|
PIPEMAXP);
|
||||||
if (info->interval)
|
|
||||||
info->interval--;
|
|
||||||
r8a66597_write(r8a66597, info->interval, PIPEPERI);
|
r8a66597_write(r8a66597, info->interval, PIPEPERI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* this function must be called with interrupt disabled */
|
/* this function must be called with interrupt disabled */
|
||||||
static void pipe_setting(struct r8a66597 *r8a66597, struct r8a66597_td *td)
|
static void pipe_setting(struct r8a66597 *r8a66597, struct r8a66597_td *td)
|
||||||
{
|
{
|
||||||
@ -715,6 +751,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|||||||
struct r8a66597_pipe *pipe,
|
struct r8a66597_pipe *pipe,
|
||||||
struct urb *urb)
|
struct urb *urb)
|
||||||
{
|
{
|
||||||
|
#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||||
int i;
|
int i;
|
||||||
struct r8a66597_pipe_info *info = &pipe->info;
|
struct r8a66597_pipe_info *info = &pipe->info;
|
||||||
|
|
||||||
@ -742,6 +779,7 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this function must be called with interrupt disabled */
|
/* this function must be called with interrupt disabled */
|
||||||
@ -825,6 +863,25 @@ static void disable_r8a66597_pipe_all(struct r8a66597 *r8a66597,
|
|||||||
dev->dma_map = 0;
|
dev->dma_map = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long get_timer_interval(struct urb *urb, __u8 interval)
|
||||||
|
{
|
||||||
|
__u8 i;
|
||||||
|
unsigned long time = 1;
|
||||||
|
|
||||||
|
if (usb_pipeisoc(urb->pipe))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (get_r8a66597_usb_speed(urb->dev->speed) == HSMODE) {
|
||||||
|
for (i = 0; i < (interval - 1); i++)
|
||||||
|
time *= 2;
|
||||||
|
time = time * 125 / 1000; /* uSOF -> msec */
|
||||||
|
} else {
|
||||||
|
time = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
/* this function must be called with interrupt disabled */
|
/* this function must be called with interrupt disabled */
|
||||||
static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
|
static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
|
||||||
struct usb_host_endpoint *hep,
|
struct usb_host_endpoint *hep,
|
||||||
@ -840,7 +897,16 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
|
|||||||
& USB_ENDPOINT_XFERTYPE_MASK);
|
& USB_ENDPOINT_XFERTYPE_MASK);
|
||||||
info.bufnum = get_bufnum(info.pipenum);
|
info.bufnum = get_bufnum(info.pipenum);
|
||||||
info.buf_bsize = get_buf_bsize(info.pipenum);
|
info.buf_bsize = get_buf_bsize(info.pipenum);
|
||||||
info.interval = ep->bInterval;
|
if (info.type == R8A66597_BULK) {
|
||||||
|
info.interval = 0;
|
||||||
|
info.timer_interval = 0;
|
||||||
|
} else {
|
||||||
|
if (ep->bInterval > IITV)
|
||||||
|
info.interval = IITV;
|
||||||
|
else
|
||||||
|
info.interval = ep->bInterval ? ep->bInterval - 1 : 0;
|
||||||
|
info.timer_interval = get_timer_interval(urb, ep->bInterval);
|
||||||
|
}
|
||||||
if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
|
if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
|
||||||
info.dir_in = 1;
|
info.dir_in = 1;
|
||||||
else
|
else
|
||||||
@ -876,10 +942,19 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* this function must be called with interrupt disabled */
|
/* this function must be called with interrupt disabled */
|
||||||
static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port)
|
static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
|
||||||
|
u16 syssts)
|
||||||
{
|
{
|
||||||
r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
|
if (syssts == SE0) {
|
||||||
| (1 << USB_PORT_FEAT_C_CONNECTION);
|
r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syssts == FS_JSTS)
|
||||||
|
r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port));
|
||||||
|
else if (syssts == LS_JSTS)
|
||||||
|
r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port));
|
||||||
|
|
||||||
r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
|
r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
|
||||||
r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
|
r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
|
||||||
}
|
}
|
||||||
@ -960,9 +1035,9 @@ static void prepare_packet_read(struct r8a66597 *r8a66597,
|
|||||||
r8a66597_write(r8a66597, TRCLR,
|
r8a66597_write(r8a66597, TRCLR,
|
||||||
td->pipe->pipetre);
|
td->pipe->pipetre);
|
||||||
r8a66597_write(r8a66597,
|
r8a66597_write(r8a66597,
|
||||||
(urb->transfer_buffer_length
|
DIV_ROUND_UP
|
||||||
+ td->maxpacket - 1)
|
(urb->transfer_buffer_length,
|
||||||
/ td->maxpacket,
|
td->maxpacket),
|
||||||
td->pipe->pipetrn);
|
td->pipe->pipetrn);
|
||||||
r8a66597_bset(r8a66597, TRENB,
|
r8a66597_bset(r8a66597, TRENB,
|
||||||
td->pipe->pipetre);
|
td->pipe->pipetre);
|
||||||
@ -1021,8 +1096,7 @@ static void prepare_status_packet(struct r8a66597 *r8a66597,
|
|||||||
r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL);
|
r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL);
|
||||||
r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
|
r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0);
|
||||||
r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
|
r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
|
||||||
r8a66597_write(r8a66597, BCLR, CFIFOCTR);
|
r8a66597_write(r8a66597, BCLR | BVAL, CFIFOCTR);
|
||||||
r8a66597_write(r8a66597, BVAL, CFIFOCTR);
|
|
||||||
enable_irq_empty(r8a66597, 0);
|
enable_irq_empty(r8a66597, 0);
|
||||||
} else {
|
} else {
|
||||||
r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
|
r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG);
|
||||||
@ -1454,13 +1528,21 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597)
|
||||||
|
{
|
||||||
|
mod_timer(&r8a66597->rh_timer,
|
||||||
|
jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME));
|
||||||
|
}
|
||||||
|
|
||||||
static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port)
|
static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port)
|
||||||
{
|
{
|
||||||
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
|
struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
|
||||||
|
|
||||||
rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
|
rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
|
||||||
rh->scount = R8A66597_MAX_SAMPLING;
|
rh->scount = R8A66597_MAX_SAMPLING;
|
||||||
mod_timer(&r8a66597->rh_timer, jiffies + msecs_to_jiffies(50));
|
r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
|
||||||
|
| (1 << USB_PORT_FEAT_C_CONNECTION);
|
||||||
|
r8a66597_root_hub_start_polling(r8a66597);
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
|
static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
|
||||||
@ -1547,41 +1629,55 @@ static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port)
|
|||||||
if ((tmp & USBRST) == USBRST) {
|
if ((tmp & USBRST) == USBRST) {
|
||||||
r8a66597_mdfy(r8a66597, UACT, USBRST | UACT,
|
r8a66597_mdfy(r8a66597, UACT, USBRST | UACT,
|
||||||
dvstctr_reg);
|
dvstctr_reg);
|
||||||
mod_timer(&r8a66597->rh_timer,
|
r8a66597_root_hub_start_polling(r8a66597);
|
||||||
jiffies + msecs_to_jiffies(50));
|
|
||||||
} else
|
} else
|
||||||
r8a66597_usb_connect(r8a66597, port);
|
r8a66597_usb_connect(r8a66597, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(rh->port & (1 << USB_PORT_FEAT_CONNECTION))) {
|
||||||
|
r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port));
|
||||||
|
r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
|
||||||
|
}
|
||||||
|
|
||||||
if (rh->scount > 0) {
|
if (rh->scount > 0) {
|
||||||
tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
|
tmp = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
|
||||||
if (tmp == rh->old_syssts) {
|
if (tmp == rh->old_syssts) {
|
||||||
rh->scount--;
|
rh->scount--;
|
||||||
if (rh->scount == 0) {
|
if (rh->scount == 0)
|
||||||
if (tmp == FS_JSTS) {
|
r8a66597_check_syssts(r8a66597, port, tmp);
|
||||||
r8a66597_bset(r8a66597, HSE,
|
else
|
||||||
get_syscfg_reg(port));
|
r8a66597_root_hub_start_polling(r8a66597);
|
||||||
r8a66597_usb_preconnect(r8a66597, port);
|
|
||||||
} else if (tmp == LS_JSTS) {
|
|
||||||
r8a66597_bclr(r8a66597, HSE,
|
|
||||||
get_syscfg_reg(port));
|
|
||||||
r8a66597_usb_preconnect(r8a66597, port);
|
|
||||||
} else if (tmp == SE0)
|
|
||||||
r8a66597_bset(r8a66597, ATTCHE,
|
|
||||||
get_intenb_reg(port));
|
|
||||||
} else {
|
|
||||||
mod_timer(&r8a66597->rh_timer,
|
|
||||||
jiffies + msecs_to_jiffies(50));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
rh->scount = R8A66597_MAX_SAMPLING;
|
rh->scount = R8A66597_MAX_SAMPLING;
|
||||||
rh->old_syssts = tmp;
|
rh->old_syssts = tmp;
|
||||||
mod_timer(&r8a66597->rh_timer,
|
r8a66597_root_hub_start_polling(r8a66597);
|
||||||
jiffies + msecs_to_jiffies(50));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void r8a66597_interval_timer(unsigned long _r8a66597)
|
||||||
|
{
|
||||||
|
struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
|
||||||
|
unsigned long flags;
|
||||||
|
u16 pipenum;
|
||||||
|
struct r8a66597_td *td;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&r8a66597->lock, flags);
|
||||||
|
|
||||||
|
for (pipenum = 0; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
|
||||||
|
if (!(r8a66597->interval_map & (1 << pipenum)))
|
||||||
|
continue;
|
||||||
|
if (timer_pending(&r8a66597->interval_timer[pipenum]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
td = r8a66597_get_td(r8a66597, pipenum);
|
||||||
|
if (td)
|
||||||
|
start_transfer(r8a66597, td);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&r8a66597->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
static void r8a66597_td_timer(unsigned long _r8a66597)
|
static void r8a66597_td_timer(unsigned long _r8a66597)
|
||||||
{
|
{
|
||||||
struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
|
struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
|
||||||
@ -1763,10 +1859,17 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd,
|
|||||||
urb->hcpriv = td;
|
urb->hcpriv = td;
|
||||||
|
|
||||||
if (request) {
|
if (request) {
|
||||||
ret = start_transfer(r8a66597, td);
|
if (td->pipe->info.timer_interval) {
|
||||||
if (ret < 0) {
|
r8a66597->interval_map |= 1 << td->pipenum;
|
||||||
list_del(&td->queue);
|
mod_timer(&r8a66597->interval_timer[td->pipenum],
|
||||||
kfree(td);
|
jiffies + msecs_to_jiffies(
|
||||||
|
td->pipe->info.timer_interval));
|
||||||
|
} else {
|
||||||
|
ret = start_transfer(r8a66597, td);
|
||||||
|
if (ret < 0) {
|
||||||
|
list_del(&td->queue);
|
||||||
|
kfree(td);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
set_td_timer(r8a66597, td);
|
set_td_timer(r8a66597, td);
|
||||||
@ -2107,13 +2210,11 @@ static struct hc_driver r8a66597_hc_driver = {
|
|||||||
#if defined(CONFIG_PM)
|
#if defined(CONFIG_PM)
|
||||||
static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
|
static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
|
||||||
{
|
{
|
||||||
pdev->dev.power.power_state = state;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int r8a66597_resume(struct platform_device *pdev)
|
static int r8a66597_resume(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
pdev->dev.power.power_state = PMSG_ON;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else /* if defined(CONFIG_PM) */
|
#else /* if defined(CONFIG_PM) */
|
||||||
@ -2194,6 +2295,9 @@ static int __init r8a66597_probe(struct platform_device *pdev)
|
|||||||
init_timer(&r8a66597->td_timer[i]);
|
init_timer(&r8a66597->td_timer[i]);
|
||||||
r8a66597->td_timer[i].function = r8a66597_td_timer;
|
r8a66597->td_timer[i].function = r8a66597_td_timer;
|
||||||
r8a66597->td_timer[i].data = (unsigned long)r8a66597;
|
r8a66597->td_timer[i].data = (unsigned long)r8a66597;
|
||||||
|
setup_timer(&r8a66597->interval_timer[i],
|
||||||
|
r8a66597_interval_timer,
|
||||||
|
(unsigned long)r8a66597);
|
||||||
}
|
}
|
||||||
INIT_LIST_HEAD(&r8a66597->child_device);
|
INIT_LIST_HEAD(&r8a66597->child_device);
|
||||||
|
|
||||||
|
@ -187,7 +187,11 @@
|
|||||||
#define REW 0x4000 /* b14: Buffer rewind */
|
#define REW 0x4000 /* b14: Buffer rewind */
|
||||||
#define DCLRM 0x2000 /* b13: DMA buffer clear mode */
|
#define DCLRM 0x2000 /* b13: DMA buffer clear mode */
|
||||||
#define DREQE 0x1000 /* b12: DREQ output enable */
|
#define DREQE 0x1000 /* b12: DREQ output enable */
|
||||||
|
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||||
|
#define MBW 0x0800
|
||||||
|
#else
|
||||||
#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */
|
#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */
|
||||||
|
#endif
|
||||||
#define MBW_8 0x0000 /* 8bit */
|
#define MBW_8 0x0000 /* 8bit */
|
||||||
#define MBW_16 0x0400 /* 16bit */
|
#define MBW_16 0x0400 /* 16bit */
|
||||||
#define BIGEND 0x0100 /* b8: Big endian mode */
|
#define BIGEND 0x0100 /* b8: Big endian mode */
|
||||||
@ -395,8 +399,13 @@
|
|||||||
#define R8A66597_MAX_NUM_PIPE 10
|
#define R8A66597_MAX_NUM_PIPE 10
|
||||||
#define R8A66597_BUF_BSIZE 8
|
#define R8A66597_BUF_BSIZE 8
|
||||||
#define R8A66597_MAX_DEVICE 10
|
#define R8A66597_MAX_DEVICE 10
|
||||||
|
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||||
|
#define R8A66597_MAX_ROOT_HUB 1
|
||||||
|
#else
|
||||||
#define R8A66597_MAX_ROOT_HUB 2
|
#define R8A66597_MAX_ROOT_HUB 2
|
||||||
#define R8A66597_MAX_SAMPLING 10
|
#endif
|
||||||
|
#define R8A66597_MAX_SAMPLING 5
|
||||||
|
#define R8A66597_RH_POLL_TIME 10
|
||||||
#define R8A66597_MAX_DMA_CHANNEL 2
|
#define R8A66597_MAX_DMA_CHANNEL 2
|
||||||
#define R8A66597_PIPE_NO_DMA R8A66597_MAX_DMA_CHANNEL
|
#define R8A66597_PIPE_NO_DMA R8A66597_MAX_DMA_CHANNEL
|
||||||
#define check_bulk_or_isoc(pipenum) ((pipenum >= 1 && pipenum <= 5))
|
#define check_bulk_or_isoc(pipenum) ((pipenum >= 1 && pipenum <= 5))
|
||||||
@ -404,6 +413,7 @@
|
|||||||
#define make_devsel(addr) (addr << 12)
|
#define make_devsel(addr) (addr << 12)
|
||||||
|
|
||||||
struct r8a66597_pipe_info {
|
struct r8a66597_pipe_info {
|
||||||
|
unsigned long timer_interval;
|
||||||
u16 pipenum;
|
u16 pipenum;
|
||||||
u16 address; /* R8A66597 HCD usb address */
|
u16 address; /* R8A66597 HCD usb address */
|
||||||
u16 epnum;
|
u16 epnum;
|
||||||
@ -478,9 +488,11 @@ struct r8a66597 {
|
|||||||
|
|
||||||
struct timer_list rh_timer;
|
struct timer_list rh_timer;
|
||||||
struct timer_list td_timer[R8A66597_MAX_NUM_PIPE];
|
struct timer_list td_timer[R8A66597_MAX_NUM_PIPE];
|
||||||
|
struct timer_list interval_timer[R8A66597_MAX_NUM_PIPE];
|
||||||
|
|
||||||
unsigned short address_map;
|
unsigned short address_map;
|
||||||
unsigned short timeout_map;
|
unsigned short timeout_map;
|
||||||
|
unsigned short interval_map;
|
||||||
unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
|
unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
|
||||||
unsigned char dma_map;
|
unsigned char dma_map;
|
||||||
|
|
||||||
@ -526,8 +538,21 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
|
|||||||
unsigned long offset, u16 *buf,
|
unsigned long offset, u16 *buf,
|
||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||||
|
unsigned long fifoaddr = r8a66597->reg + offset;
|
||||||
|
unsigned long count;
|
||||||
|
|
||||||
|
count = len / 4;
|
||||||
|
insl(fifoaddr, buf, count);
|
||||||
|
|
||||||
|
if (len & 0x00000003) {
|
||||||
|
unsigned long tmp = inl(fifoaddr);
|
||||||
|
memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03);
|
||||||
|
}
|
||||||
|
#else
|
||||||
len = (len + 1) / 2;
|
len = (len + 1) / 2;
|
||||||
insw(r8a66597->reg + offset, buf, len);
|
insw(r8a66597->reg + offset, buf, len);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
|
static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
|
||||||
@ -541,6 +566,24 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
|
|||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
unsigned long fifoaddr = r8a66597->reg + offset;
|
unsigned long fifoaddr = r8a66597->reg + offset;
|
||||||
|
#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
|
||||||
|
unsigned long count;
|
||||||
|
unsigned char *pb;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
count = len / 4;
|
||||||
|
outsl(fifoaddr, buf, count);
|
||||||
|
|
||||||
|
if (len & 0x00000003) {
|
||||||
|
pb = (unsigned char *)buf + count * 4;
|
||||||
|
for (i = 0; i < (len & 0x00000003); i++) {
|
||||||
|
if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
|
||||||
|
outb(pb[i], fifoaddr + i);
|
||||||
|
else
|
||||||
|
outb(pb[i], fifoaddr + 3 - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
int odd = len & 0x0001;
|
int odd = len & 0x0001;
|
||||||
|
|
||||||
len = len / 2;
|
len = len / 2;
|
||||||
@ -549,6 +592,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
|
|||||||
buf = &buf[len];
|
buf = &buf[len];
|
||||||
outb((unsigned char)*buf, fifoaddr);
|
outb((unsigned char)*buf, fifoaddr);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
|
static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
|
||||||
@ -581,6 +625,11 @@ static inline unsigned long get_dvstctr_reg(int port)
|
|||||||
return port == 0 ? DVSTCTR0 : DVSTCTR1;
|
return port == 0 ? DVSTCTR0 : DVSTCTR1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned long get_dmacfg_reg(int port)
|
||||||
|
{
|
||||||
|
return port == 0 ? DMA0CFG : DMA1CFG;
|
||||||
|
}
|
||||||
|
|
||||||
static inline unsigned long get_intenb_reg(int port)
|
static inline unsigned long get_intenb_reg(int port)
|
||||||
{
|
{
|
||||||
return port == 0 ? INTENB1 : INTENB2;
|
return port == 0 ? INTENB1 : INTENB2;
|
||||||
|
@ -94,12 +94,10 @@ static void port_power(struct sl811 *sl811, int is_on)
|
|||||||
|
|
||||||
sl811->port1 = (1 << USB_PORT_FEAT_POWER);
|
sl811->port1 = (1 << USB_PORT_FEAT_POWER);
|
||||||
sl811->irq_enable = SL11H_INTMASK_INSRMV;
|
sl811->irq_enable = SL11H_INTMASK_INSRMV;
|
||||||
hcd->self.controller->power.power_state = PMSG_ON;
|
|
||||||
} else {
|
} else {
|
||||||
sl811->port1 = 0;
|
sl811->port1 = 0;
|
||||||
sl811->irq_enable = 0;
|
sl811->irq_enable = 0;
|
||||||
hcd->state = HC_STATE_HALT;
|
hcd->state = HC_STATE_HALT;
|
||||||
hcd->self.controller->power.power_state = PMSG_SUSPEND;
|
|
||||||
}
|
}
|
||||||
sl811->ctrl1 = 0;
|
sl811->ctrl1 = 0;
|
||||||
sl811_write(sl811, SL11H_IRQ_ENABLE, 0);
|
sl811_write(sl811, SL11H_IRQ_ENABLE, 0);
|
||||||
@ -1337,7 +1335,7 @@ static int
|
|||||||
sl811h_bus_suspend(struct usb_hcd *hcd)
|
sl811h_bus_suspend(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
// SOFs off
|
// SOFs off
|
||||||
DBG("%s\n", __FUNCTION__);
|
DBG("%s\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1345,7 +1343,7 @@ static int
|
|||||||
sl811h_bus_resume(struct usb_hcd *hcd)
|
sl811h_bus_resume(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
// SOFs on
|
// SOFs on
|
||||||
DBG("%s\n", __FUNCTION__);
|
DBG("%s\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1772,8 +1770,6 @@ sl811h_suspend(struct platform_device *dev, pm_message_t state)
|
|||||||
port_power(sl811, 0);
|
port_power(sl811, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (retval == 0)
|
|
||||||
dev->dev.power.power_state = state;
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1786,15 +1782,13 @@ sl811h_resume(struct platform_device *dev)
|
|||||||
/* with no "check to see if VBUS is still powered" board hook,
|
/* with no "check to see if VBUS is still powered" board hook,
|
||||||
* let's assume it'd only be powered to enable remote wakeup.
|
* let's assume it'd only be powered to enable remote wakeup.
|
||||||
*/
|
*/
|
||||||
if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND
|
if (!sl811->port1 || !device_can_wakeup(&hcd->self.root_hub->dev)) {
|
||||||
|| !device_can_wakeup(&hcd->self.root_hub->dev)) {
|
|
||||||
sl811->port1 = 0;
|
sl811->port1 = 0;
|
||||||
port_power(sl811, 1);
|
port_power(sl811, 1);
|
||||||
usb_root_hub_lost_power(hcd->self.root_hub);
|
usb_root_hub_lost_power(hcd->self.root_hub);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->dev.power.power_state = PMSG_ON;
|
|
||||||
return sl811h_bus_resume(hcd);
|
return sl811h_bus_resume(hcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -262,20 +262,12 @@ __acquires(uhci->lock)
|
|||||||
{
|
{
|
||||||
int auto_stop;
|
int auto_stop;
|
||||||
int int_enable, egsm_enable;
|
int int_enable, egsm_enable;
|
||||||
|
struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub;
|
||||||
|
|
||||||
auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
|
auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
|
||||||
dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
|
dev_dbg(&rhdev->dev, "%s%s\n", __func__,
|
||||||
"%s%s\n", __FUNCTION__,
|
|
||||||
(auto_stop ? " (auto-stop)" : ""));
|
(auto_stop ? " (auto-stop)" : ""));
|
||||||
|
|
||||||
/* If we get a suspend request when we're already auto-stopped
|
|
||||||
* then there's nothing to do.
|
|
||||||
*/
|
|
||||||
if (uhci->rh_state == UHCI_RH_AUTO_STOPPED) {
|
|
||||||
uhci->rh_state = new_state;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable resume-detect interrupts if they work.
|
/* Enable resume-detect interrupts if they work.
|
||||||
* Then enter Global Suspend mode if _it_ works, still configured.
|
* Then enter Global Suspend mode if _it_ works, still configured.
|
||||||
*/
|
*/
|
||||||
@ -285,8 +277,10 @@ __acquires(uhci->lock)
|
|||||||
if (remote_wakeup_is_broken(uhci))
|
if (remote_wakeup_is_broken(uhci))
|
||||||
egsm_enable = 0;
|
egsm_enable = 0;
|
||||||
if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable ||
|
if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable ||
|
||||||
!device_may_wakeup(
|
#ifdef CONFIG_PM
|
||||||
&uhci_to_hcd(uhci)->self.root_hub->dev))
|
(!auto_stop && !rhdev->do_remote_wakeup) ||
|
||||||
|
#endif
|
||||||
|
(auto_stop && !device_may_wakeup(&rhdev->dev)))
|
||||||
uhci->working_RD = int_enable = 0;
|
uhci->working_RD = int_enable = 0;
|
||||||
|
|
||||||
outw(int_enable, uhci->io_addr + USBINTR);
|
outw(int_enable, uhci->io_addr + USBINTR);
|
||||||
@ -308,8 +302,7 @@ __acquires(uhci->lock)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH))
|
if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH))
|
||||||
dev_warn(&uhci_to_hcd(uhci)->self.root_hub->dev,
|
dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n");
|
||||||
"Controller not stopped yet!\n");
|
|
||||||
|
|
||||||
uhci_get_current_frame_number(uhci);
|
uhci_get_current_frame_number(uhci);
|
||||||
|
|
||||||
@ -342,7 +335,7 @@ __releases(uhci->lock)
|
|||||||
__acquires(uhci->lock)
|
__acquires(uhci->lock)
|
||||||
{
|
{
|
||||||
dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
|
dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
|
||||||
"%s%s\n", __FUNCTION__,
|
"%s%s\n", __func__,
|
||||||
uhci->rh_state == UHCI_RH_AUTO_STOPPED ?
|
uhci->rh_state == UHCI_RH_AUTO_STOPPED ?
|
||||||
" (auto-start)" : "");
|
" (auto-start)" : "");
|
||||||
|
|
||||||
@ -737,12 +730,12 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
|
static int uhci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
|
||||||
{
|
{
|
||||||
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
|
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
|
dev_dbg(uhci_dev(uhci), "%s\n", __func__);
|
||||||
|
|
||||||
spin_lock_irq(&uhci->lock);
|
spin_lock_irq(&uhci->lock);
|
||||||
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
|
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
|
||||||
@ -774,11 +767,11 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uhci_resume(struct usb_hcd *hcd)
|
static int uhci_pci_resume(struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
|
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
|
||||||
|
|
||||||
dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
|
dev_dbg(uhci_dev(uhci), "%s\n", __func__);
|
||||||
|
|
||||||
/* Since we aren't in D3 any more, it's safe to set this flag
|
/* Since we aren't in D3 any more, it's safe to set this flag
|
||||||
* even if the controller was dead.
|
* even if the controller was dead.
|
||||||
@ -872,8 +865,8 @@ static const struct hc_driver uhci_driver = {
|
|||||||
.reset = uhci_init,
|
.reset = uhci_init,
|
||||||
.start = uhci_start,
|
.start = uhci_start,
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.suspend = uhci_suspend,
|
.pci_suspend = uhci_pci_suspend,
|
||||||
.resume = uhci_resume,
|
.pci_resume = uhci_pci_resume,
|
||||||
.bus_suspend = uhci_rh_suspend,
|
.bus_suspend = uhci_rh_suspend,
|
||||||
.bus_resume = uhci_rh_resume,
|
.bus_resume = uhci_rh_resume,
|
||||||
#endif
|
#endif
|
||||||
|
@ -1171,7 +1171,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
|
|||||||
/* Some debugging code */
|
/* Some debugging code */
|
||||||
dev_dbg(&urb->dev->dev,
|
dev_dbg(&urb->dev->dev,
|
||||||
"%s: failed with status %x\n",
|
"%s: failed with status %x\n",
|
||||||
__FUNCTION__, status);
|
__func__, status);
|
||||||
|
|
||||||
if (debug > 1 && errbuf) {
|
if (debug > 1 && errbuf) {
|
||||||
/* Print the chain for debugging */
|
/* Print the chain for debugging */
|
||||||
|
@ -5,8 +5,8 @@ comment "USB Imaging devices"
|
|||||||
depends on USB
|
depends on USB
|
||||||
|
|
||||||
config USB_MDC800
|
config USB_MDC800
|
||||||
tristate "USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)"
|
tristate "USB Mustek MDC800 Digital Camera support"
|
||||||
depends on USB && EXPERIMENTAL
|
depends on USB
|
||||||
---help---
|
---help---
|
||||||
Say Y here if you want to connect this type of still camera to
|
Say Y here if you want to connect this type of still camera to
|
||||||
your computer's USB port. This driver can be used with gphoto 0.4.3
|
your computer's USB port. This driver can be used with gphoto 0.4.3
|
||||||
|
@ -185,7 +185,7 @@ static struct usb_driver mts_usb_driver = {
|
|||||||
printk( KERN_DEBUG MTS_NAME x )
|
printk( KERN_DEBUG MTS_NAME x )
|
||||||
|
|
||||||
#define MTS_DEBUG_GOT_HERE() \
|
#define MTS_DEBUG_GOT_HERE() \
|
||||||
MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __PRETTY_FUNCTION__ )
|
MTS_DEBUG("got to %s:%d (%s)\n", __FILE__, (int)__LINE__, __func__ )
|
||||||
#define MTS_DEBUG_INT() \
|
#define MTS_DEBUG_INT() \
|
||||||
do { MTS_DEBUG_GOT_HERE(); \
|
do { MTS_DEBUG_GOT_HERE(); \
|
||||||
MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \
|
MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \
|
||||||
@ -794,7 +794,6 @@ static int mts_usb_probe(struct usb_interface *intf,
|
|||||||
|
|
||||||
new_desc->usb_dev = dev;
|
new_desc->usb_dev = dev;
|
||||||
new_desc->usb_intf = intf;
|
new_desc->usb_intf = intf;
|
||||||
init_MUTEX(&new_desc->lock);
|
|
||||||
|
|
||||||
/* endpoints */
|
/* endpoints */
|
||||||
new_desc->ep_out = ep_out;
|
new_desc->ep_out = ep_out;
|
||||||
|
@ -39,7 +39,6 @@ struct mts_desc {
|
|||||||
u8 ep_image;
|
u8 ep_image;
|
||||||
|
|
||||||
struct Scsi_Host * host;
|
struct Scsi_Host * host;
|
||||||
struct semaphore lock;
|
|
||||||
|
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
struct mts_transfer_context context;
|
struct mts_transfer_context context;
|
||||||
|
@ -33,8 +33,8 @@ config USB_EMI26
|
|||||||
module will be called emi26.
|
module will be called emi26.
|
||||||
|
|
||||||
config USB_ADUTUX
|
config USB_ADUTUX
|
||||||
tristate "ADU devices from Ontrak Control Systems (EXPERIMENTAL)"
|
tristate "ADU devices from Ontrak Control Systems"
|
||||||
depends on USB && EXPERIMENTAL
|
depends on USB
|
||||||
help
|
help
|
||||||
Say Y if you want to use an ADU device from Ontrak Control
|
Say Y if you want to use an ADU device from Ontrak Control
|
||||||
Systems.
|
Systems.
|
||||||
@ -43,8 +43,8 @@ config USB_ADUTUX
|
|||||||
will be called adutux.
|
will be called adutux.
|
||||||
|
|
||||||
config USB_AUERSWALD
|
config USB_AUERSWALD
|
||||||
tristate "USB Auerswald ISDN support (EXPERIMENTAL)"
|
tristate "USB Auerswald ISDN support"
|
||||||
depends on USB && EXPERIMENTAL
|
depends on USB
|
||||||
help
|
help
|
||||||
Say Y here if you want to connect an Auerswald USB ISDN Device
|
Say Y here if you want to connect an Auerswald USB ISDN Device
|
||||||
to your computer's USB port.
|
to your computer's USB port.
|
||||||
@ -53,8 +53,8 @@ config USB_AUERSWALD
|
|||||||
module will be called auerswald.
|
module will be called auerswald.
|
||||||
|
|
||||||
config USB_RIO500
|
config USB_RIO500
|
||||||
tristate "USB Diamond Rio500 support (EXPERIMENTAL)"
|
tristate "USB Diamond Rio500 support"
|
||||||
depends on USB && EXPERIMENTAL
|
depends on USB
|
||||||
help
|
help
|
||||||
Say Y here if you want to connect a USB Rio500 mp3 player to your
|
Say Y here if you want to connect a USB Rio500 mp3 player to your
|
||||||
computer's USB port. Please read <file:Documentation/usb/rio.txt>
|
computer's USB port. Please read <file:Documentation/usb/rio.txt>
|
||||||
@ -64,8 +64,8 @@ config USB_RIO500
|
|||||||
module will be called rio500.
|
module will be called rio500.
|
||||||
|
|
||||||
config USB_LEGOTOWER
|
config USB_LEGOTOWER
|
||||||
tristate "USB Lego Infrared Tower support (EXPERIMENTAL)"
|
tristate "USB Lego Infrared Tower support"
|
||||||
depends on USB && EXPERIMENTAL
|
depends on USB
|
||||||
help
|
help
|
||||||
Say Y here if you want to connect a USB Lego Infrared Tower to your
|
Say Y here if you want to connect a USB Lego Infrared Tower to your
|
||||||
computer's USB port.
|
computer's USB port.
|
||||||
@ -259,8 +259,8 @@ config USB_IOWARRIOR
|
|||||||
module will be called iowarrior.
|
module will be called iowarrior.
|
||||||
|
|
||||||
config USB_TEST
|
config USB_TEST
|
||||||
tristate "USB testing driver (DEVELOPMENT)"
|
tristate "USB testing driver"
|
||||||
depends on USB && USB_DEVICEFS && EXPERIMENTAL
|
depends on USB && USB_DEVICEFS
|
||||||
help
|
help
|
||||||
This driver is for testing host controller software. It is used
|
This driver is for testing host controller software. It is used
|
||||||
with specialized device firmware for regression and stress testing,
|
with specialized device firmware for regression and stress testing,
|
||||||
|
@ -147,10 +147,10 @@ static void adu_abort_transfers(struct adu_device *dev)
|
|||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
dbg(2," %s : enter", __FUNCTION__);
|
dbg(2," %s : enter", __func__);
|
||||||
|
|
||||||
if (dev->udev == NULL) {
|
if (dev->udev == NULL) {
|
||||||
dbg(1," %s : udev is null", __FUNCTION__);
|
dbg(1," %s : udev is null", __func__);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,12 +172,12 @@ static void adu_abort_transfers(struct adu_device *dev)
|
|||||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
dbg(2," %s : leave", __FUNCTION__);
|
dbg(2," %s : leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adu_delete(struct adu_device *dev)
|
static void adu_delete(struct adu_device *dev)
|
||||||
{
|
{
|
||||||
dbg(2, "%s enter", __FUNCTION__);
|
dbg(2, "%s enter", __func__);
|
||||||
|
|
||||||
/* free data structures */
|
/* free data structures */
|
||||||
usb_free_urb(dev->interrupt_in_urb);
|
usb_free_urb(dev->interrupt_in_urb);
|
||||||
@ -188,7 +188,7 @@ static void adu_delete(struct adu_device *dev)
|
|||||||
kfree(dev->interrupt_out_buffer);
|
kfree(dev->interrupt_out_buffer);
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
|
|
||||||
dbg(2, "%s : leave", __FUNCTION__);
|
dbg(2, "%s : leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adu_interrupt_in_callback(struct urb *urb)
|
static void adu_interrupt_in_callback(struct urb *urb)
|
||||||
@ -196,8 +196,8 @@ static void adu_interrupt_in_callback(struct urb *urb)
|
|||||||
struct adu_device *dev = urb->context;
|
struct adu_device *dev = urb->context;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
|
|
||||||
dbg(4," %s : enter, status %d", __FUNCTION__, status);
|
dbg(4," %s : enter, status %d", __func__, status);
|
||||||
adu_debug_data(5, __FUNCTION__, urb->actual_length,
|
adu_debug_data(5, __func__, urb->actual_length,
|
||||||
urb->transfer_buffer);
|
urb->transfer_buffer);
|
||||||
|
|
||||||
spin_lock(&dev->buflock);
|
spin_lock(&dev->buflock);
|
||||||
@ -206,7 +206,7 @@ static void adu_interrupt_in_callback(struct urb *urb)
|
|||||||
if ((status != -ENOENT) && (status != -ECONNRESET) &&
|
if ((status != -ENOENT) && (status != -ECONNRESET) &&
|
||||||
(status != -ESHUTDOWN)) {
|
(status != -ESHUTDOWN)) {
|
||||||
dbg(1," %s : nonzero status received: %d",
|
dbg(1," %s : nonzero status received: %d",
|
||||||
__FUNCTION__, status);
|
__func__, status);
|
||||||
}
|
}
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -220,10 +220,10 @@ static void adu_interrupt_in_callback(struct urb *urb)
|
|||||||
dev->interrupt_in_buffer, urb->actual_length);
|
dev->interrupt_in_buffer, urb->actual_length);
|
||||||
|
|
||||||
dev->read_buffer_length += urb->actual_length;
|
dev->read_buffer_length += urb->actual_length;
|
||||||
dbg(2," %s reading %d ", __FUNCTION__,
|
dbg(2," %s reading %d ", __func__,
|
||||||
urb->actual_length);
|
urb->actual_length);
|
||||||
} else {
|
} else {
|
||||||
dbg(1," %s : read_buffer overflow", __FUNCTION__);
|
dbg(1," %s : read_buffer overflow", __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,9 +232,9 @@ static void adu_interrupt_in_callback(struct urb *urb)
|
|||||||
spin_unlock(&dev->buflock);
|
spin_unlock(&dev->buflock);
|
||||||
/* always wake up so we recover from errors */
|
/* always wake up so we recover from errors */
|
||||||
wake_up_interruptible(&dev->read_wait);
|
wake_up_interruptible(&dev->read_wait);
|
||||||
adu_debug_data(5, __FUNCTION__, urb->actual_length,
|
adu_debug_data(5, __func__, urb->actual_length,
|
||||||
urb->transfer_buffer);
|
urb->transfer_buffer);
|
||||||
dbg(4," %s : leave, status %d", __FUNCTION__, status);
|
dbg(4," %s : leave, status %d", __func__, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adu_interrupt_out_callback(struct urb *urb)
|
static void adu_interrupt_out_callback(struct urb *urb)
|
||||||
@ -242,14 +242,14 @@ static void adu_interrupt_out_callback(struct urb *urb)
|
|||||||
struct adu_device *dev = urb->context;
|
struct adu_device *dev = urb->context;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
|
|
||||||
dbg(4," %s : enter, status %d", __FUNCTION__, status);
|
dbg(4," %s : enter, status %d", __func__, status);
|
||||||
adu_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer);
|
adu_debug_data(5,__func__, urb->actual_length, urb->transfer_buffer);
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
if ((status != -ENOENT) &&
|
if ((status != -ENOENT) &&
|
||||||
(status != -ECONNRESET)) {
|
(status != -ECONNRESET)) {
|
||||||
dbg(1, " %s :nonzero status received: %d",
|
dbg(1, " %s :nonzero status received: %d",
|
||||||
__FUNCTION__, status);
|
__func__, status);
|
||||||
}
|
}
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -260,9 +260,9 @@ static void adu_interrupt_out_callback(struct urb *urb)
|
|||||||
spin_unlock(&dev->buflock);
|
spin_unlock(&dev->buflock);
|
||||||
exit:
|
exit:
|
||||||
|
|
||||||
adu_debug_data(5, __FUNCTION__, urb->actual_length,
|
adu_debug_data(5, __func__, urb->actual_length,
|
||||||
urb->transfer_buffer);
|
urb->transfer_buffer);
|
||||||
dbg(4," %s : leave, status %d", __FUNCTION__, status);
|
dbg(4," %s : leave, status %d", __func__, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adu_open(struct inode *inode, struct file *file)
|
static int adu_open(struct inode *inode, struct file *file)
|
||||||
@ -272,19 +272,19 @@ static int adu_open(struct inode *inode, struct file *file)
|
|||||||
int subminor;
|
int subminor;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
dbg(2,"%s : enter", __FUNCTION__);
|
dbg(2,"%s : enter", __func__);
|
||||||
|
|
||||||
subminor = iminor(inode);
|
subminor = iminor(inode);
|
||||||
|
|
||||||
if ((retval = mutex_lock_interruptible(&adutux_mutex))) {
|
if ((retval = mutex_lock_interruptible(&adutux_mutex))) {
|
||||||
dbg(2, "%s : mutex lock failed", __FUNCTION__);
|
dbg(2, "%s : mutex lock failed", __func__);
|
||||||
goto exit_no_lock;
|
goto exit_no_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface = usb_find_interface(&adu_driver, subminor);
|
interface = usb_find_interface(&adu_driver, subminor);
|
||||||
if (!interface) {
|
if (!interface) {
|
||||||
err("%s - error, can't find device for minor %d",
|
err("%s - error, can't find device for minor %d",
|
||||||
__FUNCTION__, subminor);
|
__func__, subminor);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit_no_device;
|
goto exit_no_device;
|
||||||
}
|
}
|
||||||
@ -302,7 +302,7 @@ static int adu_open(struct inode *inode, struct file *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
++dev->open_count;
|
++dev->open_count;
|
||||||
dbg(2,"%s : open count %d", __FUNCTION__, dev->open_count);
|
dbg(2,"%s : open count %d", __func__, dev->open_count);
|
||||||
|
|
||||||
/* save device in the file's private structure */
|
/* save device in the file's private structure */
|
||||||
file->private_data = dev;
|
file->private_data = dev;
|
||||||
@ -332,23 +332,23 @@ static int adu_open(struct inode *inode, struct file *file)
|
|||||||
exit_no_device:
|
exit_no_device:
|
||||||
mutex_unlock(&adutux_mutex);
|
mutex_unlock(&adutux_mutex);
|
||||||
exit_no_lock:
|
exit_no_lock:
|
||||||
dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval);
|
dbg(2,"%s : leave, return value %d ", __func__, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adu_release_internal(struct adu_device *dev)
|
static void adu_release_internal(struct adu_device *dev)
|
||||||
{
|
{
|
||||||
dbg(2," %s : enter", __FUNCTION__);
|
dbg(2," %s : enter", __func__);
|
||||||
|
|
||||||
/* decrement our usage count for the device */
|
/* decrement our usage count for the device */
|
||||||
--dev->open_count;
|
--dev->open_count;
|
||||||
dbg(2," %s : open count %d", __FUNCTION__, dev->open_count);
|
dbg(2," %s : open count %d", __func__, dev->open_count);
|
||||||
if (dev->open_count <= 0) {
|
if (dev->open_count <= 0) {
|
||||||
adu_abort_transfers(dev);
|
adu_abort_transfers(dev);
|
||||||
dev->open_count = 0;
|
dev->open_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg(2," %s : leave", __FUNCTION__);
|
dbg(2," %s : leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adu_release(struct inode *inode, struct file *file)
|
static int adu_release(struct inode *inode, struct file *file)
|
||||||
@ -356,17 +356,17 @@ static int adu_release(struct inode *inode, struct file *file)
|
|||||||
struct adu_device *dev;
|
struct adu_device *dev;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
dbg(2," %s : enter", __FUNCTION__);
|
dbg(2," %s : enter", __func__);
|
||||||
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
dbg(1," %s : file is NULL", __FUNCTION__);
|
dbg(1," %s : file is NULL", __func__);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = file->private_data;
|
dev = file->private_data;
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
dbg(1," %s : object is NULL", __FUNCTION__);
|
dbg(1," %s : object is NULL", __func__);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -374,7 +374,7 @@ static int adu_release(struct inode *inode, struct file *file)
|
|||||||
mutex_lock(&adutux_mutex); /* not interruptible */
|
mutex_lock(&adutux_mutex); /* not interruptible */
|
||||||
|
|
||||||
if (dev->open_count <= 0) {
|
if (dev->open_count <= 0) {
|
||||||
dbg(1," %s : device not opened", __FUNCTION__);
|
dbg(1," %s : device not opened", __func__);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -388,7 +388,7 @@ static int adu_release(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
exit:
|
exit:
|
||||||
mutex_unlock(&adutux_mutex);
|
mutex_unlock(&adutux_mutex);
|
||||||
dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
|
dbg(2," %s : leave, return value %d", __func__, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,10 +405,10 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
|
|
||||||
dbg(2," %s : enter, count = %Zd, file=%p", __FUNCTION__, count, file);
|
dbg(2," %s : enter, count = %Zd, file=%p", __func__, count, file);
|
||||||
|
|
||||||
dev = file->private_data;
|
dev = file->private_data;
|
||||||
dbg(2," %s : dev=%p", __FUNCTION__, dev);
|
dbg(2," %s : dev=%p", __func__, dev);
|
||||||
|
|
||||||
if (mutex_lock_interruptible(&dev->mtx))
|
if (mutex_lock_interruptible(&dev->mtx))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
@ -422,16 +422,16 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||||||
|
|
||||||
/* verify that some data was requested */
|
/* verify that some data was requested */
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
dbg(1," %s : read request of 0 bytes", __FUNCTION__);
|
dbg(1," %s : read request of 0 bytes", __func__);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout = COMMAND_TIMEOUT;
|
timeout = COMMAND_TIMEOUT;
|
||||||
dbg(2," %s : about to start looping", __FUNCTION__);
|
dbg(2," %s : about to start looping", __func__);
|
||||||
while (bytes_to_read) {
|
while (bytes_to_read) {
|
||||||
int data_in_secondary = dev->secondary_tail - dev->secondary_head;
|
int data_in_secondary = dev->secondary_tail - dev->secondary_head;
|
||||||
dbg(2," %s : while, data_in_secondary=%d, status=%d",
|
dbg(2," %s : while, data_in_secondary=%d, status=%d",
|
||||||
__FUNCTION__, data_in_secondary,
|
__func__, data_in_secondary,
|
||||||
dev->interrupt_in_urb->status);
|
dev->interrupt_in_urb->status);
|
||||||
|
|
||||||
if (data_in_secondary) {
|
if (data_in_secondary) {
|
||||||
@ -456,7 +456,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||||||
/* we secure access to the primary */
|
/* we secure access to the primary */
|
||||||
char *tmp;
|
char *tmp;
|
||||||
dbg(2," %s : swap, read_buffer_length = %d",
|
dbg(2," %s : swap, read_buffer_length = %d",
|
||||||
__FUNCTION__, dev->read_buffer_length);
|
__func__, dev->read_buffer_length);
|
||||||
tmp = dev->read_buffer_secondary;
|
tmp = dev->read_buffer_secondary;
|
||||||
dev->read_buffer_secondary = dev->read_buffer_primary;
|
dev->read_buffer_secondary = dev->read_buffer_primary;
|
||||||
dev->read_buffer_primary = tmp;
|
dev->read_buffer_primary = tmp;
|
||||||
@ -471,10 +471,10 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||||||
if (!dev->read_urb_finished) {
|
if (!dev->read_urb_finished) {
|
||||||
/* somebody is doing IO */
|
/* somebody is doing IO */
|
||||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||||
dbg(2," %s : submitted already", __FUNCTION__);
|
dbg(2," %s : submitted already", __func__);
|
||||||
} else {
|
} else {
|
||||||
/* we must initiate input */
|
/* we must initiate input */
|
||||||
dbg(2," %s : initiate input", __FUNCTION__);
|
dbg(2," %s : initiate input", __func__);
|
||||||
dev->read_urb_finished = 0;
|
dev->read_urb_finished = 0;
|
||||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||||
|
|
||||||
@ -492,7 +492,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||||||
if (retval == -ENOMEM) {
|
if (retval == -ENOMEM) {
|
||||||
retval = bytes_read ? bytes_read : -ENOMEM;
|
retval = bytes_read ? bytes_read : -ENOMEM;
|
||||||
}
|
}
|
||||||
dbg(2," %s : submit failed", __FUNCTION__);
|
dbg(2," %s : submit failed", __func__);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,13 +511,13 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||||||
remove_wait_queue(&dev->read_wait, &wait);
|
remove_wait_queue(&dev->read_wait, &wait);
|
||||||
|
|
||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
dbg(2," %s : timeout", __FUNCTION__);
|
dbg(2," %s : timeout", __func__);
|
||||||
retval = bytes_read ? bytes_read : -ETIMEDOUT;
|
retval = bytes_read ? bytes_read : -ETIMEDOUT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
dbg(2," %s : signal pending", __FUNCTION__);
|
dbg(2," %s : signal pending", __func__);
|
||||||
retval = bytes_read ? bytes_read : -EINTR;
|
retval = bytes_read ? bytes_read : -EINTR;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -550,7 +550,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
|
|||||||
/* unlock the device */
|
/* unlock the device */
|
||||||
mutex_unlock(&dev->mtx);
|
mutex_unlock(&dev->mtx);
|
||||||
|
|
||||||
dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
|
dbg(2," %s : leave, return value %d", __func__, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +565,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
dbg(2," %s : enter, count = %Zd", __FUNCTION__, count);
|
dbg(2," %s : enter, count = %Zd", __func__, count);
|
||||||
|
|
||||||
dev = file->private_data;
|
dev = file->private_data;
|
||||||
|
|
||||||
@ -582,7 +582,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
|
|||||||
|
|
||||||
/* verify that we actually have some data to write */
|
/* verify that we actually have some data to write */
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
dbg(1," %s : write request of 0 bytes", __FUNCTION__);
|
dbg(1," %s : write request of 0 bytes", __func__);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,13 +595,13 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
|
|||||||
|
|
||||||
mutex_unlock(&dev->mtx);
|
mutex_unlock(&dev->mtx);
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
dbg(1," %s : interrupted", __FUNCTION__);
|
dbg(1," %s : interrupted", __func__);
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
retval = -EINTR;
|
retval = -EINTR;
|
||||||
goto exit_onqueue;
|
goto exit_onqueue;
|
||||||
}
|
}
|
||||||
if (schedule_timeout(COMMAND_TIMEOUT) == 0) {
|
if (schedule_timeout(COMMAND_TIMEOUT) == 0) {
|
||||||
dbg(1, "%s - command timed out.", __FUNCTION__);
|
dbg(1, "%s - command timed out.", __func__);
|
||||||
retval = -ETIMEDOUT;
|
retval = -ETIMEDOUT;
|
||||||
goto exit_onqueue;
|
goto exit_onqueue;
|
||||||
}
|
}
|
||||||
@ -612,18 +612,18 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
|
|||||||
goto exit_nolock;
|
goto exit_nolock;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg(4," %s : in progress, count = %Zd", __FUNCTION__, count);
|
dbg(4," %s : in progress, count = %Zd", __func__, count);
|
||||||
} else {
|
} else {
|
||||||
spin_unlock_irqrestore(&dev->buflock, flags);
|
spin_unlock_irqrestore(&dev->buflock, flags);
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
remove_wait_queue(&dev->write_wait, &waita);
|
remove_wait_queue(&dev->write_wait, &waita);
|
||||||
dbg(4," %s : sending, count = %Zd", __FUNCTION__, count);
|
dbg(4," %s : sending, count = %Zd", __func__, count);
|
||||||
|
|
||||||
/* write the data into interrupt_out_buffer from userspace */
|
/* write the data into interrupt_out_buffer from userspace */
|
||||||
buffer_size = le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize);
|
buffer_size = le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize);
|
||||||
bytes_to_write = count > buffer_size ? buffer_size : count;
|
bytes_to_write = count > buffer_size ? buffer_size : count;
|
||||||
dbg(4," %s : buffer_size = %Zd, count = %Zd, bytes_to_write = %Zd",
|
dbg(4," %s : buffer_size = %Zd, count = %Zd, bytes_to_write = %Zd",
|
||||||
__FUNCTION__, buffer_size, count, bytes_to_write);
|
__func__, buffer_size, count, bytes_to_write);
|
||||||
|
|
||||||
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write) != 0) {
|
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write) != 0) {
|
||||||
retval = -EFAULT;
|
retval = -EFAULT;
|
||||||
@ -661,7 +661,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
|
|||||||
exit:
|
exit:
|
||||||
mutex_unlock(&dev->mtx);
|
mutex_unlock(&dev->mtx);
|
||||||
exit_nolock:
|
exit_nolock:
|
||||||
dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
|
dbg(2," %s : leave, return value %d", __func__, retval);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
exit_onqueue:
|
exit_onqueue:
|
||||||
@ -706,7 +706,7 @@ static int adu_probe(struct usb_interface *interface,
|
|||||||
int out_end_size;
|
int out_end_size;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dbg(2," %s : enter", __FUNCTION__);
|
dbg(2," %s : enter", __func__);
|
||||||
|
|
||||||
if (udev == NULL) {
|
if (udev == NULL) {
|
||||||
dev_err(&interface->dev, "udev is NULL.\n");
|
dev_err(&interface->dev, "udev is NULL.\n");
|
||||||
@ -807,7 +807,7 @@ static int adu_probe(struct usb_interface *interface,
|
|||||||
dev_err(&interface->dev, "Could not retrieve serial number\n");
|
dev_err(&interface->dev, "Could not retrieve serial number\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
dbg(2," %s : serial_number=%s", __FUNCTION__, dev->serial_number);
|
dbg(2," %s : serial_number=%s", __func__, dev->serial_number);
|
||||||
|
|
||||||
/* we can register the device now, as it is ready */
|
/* we can register the device now, as it is ready */
|
||||||
usb_set_intfdata(interface, dev);
|
usb_set_intfdata(interface, dev);
|
||||||
@ -828,7 +828,7 @@ static int adu_probe(struct usb_interface *interface,
|
|||||||
udev->descriptor.idProduct, dev->serial_number,
|
udev->descriptor.idProduct, dev->serial_number,
|
||||||
(dev->minor - ADU_MINOR_BASE));
|
(dev->minor - ADU_MINOR_BASE));
|
||||||
exit:
|
exit:
|
||||||
dbg(2," %s : leave, return value %p (dev)", __FUNCTION__, dev);
|
dbg(2," %s : leave, return value %p (dev)", __func__, dev);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
@ -847,7 +847,7 @@ static void adu_disconnect(struct usb_interface *interface)
|
|||||||
struct adu_device *dev;
|
struct adu_device *dev;
|
||||||
int minor;
|
int minor;
|
||||||
|
|
||||||
dbg(2," %s : enter", __FUNCTION__);
|
dbg(2," %s : enter", __func__);
|
||||||
|
|
||||||
dev = usb_get_intfdata(interface);
|
dev = usb_get_intfdata(interface);
|
||||||
|
|
||||||
@ -861,7 +861,7 @@ static void adu_disconnect(struct usb_interface *interface)
|
|||||||
usb_set_intfdata(interface, NULL);
|
usb_set_intfdata(interface, NULL);
|
||||||
|
|
||||||
/* if the device is not opened, then we clean up right now */
|
/* if the device is not opened, then we clean up right now */
|
||||||
dbg(2," %s : open count %d", __FUNCTION__, dev->open_count);
|
dbg(2," %s : open count %d", __func__, dev->open_count);
|
||||||
if (!dev->open_count)
|
if (!dev->open_count)
|
||||||
adu_delete(dev);
|
adu_delete(dev);
|
||||||
|
|
||||||
@ -870,7 +870,7 @@ static void adu_disconnect(struct usb_interface *interface)
|
|||||||
dev_info(&interface->dev, "ADU device adutux%d now disconnected\n",
|
dev_info(&interface->dev, "ADU device adutux%d now disconnected\n",
|
||||||
(minor - ADU_MINOR_BASE));
|
(minor - ADU_MINOR_BASE));
|
||||||
|
|
||||||
dbg(2," %s : leave", __FUNCTION__);
|
dbg(2," %s : leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* usb specific object needed to register this driver with the usb subsystem */
|
/* usb specific object needed to register this driver with the usb subsystem */
|
||||||
@ -885,7 +885,7 @@ static int __init adu_init(void)
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
dbg(2," %s : enter", __FUNCTION__);
|
dbg(2," %s : enter", __func__);
|
||||||
|
|
||||||
/* register this driver with the USB subsystem */
|
/* register this driver with the USB subsystem */
|
||||||
result = usb_register(&adu_driver);
|
result = usb_register(&adu_driver);
|
||||||
@ -899,17 +899,17 @@ static int __init adu_init(void)
|
|||||||
info("adutux is an experimental driver. Use at your own risk");
|
info("adutux is an experimental driver. Use at your own risk");
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
dbg(2," %s : leave, return value %d", __FUNCTION__, result);
|
dbg(2," %s : leave, return value %d", __func__, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit adu_exit(void)
|
static void __exit adu_exit(void)
|
||||||
{
|
{
|
||||||
dbg(2," %s : enter", __FUNCTION__);
|
dbg(2," %s : enter", __func__);
|
||||||
/* deregister this driver with the USB subsystem */
|
/* deregister this driver with the USB subsystem */
|
||||||
usb_deregister(&adu_driver);
|
usb_deregister(&adu_driver);
|
||||||
dbg(2," %s : leave", __FUNCTION__);
|
dbg(2," %s : leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(adu_init);
|
module_init(adu_init);
|
||||||
|
@ -103,11 +103,11 @@ static void appledisplay_complete(struct urb *urb)
|
|||||||
case -ESHUTDOWN:
|
case -ESHUTDOWN:
|
||||||
/* This urb is terminated, clean up */
|
/* This urb is terminated, clean up */
|
||||||
dbg("%s - urb shuttingdown with status: %d",
|
dbg("%s - urb shuttingdown with status: %d",
|
||||||
__FUNCTION__, status);
|
__func__, status);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
dbg("%s - nonzero urb status received: %d",
|
dbg("%s - nonzero urb status received: %d",
|
||||||
__FUNCTION__, status);
|
__func__, status);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ static void appledisplay_complete(struct urb *urb)
|
|||||||
retval = usb_submit_urb(pdata->urb, GFP_ATOMIC);
|
retval = usb_submit_urb(pdata->urb, GFP_ATOMIC);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
err("%s - usb_submit_urb failed with result %d",
|
err("%s - usb_submit_urb failed with result %d",
|
||||||
__FUNCTION__, retval);
|
__func__, retval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
/* Debug support */
|
/* Debug support */
|
||||||
@ -232,7 +233,7 @@ typedef struct auerscon
|
|||||||
/* USB device context */
|
/* USB device context */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
struct semaphore mutex; /* protection in user context */
|
struct mutex mutex; /* protection in user context */
|
||||||
char name[20]; /* name of the /dev/usb entry */
|
char name[20]; /* name of the /dev/usb entry */
|
||||||
unsigned int dtindex; /* index in the device table */
|
unsigned int dtindex; /* index in the device table */
|
||||||
struct usb_device * usbdev; /* USB device handle */
|
struct usb_device * usbdev; /* USB device handle */
|
||||||
@ -253,12 +254,12 @@ typedef struct
|
|||||||
/* character device context */
|
/* character device context */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
struct semaphore mutex; /* protection in user context */
|
struct mutex mutex; /* protection in user context */
|
||||||
pauerswald_t auerdev; /* context pointer of assigned device */
|
pauerswald_t auerdev; /* context pointer of assigned device */
|
||||||
auerbufctl_t bufctl; /* controls the buffer chain */
|
auerbufctl_t bufctl; /* controls the buffer chain */
|
||||||
auerscon_t scontext; /* service context */
|
auerscon_t scontext; /* service context */
|
||||||
wait_queue_head_t readwait; /* for synchronous reading */
|
wait_queue_head_t readwait; /* for synchronous reading */
|
||||||
struct semaphore readmutex; /* protection against multiple reads */
|
struct mutex readmutex; /* protection against multiple reads */
|
||||||
pauerbuf_t readbuf; /* buffer held for partial reading */
|
pauerbuf_t readbuf; /* buffer held for partial reading */
|
||||||
unsigned int readoffset; /* current offset in readbuf */
|
unsigned int readoffset; /* current offset in readbuf */
|
||||||
unsigned int removed; /* is != 0 if device is removed */
|
unsigned int removed; /* is != 0 if device is removed */
|
||||||
@ -283,7 +284,7 @@ static void auerchain_complete (struct urb * urb)
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* get pointer to element and to chain */
|
/* get pointer to element and to chain */
|
||||||
pauerchainelement_t acep = (pauerchainelement_t) urb->context;
|
pauerchainelement_t acep = urb->context;
|
||||||
pauerchain_t acp = acep->chain;
|
pauerchain_t acp = acep->chain;
|
||||||
|
|
||||||
/* restore original entries in urb */
|
/* restore original entries in urb */
|
||||||
@ -593,7 +594,7 @@ static int auerchain_setup (pauerchain_t acp, unsigned int numElements)
|
|||||||
/* completion handler for synchronous chained URBs */
|
/* completion handler for synchronous chained URBs */
|
||||||
static void auerchain_blocking_completion (struct urb *urb)
|
static void auerchain_blocking_completion (struct urb *urb)
|
||||||
{
|
{
|
||||||
pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context;
|
pauerchain_chs_t pchs = urb->context;
|
||||||
pchs->done = 1;
|
pchs->done = 1;
|
||||||
wmb();
|
wmb();
|
||||||
wake_up (&pchs->wqh);
|
wake_up (&pchs->wqh);
|
||||||
@ -846,7 +847,7 @@ static int auerswald_status_retry (int status)
|
|||||||
/* Completion of asynchronous write block */
|
/* Completion of asynchronous write block */
|
||||||
static void auerchar_ctrlwrite_complete (struct urb * urb)
|
static void auerchar_ctrlwrite_complete (struct urb * urb)
|
||||||
{
|
{
|
||||||
pauerbuf_t bp = (pauerbuf_t) urb->context;
|
pauerbuf_t bp = urb->context;
|
||||||
pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
|
pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
|
||||||
dbg ("auerchar_ctrlwrite_complete called");
|
dbg ("auerchar_ctrlwrite_complete called");
|
||||||
|
|
||||||
@ -859,7 +860,7 @@ static void auerchar_ctrlwrite_complete (struct urb * urb)
|
|||||||
/* Completion handler for dummy retry packet */
|
/* Completion handler for dummy retry packet */
|
||||||
static void auerswald_ctrlread_wretcomplete (struct urb * urb)
|
static void auerswald_ctrlread_wretcomplete (struct urb * urb)
|
||||||
{
|
{
|
||||||
pauerbuf_t bp = (pauerbuf_t) urb->context;
|
pauerbuf_t bp = urb->context;
|
||||||
pauerswald_t cp;
|
pauerswald_t cp;
|
||||||
int ret;
|
int ret;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
@ -903,7 +904,7 @@ static void auerswald_ctrlread_complete (struct urb * urb)
|
|||||||
unsigned int serviceid;
|
unsigned int serviceid;
|
||||||
pauerswald_t cp;
|
pauerswald_t cp;
|
||||||
pauerscon_t scp;
|
pauerscon_t scp;
|
||||||
pauerbuf_t bp = (pauerbuf_t) urb->context;
|
pauerbuf_t bp = urb->context;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -980,9 +981,9 @@ static void auerswald_int_complete (struct urb * urb)
|
|||||||
int ret;
|
int ret;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
pauerbuf_t bp = NULL;
|
pauerbuf_t bp = NULL;
|
||||||
pauerswald_t cp = (pauerswald_t) urb->context;
|
pauerswald_t cp = urb->context;
|
||||||
|
|
||||||
dbg ("%s called", __FUNCTION__);
|
dbg ("%s called", __func__);
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -992,10 +993,10 @@ static void auerswald_int_complete (struct urb * urb)
|
|||||||
case -ENOENT:
|
case -ENOENT:
|
||||||
case -ESHUTDOWN:
|
case -ESHUTDOWN:
|
||||||
/* this urb is terminated, clean up */
|
/* this urb is terminated, clean up */
|
||||||
dbg("%s - urb shutting down with status: %d", __FUNCTION__, status);
|
dbg("%s - urb shutting down with status: %d", __func__, status);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
dbg("%s - nonzero urb status received: %d", __FUNCTION__, status);
|
dbg("%s - nonzero urb status received: %d", __func__, status);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1080,7 +1081,7 @@ static void auerswald_int_complete (struct urb * urb)
|
|||||||
ret = usb_submit_urb (urb, GFP_ATOMIC);
|
ret = usb_submit_urb (urb, GFP_ATOMIC);
|
||||||
if (ret)
|
if (ret)
|
||||||
err ("%s - usb_submit_urb failed with result %d",
|
err ("%s - usb_submit_urb failed with result %d",
|
||||||
__FUNCTION__, ret);
|
__func__, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* int memory deallocation
|
/* int memory deallocation
|
||||||
@ -1376,7 +1377,7 @@ static int auerchar_open (struct inode *inode, struct file *file)
|
|||||||
if (cp == NULL) {
|
if (cp == NULL) {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
if (down_interruptible (&cp->mutex)) {
|
if (mutex_lock_interruptible(&cp->mutex)) {
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1389,8 +1390,8 @@ static int auerchar_open (struct inode *inode, struct file *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize device descriptor */
|
/* Initialize device descriptor */
|
||||||
init_MUTEX( &ccp->mutex);
|
mutex_init(&ccp->mutex);
|
||||||
init_MUTEX( &ccp->readmutex);
|
mutex_init(&ccp->readmutex);
|
||||||
auerbuf_init (&ccp->bufctl);
|
auerbuf_init (&ccp->bufctl);
|
||||||
ccp->scontext.id = AUH_UNASSIGNED;
|
ccp->scontext.id = AUH_UNASSIGNED;
|
||||||
ccp->scontext.dispatch = auerchar_ctrlread_dispatch;
|
ccp->scontext.dispatch = auerchar_ctrlread_dispatch;
|
||||||
@ -1405,7 +1406,7 @@ static int auerchar_open (struct inode *inode, struct file *file)
|
|||||||
cp->open_count++;
|
cp->open_count++;
|
||||||
ccp->auerdev = cp;
|
ccp->auerdev = cp;
|
||||||
dbg("open %s as /dev/%s", cp->dev_desc, cp->name);
|
dbg("open %s as /dev/%s", cp->dev_desc, cp->name);
|
||||||
up (&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
|
|
||||||
/* file IO stuff */
|
/* file IO stuff */
|
||||||
file->f_pos = 0;
|
file->f_pos = 0;
|
||||||
@ -1413,7 +1414,7 @@ static int auerchar_open (struct inode *inode, struct file *file)
|
|||||||
return nonseekable_open(inode, file);
|
return nonseekable_open(inode, file);
|
||||||
|
|
||||||
/* Error exit */
|
/* Error exit */
|
||||||
ofail: up (&cp->mutex);
|
ofail: mutex_unlock(&cp->mutex);
|
||||||
auerchar_delete (ccp);
|
auerchar_delete (ccp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1432,23 +1433,23 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
|
|||||||
dbg ("ioctl");
|
dbg ("ioctl");
|
||||||
|
|
||||||
/* get the mutexes */
|
/* get the mutexes */
|
||||||
if (down_interruptible (&ccp->mutex)) {
|
if (mutex_lock_interruptible(&ccp->mutex)) {
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
cp = ccp->auerdev;
|
cp = ccp->auerdev;
|
||||||
if (!cp) {
|
if (!cp) {
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
if (down_interruptible (&cp->mutex)) {
|
if (mutex_lock_interruptible(&cp->mutex)) {
|
||||||
up(&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for removal */
|
/* Check for removal */
|
||||||
if (!cp->usbdev) {
|
if (!cp->usbdev) {
|
||||||
up(&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
up(&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1550,8 +1551,8 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* release the mutexes */
|
/* release the mutexes */
|
||||||
up(&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
up(&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1574,18 +1575,18 @@ static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* get the mutex */
|
/* get the mutex */
|
||||||
if (down_interruptible (&ccp->mutex))
|
if (mutex_lock_interruptible(&ccp->mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
/* Can we expect to read something? */
|
/* Can we expect to read something? */
|
||||||
if (ccp->scontext.id == AUH_UNASSIGNED) {
|
if (ccp->scontext.id == AUH_UNASSIGNED) {
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only one reader per device allowed */
|
/* only one reader per device allowed */
|
||||||
if (down_interruptible (&ccp->readmutex)) {
|
if (mutex_lock_interruptible(&ccp->readmutex)) {
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1602,8 +1603,8 @@ static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count,
|
|||||||
if (count) {
|
if (count) {
|
||||||
if (copy_to_user (buf, bp->bufp+ccp->readoffset, count)) {
|
if (copy_to_user (buf, bp->bufp+ccp->readoffset, count)) {
|
||||||
dbg ("auerswald_read: copy_to_user failed");
|
dbg ("auerswald_read: copy_to_user failed");
|
||||||
up (&ccp->readmutex);
|
mutex_unlock(&ccp->readmutex);
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1617,8 +1618,8 @@ static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count,
|
|||||||
}
|
}
|
||||||
/* return with number of bytes read */
|
/* return with number of bytes read */
|
||||||
if (count) {
|
if (count) {
|
||||||
up (&ccp->readmutex);
|
mutex_unlock(&ccp->readmutex);
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1654,29 +1655,29 @@ static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count,
|
|||||||
dbg ("No read buffer available, returning -EAGAIN");
|
dbg ("No read buffer available, returning -EAGAIN");
|
||||||
set_current_state (TASK_RUNNING);
|
set_current_state (TASK_RUNNING);
|
||||||
remove_wait_queue (&ccp->readwait, &wait);
|
remove_wait_queue (&ccp->readwait, &wait);
|
||||||
up (&ccp->readmutex);
|
mutex_unlock(&ccp->readmutex);
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -EAGAIN; /* nonblocking, no data available */
|
return -EAGAIN; /* nonblocking, no data available */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* yes, we should wait! */
|
/* yes, we should wait! */
|
||||||
up (&ccp->mutex); /* allow other operations while we wait */
|
mutex_unlock(&ccp->mutex); /* allow other operations while we wait */
|
||||||
schedule();
|
schedule();
|
||||||
remove_wait_queue (&ccp->readwait, &wait);
|
remove_wait_queue (&ccp->readwait, &wait);
|
||||||
if (signal_pending (current)) {
|
if (signal_pending (current)) {
|
||||||
/* waked up by a signal */
|
/* waked up by a signal */
|
||||||
up (&ccp->readmutex);
|
mutex_unlock(&ccp->readmutex);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Anything left to read? */
|
/* Anything left to read? */
|
||||||
if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) {
|
if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) {
|
||||||
up (&ccp->readmutex);
|
mutex_unlock(&ccp->readmutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (down_interruptible (&ccp->mutex)) {
|
if (mutex_lock_interruptible(&ccp->mutex)) {
|
||||||
up (&ccp->readmutex);
|
mutex_unlock(&ccp->readmutex);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1707,27 +1708,27 @@ static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t
|
|||||||
|
|
||||||
write_again:
|
write_again:
|
||||||
/* get the mutex */
|
/* get the mutex */
|
||||||
if (down_interruptible (&ccp->mutex))
|
if (mutex_lock_interruptible(&ccp->mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
/* Can we expect to write something? */
|
/* Can we expect to write something? */
|
||||||
if (ccp->scontext.id == AUH_UNASSIGNED) {
|
if (ccp->scontext.id == AUH_UNASSIGNED) {
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
cp = ccp->auerdev;
|
cp = ccp->auerdev;
|
||||||
if (!cp) {
|
if (!cp) {
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
if (down_interruptible (&cp->mutex)) {
|
if (mutex_lock_interruptible(&cp->mutex)) {
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
if (!cp->usbdev) {
|
if (!cp->usbdev) {
|
||||||
up (&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
/* Prepare for sleep */
|
/* Prepare for sleep */
|
||||||
@ -1750,8 +1751,8 @@ static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t
|
|||||||
|
|
||||||
/* are there any buffers left? */
|
/* are there any buffers left? */
|
||||||
if (!bp) {
|
if (!bp) {
|
||||||
up (&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
|
|
||||||
/* NONBLOCK: don't wait */
|
/* NONBLOCK: don't wait */
|
||||||
if (file->f_flags & O_NONBLOCK) {
|
if (file->f_flags & O_NONBLOCK) {
|
||||||
@ -1783,8 +1784,8 @@ static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t
|
|||||||
auerbuf_releasebuf (bp);
|
auerbuf_releasebuf (bp);
|
||||||
/* Wake up all processes waiting for a buffer */
|
/* Wake up all processes waiting for a buffer */
|
||||||
wake_up (&cp->bufferwait);
|
wake_up (&cp->bufferwait);
|
||||||
up (&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1803,18 +1804,18 @@ static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t
|
|||||||
auerchar_ctrlwrite_complete, bp);
|
auerchar_ctrlwrite_complete, bp);
|
||||||
/* up we go */
|
/* up we go */
|
||||||
ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
|
ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
|
||||||
up (&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret);
|
dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret);
|
||||||
auerbuf_releasebuf (bp);
|
auerbuf_releasebuf (bp);
|
||||||
/* Wake up all processes waiting for a buffer */
|
/* Wake up all processes waiting for a buffer */
|
||||||
wake_up (&cp->bufferwait);
|
wake_up (&cp->bufferwait);
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dbg ("auerchar_write: Write OK");
|
dbg ("auerchar_write: Write OK");
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1827,24 +1828,24 @@ static int auerchar_release (struct inode *inode, struct file *file)
|
|||||||
pauerswald_t cp;
|
pauerswald_t cp;
|
||||||
dbg("release");
|
dbg("release");
|
||||||
|
|
||||||
down(&ccp->mutex);
|
mutex_lock(&ccp->mutex);
|
||||||
cp = ccp->auerdev;
|
cp = ccp->auerdev;
|
||||||
if (cp) {
|
if (cp) {
|
||||||
down(&cp->mutex);
|
mutex_lock(&cp->mutex);
|
||||||
/* remove an open service */
|
/* remove an open service */
|
||||||
auerswald_removeservice (cp, &ccp->scontext);
|
auerswald_removeservice (cp, &ccp->scontext);
|
||||||
/* detach from device */
|
/* detach from device */
|
||||||
if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) {
|
if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) {
|
||||||
/* usb device waits for removal */
|
/* usb device waits for removal */
|
||||||
up (&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
auerswald_delete (cp);
|
auerswald_delete (cp);
|
||||||
} else {
|
} else {
|
||||||
up (&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
}
|
}
|
||||||
cp = NULL;
|
cp = NULL;
|
||||||
ccp->auerdev = NULL;
|
ccp->auerdev = NULL;
|
||||||
}
|
}
|
||||||
up (&ccp->mutex);
|
mutex_unlock(&ccp->mutex);
|
||||||
auerchar_delete (ccp);
|
auerchar_delete (ccp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1917,7 +1918,7 @@ static int auerswald_probe (struct usb_interface *intf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize device descriptor */
|
/* Initialize device descriptor */
|
||||||
init_MUTEX (&cp->mutex);
|
mutex_init(&cp->mutex);
|
||||||
cp->usbdev = usbdev;
|
cp->usbdev = usbdev;
|
||||||
auerchain_init (&cp->controlchain);
|
auerchain_init (&cp->controlchain);
|
||||||
auerbuf_init (&cp->bufctl);
|
auerbuf_init (&cp->bufctl);
|
||||||
@ -2042,7 +2043,7 @@ static void auerswald_disconnect (struct usb_interface *intf)
|
|||||||
/* give back our USB minor number */
|
/* give back our USB minor number */
|
||||||
usb_deregister_dev(intf, &auerswald_class);
|
usb_deregister_dev(intf, &auerswald_class);
|
||||||
|
|
||||||
down (&cp->mutex);
|
mutex_lock(&cp->mutex);
|
||||||
info ("device /dev/%s now disconnecting", cp->name);
|
info ("device /dev/%s now disconnecting", cp->name);
|
||||||
|
|
||||||
/* Stop the interrupt endpoint */
|
/* Stop the interrupt endpoint */
|
||||||
@ -2057,16 +2058,18 @@ static void auerswald_disconnect (struct usb_interface *intf)
|
|||||||
|
|
||||||
if (cp->open_count == 0) {
|
if (cp->open_count == 0) {
|
||||||
/* nobody is using this device. So we can clean up now */
|
/* nobody is using this device. So we can clean up now */
|
||||||
up (&cp->mutex);/* up() is possible here because no other task
|
mutex_unlock(&cp->mutex);
|
||||||
can open the device (see above). I don't want
|
/* mutex_unlock() is possible here because no other task
|
||||||
to kfree() a locked mutex. */
|
can open the device (see above). I don't want
|
||||||
|
to kfree() a locked mutex. */
|
||||||
|
|
||||||
auerswald_delete (cp);
|
auerswald_delete (cp);
|
||||||
} else {
|
} else {
|
||||||
/* device is used. Remove the pointer to the
|
/* device is used. Remove the pointer to the
|
||||||
usb device (it's not valid any more). The last
|
usb device (it's not valid any more). The last
|
||||||
release() will do the clean up */
|
release() will do the clean up */
|
||||||
cp->usbdev = NULL;
|
cp->usbdev = NULL;
|
||||||
up (&cp->mutex);
|
mutex_unlock(&cp->mutex);
|
||||||
/* Terminate waiting writers */
|
/* Terminate waiting writers */
|
||||||
wake_up (&cp->bufferwait);
|
wake_up (&cp->bufferwait);
|
||||||
/* Inform all waiting readers */
|
/* Inform all waiting readers */
|
||||||
|
@ -70,8 +70,8 @@ static int emi26_writememory (struct usb_device *dev, int address, unsigned char
|
|||||||
static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit)
|
static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit)
|
||||||
{
|
{
|
||||||
int response;
|
int response;
|
||||||
info("%s - %d", __FUNCTION__, reset_bit);
|
info("%s - %d", __func__, reset_bit);
|
||||||
/* printk(KERN_DEBUG "%s - %d", __FUNCTION__, reset_bit); */
|
/* printk(KERN_DEBUG "%s - %d", __func__, reset_bit); */
|
||||||
response = emi26_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
|
response = emi26_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
|
||||||
if (response < 0) {
|
if (response < 0) {
|
||||||
err("emi26: set_reset (%d) failed", reset_bit);
|
err("emi26: set_reset (%d) failed", reset_bit);
|
||||||
@ -91,7 +91,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
|
|
||||||
buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
|
buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
err( "%s - error loading firmware: error = %d", __FUNCTION__, -ENOMEM);
|
err( "%s - error loading firmware: error = %d", __func__, -ENOMEM);
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
/* Assert reset (stop the CPU in the EMI) */
|
/* Assert reset (stop the CPU in the EMI) */
|
||||||
err = emi26_set_reset(dev,1);
|
err = emi26_set_reset(dev,1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err( "%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err( "%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
for (i=0; g_Loader[i].type == 0; i++) {
|
for (i=0; g_Loader[i].type == 0; i++) {
|
||||||
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
|
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
/* De-assert reset (let the CPU run) */
|
/* De-assert reset (let the CPU run) */
|
||||||
err = emi26_set_reset(dev,0);
|
err = emi26_set_reset(dev,0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
msleep(250); /* let device settle */
|
msleep(250); /* let device settle */
|
||||||
@ -135,7 +135,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
}
|
}
|
||||||
err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
|
err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
} while (i > 0);
|
} while (i > 0);
|
||||||
@ -143,7 +143,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
/* Assert reset (stop the CPU in the EMI) */
|
/* Assert reset (stop the CPU in the EMI) */
|
||||||
err = emi26_set_reset(dev,1);
|
err = emi26_set_reset(dev,1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
for (i=0; g_Loader[i].type == 0; i++) {
|
for (i=0; g_Loader[i].type == 0; i++) {
|
||||||
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
|
err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
/* De-assert reset (let the CPU run) */
|
/* De-assert reset (let the CPU run) */
|
||||||
err = emi26_set_reset(dev,0);
|
err = emi26_set_reset(dev,0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
if (!INTERNAL_RAM(g_Firmware[i].address)) {
|
if (!INTERNAL_RAM(g_Firmware[i].address)) {
|
||||||
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL);
|
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
/* Assert reset (stop the CPU in the EMI) */
|
/* Assert reset (stop the CPU in the EMI) */
|
||||||
err = emi26_set_reset(dev,1);
|
err = emi26_set_reset(dev,1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
if (INTERNAL_RAM(g_Firmware[i].address)) {
|
if (INTERNAL_RAM(g_Firmware[i].address)) {
|
||||||
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL);
|
err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ static int emi26_load_firmware (struct usb_device *dev)
|
|||||||
/* De-assert reset (let the CPU run) */
|
/* De-assert reset (let the CPU run) */
|
||||||
err = emi26_set_reset(dev,0);
|
err = emi26_set_reset(dev,0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
msleep(250); /* let device settle */
|
msleep(250); /* let device settle */
|
||||||
@ -221,7 +221,7 @@ static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *i
|
|||||||
{
|
{
|
||||||
struct usb_device *dev = interface_to_usbdev(intf);
|
struct usb_device *dev = interface_to_usbdev(intf);
|
||||||
|
|
||||||
info("%s start", __FUNCTION__);
|
info("%s start", __func__);
|
||||||
|
|
||||||
emi26_load_firmware(dev);
|
emi26_load_firmware(dev);
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ static int emi62_writememory (struct usb_device *dev, int address, unsigned char
|
|||||||
static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit)
|
static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit)
|
||||||
{
|
{
|
||||||
int response;
|
int response;
|
||||||
info("%s - %d", __FUNCTION__, reset_bit);
|
info("%s - %d", __func__, reset_bit);
|
||||||
|
|
||||||
response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
|
response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
|
||||||
if (response < 0) {
|
if (response < 0) {
|
||||||
@ -100,7 +100,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
dev_dbg(&dev->dev, "load_firmware\n");
|
dev_dbg(&dev->dev, "load_firmware\n");
|
||||||
buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
|
buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
err( "%s - error loading firmware: error = %d", __FUNCTION__, -ENOMEM);
|
err( "%s - error loading firmware: error = %d", __func__, -ENOMEM);
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
/* Assert reset (stop the CPU in the EMI) */
|
/* Assert reset (stop the CPU in the EMI) */
|
||||||
err = emi62_set_reset(dev,1);
|
err = emi62_set_reset(dev,1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
for (i=0; g_emi62_loader[i].type == 0; i++) {
|
for (i=0; g_emi62_loader[i].type == 0; i++) {
|
||||||
err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL);
|
err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
/* De-assert reset (let the CPU run) */
|
/* De-assert reset (let the CPU run) */
|
||||||
err = emi62_set_reset(dev,0);
|
err = emi62_set_reset(dev,0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
msleep(250); /* let device settle */
|
msleep(250); /* let device settle */
|
||||||
@ -144,7 +144,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
}
|
}
|
||||||
err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
|
err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
} while (i > 0);
|
} while (i > 0);
|
||||||
@ -152,7 +152,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
/* Assert reset (stop the CPU in the EMI) */
|
/* Assert reset (stop the CPU in the EMI) */
|
||||||
err = emi62_set_reset(dev,1);
|
err = emi62_set_reset(dev,1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
for (i=0; g_emi62_loader[i].type == 0; i++) {
|
for (i=0; g_emi62_loader[i].type == 0; i++) {
|
||||||
err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL);
|
err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
/* De-assert reset (let the CPU run) */
|
/* De-assert reset (let the CPU run) */
|
||||||
err = emi62_set_reset(dev,0);
|
err = emi62_set_reset(dev,0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
msleep(250); /* let device settle */
|
msleep(250); /* let device settle */
|
||||||
@ -181,7 +181,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
if (!INTERNAL_RAM(g_HexSpdifFw62[i].address)) {
|
if (!INTERNAL_RAM(g_HexSpdifFw62[i].address)) {
|
||||||
err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_EXTERNAL);
|
err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_EXTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,7 +191,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
if (!INTERNAL_RAM(g_HexMidiFw62[i].address)) {
|
if (!INTERNAL_RAM(g_HexMidiFw62[i].address)) {
|
||||||
err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_EXTERNAL);
|
err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_EXTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d\n", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d\n", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
/* Assert reset (stop the CPU in the EMI) */
|
/* Assert reset (stop the CPU in the EMI) */
|
||||||
err = emi62_set_reset(dev,1);
|
err = emi62_set_reset(dev,1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
if (INTERNAL_RAM(g_HexSpdifFw62[i].address)) {
|
if (INTERNAL_RAM(g_HexSpdifFw62[i].address)) {
|
||||||
err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_INTERNAL);
|
err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_INTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
if (INTERNAL_RAM(g_HexMidiFw62[i].address)) {
|
if (INTERNAL_RAM(g_HexMidiFw62[i].address)) {
|
||||||
err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_INTERNAL);
|
err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_INTERNAL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d\n", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d\n", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,7 +231,7 @@ static int emi62_load_firmware (struct usb_device *dev)
|
|||||||
/* De-assert reset (let the CPU run) */
|
/* De-assert reset (let the CPU run) */
|
||||||
err = emi62_set_reset(dev,0);
|
err = emi62_set_reset(dev,0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
|
err("%s - error loading firmware: error = %d", __func__, err);
|
||||||
goto wraperr;
|
goto wraperr;
|
||||||
}
|
}
|
||||||
msleep(250); /* let device settle */
|
msleep(250); /* let device settle */
|
||||||
@ -260,7 +260,7 @@ static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *i
|
|||||||
struct usb_device *dev = interface_to_usbdev(intf);
|
struct usb_device *dev = interface_to_usbdev(intf);
|
||||||
dev_dbg(&intf->dev, "emi62_probe\n");
|
dev_dbg(&intf->dev, "emi62_probe\n");
|
||||||
|
|
||||||
info("%s start", __FUNCTION__);
|
info("%s start", __func__);
|
||||||
|
|
||||||
emi62_load_firmware(dev);
|
emi62_load_firmware(dev);
|
||||||
|
|
||||||
|
@ -746,7 +746,7 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer,
|
|||||||
|
|
||||||
static void ftdi_elan_write_bulk_callback(struct urb *urb)
|
static void ftdi_elan_write_bulk_callback(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context;
|
struct usb_ftdi *ftdi = urb->context;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
|
|
||||||
if (status && !(status == -ENOENT || status == -ECONNRESET ||
|
if (status && !(status == -ENOENT || status == -ECONNRESET ||
|
||||||
|
@ -154,7 +154,7 @@ MODULE_DEVICE_TABLE(usb, iowarrior_ids);
|
|||||||
*/
|
*/
|
||||||
static void iowarrior_callback(struct urb *urb)
|
static void iowarrior_callback(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct iowarrior *dev = (struct iowarrior *)urb->context;
|
struct iowarrior *dev = urb->context;
|
||||||
int intr_idx;
|
int intr_idx;
|
||||||
int read_idx;
|
int read_idx;
|
||||||
int aux_idx;
|
int aux_idx;
|
||||||
@ -218,7 +218,7 @@ static void iowarrior_callback(struct urb *urb)
|
|||||||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||||
if (retval)
|
if (retval)
|
||||||
dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n",
|
dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n",
|
||||||
__FUNCTION__, retval);
|
__func__, retval);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ static void iowarrior_write_callback(struct urb *urb)
|
|||||||
struct iowarrior *dev;
|
struct iowarrior *dev;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
|
|
||||||
dev = (struct iowarrior *)urb->context;
|
dev = urb->context;
|
||||||
/* sync/async unlink faults aren't errors */
|
/* sync/async unlink faults aren't errors */
|
||||||
if (status &&
|
if (status &&
|
||||||
!(status == -ENOENT ||
|
!(status == -ENOENT ||
|
||||||
@ -453,7 +453,7 @@ static ssize_t iowarrior_write(struct file *file,
|
|||||||
default:
|
default:
|
||||||
/* what do we have here ? An unsupported Product-ID ? */
|
/* what do we have here ? An unsupported Product-ID ? */
|
||||||
dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n",
|
dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n",
|
||||||
__FUNCTION__, dev->product_id);
|
__func__, dev->product_id);
|
||||||
retval = -EFAULT;
|
retval = -EFAULT;
|
||||||
goto exit;
|
goto exit;
|
||||||
break;
|
break;
|
||||||
@ -604,7 +604,7 @@ static int iowarrior_open(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
interface = usb_find_interface(&iowarrior_driver, subminor);
|
interface = usb_find_interface(&iowarrior_driver, subminor);
|
||||||
if (!interface) {
|
if (!interface) {
|
||||||
err("%s - error, can't find device for minor %d", __FUNCTION__,
|
err("%s - error, can't find device for minor %d", __func__,
|
||||||
subminor);
|
subminor);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
|
|||||||
goto exit;
|
goto exit;
|
||||||
} else {
|
} else {
|
||||||
dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
|
dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
|
||||||
__FUNCTION__, status);
|
__func__, status);
|
||||||
spin_lock(&dev->rbsl);
|
spin_lock(&dev->rbsl);
|
||||||
goto resubmit; /* maybe we can recover */
|
goto resubmit; /* maybe we can recover */
|
||||||
}
|
}
|
||||||
@ -247,7 +247,7 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
|
|||||||
memcpy(actual_buffer+1, dev->interrupt_in_buffer, urb->actual_length);
|
memcpy(actual_buffer+1, dev->interrupt_in_buffer, urb->actual_length);
|
||||||
dev->ring_head = next_ring_head;
|
dev->ring_head = next_ring_head;
|
||||||
dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
|
dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
|
||||||
__FUNCTION__, urb->actual_length);
|
__func__, urb->actual_length);
|
||||||
} else {
|
} else {
|
||||||
dev_warn(&dev->intf->dev,
|
dev_warn(&dev->intf->dev,
|
||||||
"Ring buffer overflow, %d bytes dropped\n",
|
"Ring buffer overflow, %d bytes dropped\n",
|
||||||
@ -286,7 +286,7 @@ static void ld_usb_interrupt_out_callback(struct urb *urb)
|
|||||||
status == -ESHUTDOWN))
|
status == -ESHUTDOWN))
|
||||||
dbg_info(&dev->intf->dev,
|
dbg_info(&dev->intf->dev,
|
||||||
"%s - nonzero write interrupt status received: %d\n",
|
"%s - nonzero write interrupt status received: %d\n",
|
||||||
__FUNCTION__, status);
|
__func__, status);
|
||||||
|
|
||||||
dev->interrupt_out_busy = 0;
|
dev->interrupt_out_busy = 0;
|
||||||
wake_up_interruptible(&dev->write_wait);
|
wake_up_interruptible(&dev->write_wait);
|
||||||
@ -309,7 +309,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
if (!interface) {
|
if (!interface) {
|
||||||
err("%s - error, can't find device for minor %d\n",
|
err("%s - error, can't find device for minor %d\n",
|
||||||
__FUNCTION__, subminor);
|
__func__, subminor);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,7 +556,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
|
|||||||
bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
|
bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
|
||||||
if (bytes_to_write < count)
|
if (bytes_to_write < count)
|
||||||
dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
|
dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
|
||||||
dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __FUNCTION__, count, bytes_to_write);
|
dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write);
|
||||||
|
|
||||||
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
|
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
|
||||||
retval = -EFAULT;
|
retval = -EFAULT;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
* - imported into lejos project
|
* - imported into lejos project
|
||||||
* - changed wake_up to wake_up_interruptible
|
* - changed wake_up to wake_up_interruptible
|
||||||
* - changed to use lego0 rather than tower0
|
* - changed to use lego0 rather than tower0
|
||||||
* - changed dbg() to use __func__ rather than deprecated __FUNCTION__
|
* - changed dbg() to use __func__ rather than deprecated __func__
|
||||||
* 2003-01-12 - 0.53 david (david@csse.uwa.edu.au)
|
* 2003-01-12 - 0.53 david (david@csse.uwa.edu.au)
|
||||||
* - changed read and write to write everything or
|
* - changed read and write to write everything or
|
||||||
* timeout (from a patch by Chris Riesen and Brett Thaeler driver)
|
* timeout (from a patch by Chris Riesen and Brett Thaeler driver)
|
||||||
@ -49,7 +49,7 @@
|
|||||||
* - added poll
|
* - added poll
|
||||||
* - forbid seeking
|
* - forbid seeking
|
||||||
* - added nonblocking I/O
|
* - added nonblocking I/O
|
||||||
* - changed back __func__ to __FUNCTION__
|
* - changed back __func__ to __func__
|
||||||
* - read and log tower firmware version
|
* - read and log tower firmware version
|
||||||
* - reset tower on probe, avoids failure of first write
|
* - reset tower on probe, avoids failure of first write
|
||||||
* 2004-03-09 - 0.7 Juergen Stuber <starblue@users.sourceforge.net>
|
* 2004-03-09 - 0.7 Juergen Stuber <starblue@users.sourceforge.net>
|
||||||
@ -309,7 +309,7 @@ static inline void lego_usb_tower_debug_data (int level, const char *function, i
|
|||||||
*/
|
*/
|
||||||
static inline void tower_delete (struct lego_usb_tower *dev)
|
static inline void tower_delete (struct lego_usb_tower *dev)
|
||||||
{
|
{
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
tower_abort_transfers (dev);
|
tower_abort_transfers (dev);
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ static inline void tower_delete (struct lego_usb_tower *dev)
|
|||||||
kfree (dev->interrupt_out_buffer);
|
kfree (dev->interrupt_out_buffer);
|
||||||
kfree (dev);
|
kfree (dev);
|
||||||
|
|
||||||
dbg(2, "%s: leave", __FUNCTION__);
|
dbg(2, "%s: leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -337,7 +337,7 @@ static int tower_open (struct inode *inode, struct file *file)
|
|||||||
struct tower_reset_reply reset_reply;
|
struct tower_reset_reply reset_reply;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
nonseekable_open(inode, file);
|
nonseekable_open(inode, file);
|
||||||
subminor = iminor(inode);
|
subminor = iminor(inode);
|
||||||
@ -346,7 +346,7 @@ static int tower_open (struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
if (!interface) {
|
if (!interface) {
|
||||||
err ("%s - error, can't find device for minor %d",
|
err ("%s - error, can't find device for minor %d",
|
||||||
__FUNCTION__, subminor);
|
__func__, subminor);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -424,7 +424,7 @@ static int tower_open (struct inode *inode, struct file *file)
|
|||||||
mutex_unlock(&dev->lock);
|
mutex_unlock(&dev->lock);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval);
|
dbg(2, "%s: leave, return value %d ", __func__, retval);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -437,12 +437,12 @@ static int tower_release (struct inode *inode, struct file *file)
|
|||||||
struct lego_usb_tower *dev;
|
struct lego_usb_tower *dev;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
dev = (struct lego_usb_tower *)file->private_data;
|
dev = (struct lego_usb_tower *)file->private_data;
|
||||||
|
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
dbg(1, "%s: object is NULL", __FUNCTION__);
|
dbg(1, "%s: object is NULL", __func__);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto exit_nolock;
|
goto exit_nolock;
|
||||||
}
|
}
|
||||||
@ -454,7 +454,7 @@ static int tower_release (struct inode *inode, struct file *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dev->open_count != 1) {
|
if (dev->open_count != 1) {
|
||||||
dbg(1, "%s: device not opened exactly once", __FUNCTION__);
|
dbg(1, "%s: device not opened exactly once", __func__);
|
||||||
retval = -ENODEV;
|
retval = -ENODEV;
|
||||||
goto unlock_exit;
|
goto unlock_exit;
|
||||||
}
|
}
|
||||||
@ -480,7 +480,7 @@ static int tower_release (struct inode *inode, struct file *file)
|
|||||||
exit:
|
exit:
|
||||||
mutex_unlock(&open_disc_mutex);
|
mutex_unlock(&open_disc_mutex);
|
||||||
exit_nolock:
|
exit_nolock:
|
||||||
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
|
dbg(2, "%s: leave, return value %d", __func__, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,10 +491,10 @@ static int tower_release (struct inode *inode, struct file *file)
|
|||||||
*/
|
*/
|
||||||
static void tower_abort_transfers (struct lego_usb_tower *dev)
|
static void tower_abort_transfers (struct lego_usb_tower *dev)
|
||||||
{
|
{
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
dbg(1, "%s: dev is null", __FUNCTION__);
|
dbg(1, "%s: dev is null", __func__);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,7 +509,7 @@ static void tower_abort_transfers (struct lego_usb_tower *dev)
|
|||||||
usb_kill_urb(dev->interrupt_out_urb);
|
usb_kill_urb(dev->interrupt_out_urb);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
dbg(2, "%s: leave", __FUNCTION__);
|
dbg(2, "%s: leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -542,7 +542,7 @@ static unsigned int tower_poll (struct file *file, poll_table *wait)
|
|||||||
struct lego_usb_tower *dev;
|
struct lego_usb_tower *dev;
|
||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
|
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
dev = file->private_data;
|
dev = file->private_data;
|
||||||
|
|
||||||
@ -557,7 +557,7 @@ static unsigned int tower_poll (struct file *file, poll_table *wait)
|
|||||||
mask |= POLLOUT | POLLWRNORM;
|
mask |= POLLOUT | POLLWRNORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg(2, "%s: leave, mask = %d", __FUNCTION__, mask);
|
dbg(2, "%s: leave, mask = %d", __func__, mask);
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
@ -583,7 +583,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count,
|
|||||||
int retval = 0;
|
int retval = 0;
|
||||||
unsigned long timeout = 0;
|
unsigned long timeout = 0;
|
||||||
|
|
||||||
dbg(2, "%s: enter, count = %Zd", __FUNCTION__, count);
|
dbg(2, "%s: enter, count = %Zd", __func__, count);
|
||||||
|
|
||||||
dev = (struct lego_usb_tower *)file->private_data;
|
dev = (struct lego_usb_tower *)file->private_data;
|
||||||
|
|
||||||
@ -602,7 +602,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count,
|
|||||||
|
|
||||||
/* verify that we actually have some data to read */
|
/* verify that we actually have some data to read */
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
dbg(1, "%s: read request of 0 bytes", __FUNCTION__);
|
dbg(1, "%s: read request of 0 bytes", __func__);
|
||||||
goto unlock_exit;
|
goto unlock_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,7 +658,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count,
|
|||||||
mutex_unlock(&dev->lock);
|
mutex_unlock(&dev->lock);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
|
dbg(2, "%s: leave, return value %d", __func__, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,7 +672,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
|
|||||||
size_t bytes_to_write;
|
size_t bytes_to_write;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
dbg(2, "%s: enter, count = %Zd", __FUNCTION__, count);
|
dbg(2, "%s: enter, count = %Zd", __func__, count);
|
||||||
|
|
||||||
dev = (struct lego_usb_tower *)file->private_data;
|
dev = (struct lego_usb_tower *)file->private_data;
|
||||||
|
|
||||||
@ -691,7 +691,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
|
|||||||
|
|
||||||
/* verify that we actually have some data to write */
|
/* verify that we actually have some data to write */
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
dbg(1, "%s: write request of 0 bytes", __FUNCTION__);
|
dbg(1, "%s: write request of 0 bytes", __func__);
|
||||||
goto unlock_exit;
|
goto unlock_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,7 +709,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
|
|||||||
|
|
||||||
/* write the data into interrupt_out_buffer from userspace */
|
/* write the data into interrupt_out_buffer from userspace */
|
||||||
bytes_to_write = min_t(int, count, write_buffer_size);
|
bytes_to_write = min_t(int, count, write_buffer_size);
|
||||||
dbg(4, "%s: count = %Zd, bytes_to_write = %Zd", __FUNCTION__, count, bytes_to_write);
|
dbg(4, "%s: count = %Zd, bytes_to_write = %Zd", __func__, count, bytes_to_write);
|
||||||
|
|
||||||
if (copy_from_user (dev->interrupt_out_buffer, buffer, bytes_to_write)) {
|
if (copy_from_user (dev->interrupt_out_buffer, buffer, bytes_to_write)) {
|
||||||
retval = -EFAULT;
|
retval = -EFAULT;
|
||||||
@ -742,7 +742,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
|
|||||||
mutex_unlock(&dev->lock);
|
mutex_unlock(&dev->lock);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
|
dbg(2, "%s: leave, return value %d", __func__, retval);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -753,13 +753,13 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t
|
|||||||
*/
|
*/
|
||||||
static void tower_interrupt_in_callback (struct urb *urb)
|
static void tower_interrupt_in_callback (struct urb *urb)
|
||||||
{
|
{
|
||||||
struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context;
|
struct lego_usb_tower *dev = urb->context;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
dbg(4, "%s: enter, status %d", __FUNCTION__, status);
|
dbg(4, "%s: enter, status %d", __func__, status);
|
||||||
|
|
||||||
lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
|
lego_usb_tower_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
if (status == -ENOENT ||
|
if (status == -ENOENT ||
|
||||||
@ -767,7 +767,7 @@ static void tower_interrupt_in_callback (struct urb *urb)
|
|||||||
status == -ESHUTDOWN) {
|
status == -ESHUTDOWN) {
|
||||||
goto exit;
|
goto exit;
|
||||||
} else {
|
} else {
|
||||||
dbg(1, "%s: nonzero status received: %d", __FUNCTION__, status);
|
dbg(1, "%s: nonzero status received: %d", __func__, status);
|
||||||
goto resubmit; /* maybe we can recover */
|
goto resubmit; /* maybe we can recover */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -780,9 +780,9 @@ static void tower_interrupt_in_callback (struct urb *urb)
|
|||||||
urb->actual_length);
|
urb->actual_length);
|
||||||
dev->read_buffer_length += urb->actual_length;
|
dev->read_buffer_length += urb->actual_length;
|
||||||
dev->read_last_arrival = jiffies;
|
dev->read_last_arrival = jiffies;
|
||||||
dbg(3, "%s: received %d bytes", __FUNCTION__, urb->actual_length);
|
dbg(3, "%s: received %d bytes", __func__, urb->actual_length);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "%s: read_buffer overflow, %d bytes dropped", __FUNCTION__, urb->actual_length);
|
printk(KERN_WARNING "%s: read_buffer overflow, %d bytes dropped", __func__, urb->actual_length);
|
||||||
}
|
}
|
||||||
spin_unlock (&dev->read_buffer_lock);
|
spin_unlock (&dev->read_buffer_lock);
|
||||||
}
|
}
|
||||||
@ -792,7 +792,7 @@ static void tower_interrupt_in_callback (struct urb *urb)
|
|||||||
if (dev->interrupt_in_running && dev->udev) {
|
if (dev->interrupt_in_running && dev->udev) {
|
||||||
retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC);
|
retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
err("%s: usb_submit_urb failed (%d)", __FUNCTION__, retval);
|
err("%s: usb_submit_urb failed (%d)", __func__, retval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,8 +800,8 @@ static void tower_interrupt_in_callback (struct urb *urb)
|
|||||||
dev->interrupt_in_done = 1;
|
dev->interrupt_in_done = 1;
|
||||||
wake_up_interruptible (&dev->read_wait);
|
wake_up_interruptible (&dev->read_wait);
|
||||||
|
|
||||||
lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
|
lego_usb_tower_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer);
|
||||||
dbg(4, "%s: leave, status %d", __FUNCTION__, status);
|
dbg(4, "%s: leave, status %d", __func__, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -810,25 +810,25 @@ static void tower_interrupt_in_callback (struct urb *urb)
|
|||||||
*/
|
*/
|
||||||
static void tower_interrupt_out_callback (struct urb *urb)
|
static void tower_interrupt_out_callback (struct urb *urb)
|
||||||
{
|
{
|
||||||
struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context;
|
struct lego_usb_tower *dev = urb->context;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
|
|
||||||
dbg(4, "%s: enter, status %d", __FUNCTION__, status);
|
dbg(4, "%s: enter, status %d", __func__, status);
|
||||||
lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
|
lego_usb_tower_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer);
|
||||||
|
|
||||||
/* sync/async unlink faults aren't errors */
|
/* sync/async unlink faults aren't errors */
|
||||||
if (status && !(status == -ENOENT ||
|
if (status && !(status == -ENOENT ||
|
||||||
status == -ECONNRESET ||
|
status == -ECONNRESET ||
|
||||||
status == -ESHUTDOWN)) {
|
status == -ESHUTDOWN)) {
|
||||||
dbg(1, "%s - nonzero write bulk status received: %d",
|
dbg(1, "%s - nonzero write bulk status received: %d",
|
||||||
__FUNCTION__, status);
|
__func__, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->interrupt_out_busy = 0;
|
dev->interrupt_out_busy = 0;
|
||||||
wake_up_interruptible(&dev->write_wait);
|
wake_up_interruptible(&dev->write_wait);
|
||||||
|
|
||||||
lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
|
lego_usb_tower_debug_data(5, __func__, urb->actual_length, urb->transfer_buffer);
|
||||||
dbg(4, "%s: leave, status %d", __FUNCTION__, status);
|
dbg(4, "%s: leave, status %d", __func__, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -849,7 +849,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
|
|||||||
int retval = -ENOMEM;
|
int retval = -ENOMEM;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
if (udev == NULL) {
|
if (udev == NULL) {
|
||||||
info ("udev is NULL.");
|
info ("udev is NULL.");
|
||||||
@ -978,7 +978,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
|
|||||||
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
dbg(2, "%s: leave, return value 0x%.8lx (dev)", __FUNCTION__, (long) dev);
|
dbg(2, "%s: leave, return value 0x%.8lx (dev)", __func__, (long) dev);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
@ -998,7 +998,7 @@ static void tower_disconnect (struct usb_interface *interface)
|
|||||||
struct lego_usb_tower *dev;
|
struct lego_usb_tower *dev;
|
||||||
int minor;
|
int minor;
|
||||||
|
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
dev = usb_get_intfdata (interface);
|
dev = usb_get_intfdata (interface);
|
||||||
mutex_lock(&open_disc_mutex);
|
mutex_lock(&open_disc_mutex);
|
||||||
@ -1023,7 +1023,7 @@ static void tower_disconnect (struct usb_interface *interface)
|
|||||||
|
|
||||||
info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE));
|
info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE));
|
||||||
|
|
||||||
dbg(2, "%s: leave", __FUNCTION__);
|
dbg(2, "%s: leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1036,7 +1036,7 @@ static int __init lego_usb_tower_init(void)
|
|||||||
int result;
|
int result;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
/* register this driver with the USB subsystem */
|
/* register this driver with the USB subsystem */
|
||||||
result = usb_register(&tower_driver);
|
result = usb_register(&tower_driver);
|
||||||
@ -1049,7 +1049,7 @@ static int __init lego_usb_tower_init(void)
|
|||||||
info(DRIVER_DESC " " DRIVER_VERSION);
|
info(DRIVER_DESC " " DRIVER_VERSION);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
|
dbg(2, "%s: leave, return value %d", __func__, retval);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -1060,12 +1060,12 @@ static int __init lego_usb_tower_init(void)
|
|||||||
*/
|
*/
|
||||||
static void __exit lego_usb_tower_exit(void)
|
static void __exit lego_usb_tower_exit(void)
|
||||||
{
|
{
|
||||||
dbg(2, "%s: enter", __FUNCTION__);
|
dbg(2, "%s: enter", __func__);
|
||||||
|
|
||||||
/* deregister this driver with the USB subsystem */
|
/* deregister this driver with the USB subsystem */
|
||||||
usb_deregister (&tower_driver);
|
usb_deregister (&tower_driver);
|
||||||
|
|
||||||
dbg(2, "%s: leave", __FUNCTION__);
|
dbg(2, "%s: leave", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init (lego_usb_tower_init);
|
module_init (lego_usb_tower_init);
|
||||||
|
@ -113,7 +113,7 @@ static int set_outputs(struct interfacekit *kit)
|
|||||||
|
|
||||||
buffer = kzalloc(4, GFP_KERNEL);
|
buffer = kzalloc(4, GFP_KERNEL);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__);
|
dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
buffer[0] = (u8)kit->outputs;
|
buffer[0] = (u8)kit->outputs;
|
||||||
@ -146,7 +146,7 @@ static int change_string(struct interfacekit *kit, const char *display, unsigned
|
|||||||
buffer = kmalloc(8, GFP_KERNEL);
|
buffer = kmalloc(8, GFP_KERNEL);
|
||||||
form_buffer = kmalloc(30, GFP_KERNEL);
|
form_buffer = kmalloc(30, GFP_KERNEL);
|
||||||
if ((!buffer) || (!form_buffer)) {
|
if ((!buffer) || (!form_buffer)) {
|
||||||
dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__);
|
dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ static ssize_t set_backlight(struct device *dev, struct device_attribute *attr,
|
|||||||
|
|
||||||
buffer = kzalloc(8, GFP_KERNEL);
|
buffer = kzalloc(8, GFP_KERNEL);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__);
|
dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ static int set_motor(struct motorcontrol *mc, int motor)
|
|||||||
|
|
||||||
buffer = kzalloc(8, GFP_KERNEL);
|
buffer = kzalloc(8, GFP_KERNEL);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
dev_err(&mc->intf->dev, "%s - out of memory\n", __FUNCTION__);
|
dev_err(&mc->intf->dev, "%s - out of memory\n", __func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user