Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (30 commits)
  USB: Fix a bug on appledisplay.c regarding signedness
  USB: option: support hi speed for modem Haier CE100
  USB: audio gadget: free alsa devices when unloading
  USB: audio gadget: fix wTotalLength calculation
  usb: otg: isp1301_omap: fix compile error
  USB: musb: workaround Blackfin FIFO anomalies
  USB: musb: Fix array index out of bounds issue
  USB: musb: Fix null pointer dereference issue
  USB: musb: correct DMA address for tx
  USB: musb: gadget_ep0: avoid SetupEnd interrupt
  USB: musb: fix for crash in DM646x USB when (CPPI)DMA is enabled
  USB: musb: do not work if no gadget driver is loaded
  USB: musb: gadget: set otg tranceiver to idle when registering gadget
  USB: musb: Populate the VBUS GPIO with the correct GPIO number
  USB: musb: MAINTAINERS: Fix my tree's address
  USB: musb: fix compiling warning with min() macro
  USB: musb: move musb_remove to __exit
  USB: musb_gadget: fix kernel oops in txstate()
  USB: ftdi_sio: sort PID/VID entries in new ftdi_sio_ids.h header
  USB: ftdi_sio: isolate all device IDs to new ftdi_sio_ids.h header
  ...
  • Loading branch information
Linus Torvalds committed Dec 23, 2009
2 parents f793067 + 37e9066 commit 17a3be3
Show file tree
Hide file tree
Showing 28 changed files with 1,226 additions and 1,097 deletions.
18 changes: 10 additions & 8 deletions Documentation/ABI/testing/sysfs-bus-usb
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,27 @@ Contact: Alan Stern <stern@rowland.harvard.edu>
Description:
Each USB device directory will contain a file named
power/level. This file holds a power-level setting for
the device, one of "on", "auto", or "suspend".
the device, either "on" or "auto".

"on" means that the device is not allowed to autosuspend,
although normal suspends for system sleep will still
be honored. "auto" means the device will autosuspend
and autoresume in the usual manner, according to the
capabilities of its driver. "suspend" means the device
is forced into a suspended state and it will not autoresume
in response to I/O requests. However remote-wakeup requests
from the device may still be enabled (the remote-wakeup
setting is controlled separately by the power/wakeup
attribute).
capabilities of its driver.

During normal use, devices should be left in the "auto"
level. The other levels are meant for administrative uses.
level. The "on" level is meant for administrative uses.
If you want to suspend a device immediately but leave it
free to wake up in response to I/O requests, you should
write "0" to power/autosuspend.

Device not capable of proper suspend and resume should be
left in the "on" level. Although the USB spec requires
devices to support suspend/resume, many of them do not.
In fact so many don't that by default, the USB core
initializes all non-hub devices in the "on" level. Some
drivers may change this setting when they are bound.

What: /sys/bus/usb/devices/.../power/persist
Date: May 2007
KernelVersion: 2.6.23
Expand Down
41 changes: 15 additions & 26 deletions Documentation/usb/power-management.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,10 @@ being accessed through sysfs, then it definitely is idle.
Forms of dynamic PM
-------------------

Dynamic suspends can occur in two ways: manual and automatic.
"Manual" means that the user has told the kernel to suspend a device,
whereas "automatic" means that the kernel has decided all by itself to
suspend a device. Automatic suspend is called "autosuspend" for
short. In general, a device won't be autosuspended unless it has been
idle for some minimum period of time, the so-called idle-delay time.
Dynamic suspends occur when the kernel decides to suspend an idle
device. This is called "autosuspend" for short. In general, a device
won't be autosuspended unless it has been idle for some minimum period
of time, the so-called idle-delay time.

Of course, nothing the kernel does on its own initiative should
prevent the computer or its devices from working properly. If a
Expand All @@ -96,10 +94,11 @@ idle.
We can categorize power management events in two broad classes:
external and internal. External events are those triggered by some
agent outside the USB stack: system suspend/resume (triggered by
userspace), manual dynamic suspend/resume (also triggered by
userspace), and remote wakeup (triggered by the device). Internal
events are those triggered within the USB stack: autosuspend and
autoresume.
userspace), manual dynamic resume (also triggered by userspace), and
remote wakeup (triggered by the device). Internal events are those
triggered within the USB stack: autosuspend and autoresume. Note that
all dynamic suspend events are internal; external agents are not
allowed to issue dynamic suspends.


The user interface for dynamic PM
Expand Down Expand Up @@ -145,9 +144,9 @@ relevant attribute files are: wakeup, level, and autosuspend.
number of seconds the device should remain idle before
the kernel will autosuspend it (the idle-delay time).
The default is 2. 0 means to autosuspend as soon as
the device becomes idle, and -1 means never to
autosuspend. You can write a number to the file to
change the autosuspend idle-delay time.
the device becomes idle, and negative values mean
never to autosuspend. You can write a number to the
file to change the autosuspend idle-delay time.

Writing "-1" to power/autosuspend and writing "on" to power/level do
essentially the same thing -- they both prevent the device from being
Expand Down Expand Up @@ -377,9 +376,9 @@ the device hasn't been idle for long enough, a delayed workqueue
routine is automatically set up to carry out the operation when the
autosuspend idle-delay has expired.

Autoresume attempts also can fail. This will happen if power/level is
set to "suspend" or if the device doesn't manage to resume properly.
Unlike autosuspend, there's no delay for an autoresume.
Autoresume attempts also can fail, although failure would mean that
the device is no longer present or operating properly. Unlike
autosuspend, there's no delay for an autoresume.


Other parts of the driver interface
Expand Down Expand Up @@ -527,13 +526,3 @@ succeed, it may still remain active and thus cause the system to
resume as soon as the system suspend is complete. Or the remote
wakeup may fail and get lost. Which outcome occurs depends on timing
and on the hardware and firmware design.

More interestingly, a device might undergo a manual resume or
autoresume during system suspend. With current kernels this shouldn't
happen, because manual resumes must be initiated by userspace and
autoresumes happen in response to I/O requests, but all user processes
and I/O should be quiescent during a system suspend -- thanks to the
freezer. However there are plans to do away with the freezer, which
would mean these things would become possible. If and when this comes
about, the USB core will carefully arrange matters so that either type
of resume will block until the entire system has resumed.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -3679,7 +3679,7 @@ F: include/linux/isicom.h
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
M: Felipe Balbi <felipe.balbi@nokia.com>
L: linux-usb@vger.kernel.org
T: git git://gitorious.org/musb/mainline.git
T: git git://gitorious.org/usb/usb.git
S: Maintained
F: drivers/usb/musb/

Expand Down
2 changes: 0 additions & 2 deletions drivers/usb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,3 @@ obj-y += early/

obj-$(CONFIG_USB_ATM) += atm/
obj-$(CONFIG_USB_SPEEDTOUCH) += atm/

obj-$(CONFIG_USB_ULPI) += otg/
4 changes: 3 additions & 1 deletion drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1597,7 +1597,9 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
}

/**
* Check whether a new bandwidth setting exceeds the bus bandwidth.
* usb_hcd_alloc_bandwidth - check whether a new bandwidth setting exceeds
* the bus bandwidth
* @udev: target &usb_device
* @new_config: new configuration to install
* @cur_alt: the current alternate interface setting
* @new_alt: alternate interface setting that is being installed
Expand Down
58 changes: 33 additions & 25 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1658,12 +1658,12 @@ static inline void announce_device(struct usb_device *udev) { }
#endif

/**
* usb_configure_device_otg - FIXME (usbcore-internal)
* usb_enumerate_device_otg - FIXME (usbcore-internal)
* @udev: newly addressed device (in ADDRESS state)
*
* Do configuration for On-The-Go devices
* Finish enumeration for On-The-Go devices
*/
static int usb_configure_device_otg(struct usb_device *udev)
static int usb_enumerate_device_otg(struct usb_device *udev)
{
int err = 0;

Expand Down Expand Up @@ -1734,7 +1734,7 @@ static int usb_configure_device_otg(struct usb_device *udev)


/**
* usb_configure_device - Detect and probe device intfs/otg (usbcore-internal)
* usb_enumerate_device - Read device configs/intfs/otg (usbcore-internal)
* @udev: newly addressed device (in ADDRESS state)
*
* This is only called by usb_new_device() and usb_authorize_device()
Expand All @@ -1745,7 +1745,7 @@ static int usb_configure_device_otg(struct usb_device *udev)
* the string descriptors, as they will be errored out by the device
* until it has been authorized.
*/
static int usb_configure_device(struct usb_device *udev)
static int usb_enumerate_device(struct usb_device *udev)
{
int err;

Expand All @@ -1769,7 +1769,7 @@ static int usb_configure_device(struct usb_device *udev)
udev->descriptor.iManufacturer);
udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
}
err = usb_configure_device_otg(udev);
err = usb_enumerate_device_otg(udev);
fail:
return err;
}
Expand All @@ -1779,8 +1779,8 @@ static int usb_configure_device(struct usb_device *udev)
* usb_new_device - perform initial device setup (usbcore-internal)
* @udev: newly addressed device (in ADDRESS state)
*
* This is called with devices which have been enumerated, but not yet
* configured. The device descriptor is available, but not descriptors
* This is called with devices which have been detected but not fully
* enumerated. The device descriptor is available, but not descriptors
* for any device configuration. The caller must have locked either
* the parent hub (if udev is a normal device) or else the
* usb_bus_list_lock (if udev is a root hub). The parent's pointer to
Expand All @@ -1803,8 +1803,8 @@ int usb_new_device(struct usb_device *udev)
if (udev->parent)
usb_autoresume_device(udev->parent);

usb_detect_quirks(udev); /* Determine quirks */
err = usb_configure_device(udev); /* detect & probe dev/intfs */
usb_detect_quirks(udev);
err = usb_enumerate_device(udev); /* Read descriptors */
if (err < 0)
goto fail;
dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",
Expand Down Expand Up @@ -1849,21 +1849,23 @@ int usb_new_device(struct usb_device *udev)
*/
int usb_deauthorize_device(struct usb_device *usb_dev)
{
unsigned cnt;
usb_lock_device(usb_dev);
if (usb_dev->authorized == 0)
goto out_unauthorized;

usb_dev->authorized = 0;
usb_set_configuration(usb_dev, -1);

kfree(usb_dev->product);
usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
kfree(usb_dev->manufacturer);
usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
kfree(usb_dev->serial);
usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
kfree(usb_dev->config);
usb_dev->config = NULL;
for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++)
kfree(usb_dev->rawdescriptors[cnt]);

usb_destroy_configuration(usb_dev);
usb_dev->descriptor.bNumConfigurations = 0;
kfree(usb_dev->rawdescriptors);

out_unauthorized:
usb_unlock_device(usb_dev);
return 0;
Expand All @@ -1873,15 +1875,11 @@ int usb_deauthorize_device(struct usb_device *usb_dev)
int usb_authorize_device(struct usb_device *usb_dev)
{
int result = 0, c;

usb_lock_device(usb_dev);
if (usb_dev->authorized == 1)
goto out_authorized;
kfree(usb_dev->product);
usb_dev->product = NULL;
kfree(usb_dev->manufacturer);
usb_dev->manufacturer = NULL;
kfree(usb_dev->serial);
usb_dev->serial = NULL;

result = usb_autoresume_device(usb_dev);
if (result < 0) {
dev_err(&usb_dev->dev,
Expand All @@ -1894,10 +1892,18 @@ int usb_authorize_device(struct usb_device *usb_dev)
"authorization: %d\n", result);
goto error_device_descriptor;
}

kfree(usb_dev->product);
usb_dev->product = NULL;
kfree(usb_dev->manufacturer);
usb_dev->manufacturer = NULL;
kfree(usb_dev->serial);
usb_dev->serial = NULL;

usb_dev->authorized = 1;
result = usb_configure_device(usb_dev);
result = usb_enumerate_device(usb_dev);
if (result < 0)
goto error_configure;
goto error_enumerate;
/* Choose and set the configuration. This registers the interfaces
* with the driver core and lets interface drivers bind to them.
*/
Expand All @@ -1912,8 +1918,10 @@ int usb_authorize_device(struct usb_device *usb_dev)
}
}
dev_info(&usb_dev->dev, "authorized to connect\n");
error_configure:

error_enumerate:
error_device_descriptor:
usb_autosuspend_device(usb_dev);
error_autoresume:
out_authorized:
usb_unlock_device(usb_dev); // complements locktree
Expand Down
6 changes: 5 additions & 1 deletion drivers/usb/core/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,13 @@ static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
int retval; \
\
udev = to_usb_device(dev); \
return sprintf(buf, "%s\n", udev->name); \
usb_lock_device(udev); \
retval = sprintf(buf, "%s\n", udev->name); \
usb_unlock_device(udev); \
return retval; \
} \
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);

Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/core/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ MODULE_PARM_DESC(autosuspend, "default autosuspend delay");
/**
* usb_find_alt_setting() - Given a configuration, find the alternate setting
* for the given interface.
* @config - the configuration to search (not necessarily the current config).
* @iface_num - interface number to search in
* @alt_num - alternate interface setting number to search for.
* @config: the configuration to search (not necessarily the current config).
* @iface_num: interface number to search in
* @alt_num: alternate interface setting number to search for.
*
* Search the configuration's interface cache for the given alt setting.
*/
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/early/ehci-dbgp.c
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ int dbgp_external_startup(void)
}
EXPORT_SYMBOL_GPL(dbgp_external_startup);

static int __init ehci_reset_port(int port)
static int ehci_reset_port(int port)
{
u32 portsc;
u32 delay_time, delay;
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ static int __init audio_bind(struct usb_composite_dev *cdev)

static int __exit audio_unbind(struct usb_composite_dev *cdev)
{
gaudio_cleanup();
return 0;
}

Expand Down
15 changes: 10 additions & 5 deletions drivers/usb/gadget/f_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,16 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = {
DECLARE_UAC_AC_HEADER_DESCRIPTOR(2);

#define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES)
/* 1 input terminal, 1 output terminal and 1 feature unit */
#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \
+ UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0))
/* B.3.2 Class-Specific AC Interface Descriptor */
static struct uac_ac_header_descriptor_2 ac_header_desc = {
.bLength = UAC_DT_AC_HEADER_LENGTH,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_HEADER,
.bcdADC = __constant_cpu_to_le16(0x0100),
.wTotalLength = __constant_cpu_to_le16(UAC_DT_AC_HEADER_LENGTH),
.wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH),
.bInCollection = F_AUDIO_NUM_INTERFACES,
.baInterfaceNr = {
[0] = F_AUDIO_AC_INTERFACE,
Expand Down Expand Up @@ -252,12 +255,12 @@ static struct f_audio_buf *f_audio_buffer_alloc(int buf_size)

copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC);
if (!copy_buf)
return (struct f_audio_buf *)-ENOMEM;
return ERR_PTR(-ENOMEM);

copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC);
if (!copy_buf->buf) {
kfree(copy_buf);
return (struct f_audio_buf *)-ENOMEM;
return ERR_PTR(-ENOMEM);
}

return copy_buf;
Expand Down Expand Up @@ -332,7 +335,7 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req)
list_add_tail(&copy_buf->list, &audio->play_queue);
schedule_work(&audio->playback_work);
copy_buf = f_audio_buffer_alloc(audio_buf_size);
if (copy_buf < 0)
if (IS_ERR(copy_buf))
return -ENOMEM;
}

Expand Down Expand Up @@ -576,6 +579,8 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
usb_ep_enable(out_ep, audio->out_desc);
out_ep->driver_data = audio;
audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
if (IS_ERR(audio->copy_buf))
return -ENOMEM;

/*
* allocate a bunch of read buffers
Expand Down Expand Up @@ -787,7 +792,7 @@ int __init audio_bind_config(struct usb_configuration *c)
return status;

add_fail:
gaudio_cleanup(&audio->card);
gaudio_cleanup();
setup_fail:
kfree(audio);
return status;
Expand Down
Loading

0 comments on commit 17a3be3

Please sign in to comment.