aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/Kconfig15
-rw-r--r--drivers/usb/core/buffer.c21
-rw-r--r--drivers/usb/core/config.c14
-rw-r--r--drivers/usb/core/devices.c154
-rw-r--r--drivers/usb/core/devio.c359
-rw-r--r--drivers/usb/core/driver.c63
-rw-r--r--drivers/usb/core/file.c4
-rw-r--r--drivers/usb/core/hcd-pci.c147
-rw-r--r--drivers/usb/core/hcd.c220
-rw-r--r--drivers/usb/core/hcd.h92
-rw-r--r--drivers/usb/core/hub.c96
-rw-r--r--drivers/usb/core/hub.h18
-rw-r--r--drivers/usb/core/inode.c42
-rw-r--r--drivers/usb/core/message.c468
-rw-r--r--drivers/usb/core/notify.c2
-rw-r--r--drivers/usb/core/otg_whitelist.h6
-rw-r--r--drivers/usb/core/sysfs.c75
-rw-r--r--drivers/usb/core/urb.c37
-rw-r--r--drivers/usb/core/usb.c144
-rw-r--r--drivers/usb/core/usb.h21
20 files changed, 1145 insertions, 853 deletions
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 97b09f28270..5c33cdb9cac 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -9,6 +9,21 @@ config USB_DEBUG
of debug messages to the system log. Select this if you are having a
problem with USB support and want to see more of what is going on.
+config USB_ANNOUNCE_NEW_DEVICES
+ bool "USB announce new devices"
+ depends on USB
+ default N
+ help
+ Say Y here if you want the USB core to always announce the
+ idVendor, idProduct, Manufacturer, Product, and SerialNumber
+ strings for every new USB device to the syslog. This option is
+ usually used by distro vendors to help with debugging and to
+ let users know what specific device was added to the machine
+ in what location.
+
+ If you do not want this kind of information sent to the system
+ log, or have any doubts about this, say N here.
+
comment "Miscellaneous USB options"
depends on USB
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index ead2475406b..cadb2dc1d28 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -11,7 +11,6 @@
#include <linux/device.h>
#include <linux/mm.h>
#include <asm/io.h>
-#include <asm/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/usb.h>
@@ -54,11 +53,13 @@ int hcd_buffer_create(struct usb_hcd *hcd)
char name[16];
int i, size;
- if (!hcd->self.controller->dma_mask)
+ if (!hcd->self.controller->dma_mask &&
+ !(hcd->driver->flags & HCD_LOCAL_MEM))
return 0;
- for (i = 0; i < HCD_BUFFER_POOLS; i++) {
- if (!(size = pool_max [i]))
+ for (i = 0; i < HCD_BUFFER_POOLS; i++) {
+ size = pool_max[i];
+ if (!size)
continue;
snprintf(name, sizeof name, "buffer-%d", size);
hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
@@ -81,10 +82,10 @@ int hcd_buffer_create(struct usb_hcd *hcd)
*/
void hcd_buffer_destroy(struct usb_hcd *hcd)
{
- int i;
+ int i;
- for (i = 0; i < HCD_BUFFER_POOLS; i++) {
- struct dma_pool *pool = hcd->pool[i];
+ for (i = 0; i < HCD_BUFFER_POOLS; i++) {
+ struct dma_pool *pool = hcd->pool[i];
if (pool) {
dma_pool_destroy(pool);
hcd->pool[i] = NULL;
@@ -108,7 +109,8 @@ void *hcd_buffer_alloc(
int i;
/* some USB hosts just use PIO */
- if (!bus->controller->dma_mask) {
+ if (!bus->controller->dma_mask &&
+ !(hcd->driver->flags & HCD_LOCAL_MEM)) {
*dma = ~(dma_addr_t) 0;
return kmalloc(size, mem_flags);
}
@@ -133,7 +135,8 @@ void hcd_buffer_free(
if (!addr)
return;
- if (!bus->controller->dma_mask) {
+ if (!bus->controller->dma_mask &&
+ !(hcd->driver->flags & HCD_LOCAL_MEM)) {
kfree(addr);
return;
}
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 1a8edcee7f3..a92122a216b 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -238,7 +238,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
/* Allocate space for the right(?) number of endpoints */
num_ep = num_ep_orig = alt->desc.bNumEndpoints;
- alt->desc.bNumEndpoints = 0; // Use as a counter
+ alt->desc.bNumEndpoints = 0; /* Use as a counter */
if (num_ep > USB_MAXENDPOINTS) {
dev_warn(ddev, "too many endpoints for config %d interface %d "
"altsetting %d: %d, using maximum allowed: %d\n",
@@ -246,7 +246,8 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
num_ep = USB_MAXENDPOINTS;
}
- if (num_ep > 0) { /* Can't allocate 0 bytes */
+ if (num_ep > 0) {
+ /* Can't allocate 0 bytes */
len = sizeof(struct usb_host_endpoint) * num_ep;
alt->endpoint = kzalloc(len, GFP_KERNEL);
if (!alt->endpoint)
@@ -475,8 +476,9 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx,
return 0;
}
-// hub-only!! ... and only exported for reset/reinit path.
-// otherwise used internally on disconnect/destroy path
+/* hub-only!! ... and only exported for reset/reinit path.
+ * otherwise used internally on disconnect/destroy path
+ */
void usb_destroy_configuration(struct usb_device *dev)
{
int c, i;
@@ -498,7 +500,7 @@ void usb_destroy_configuration(struct usb_device *dev)
kfree(cf->string);
for (i = 0; i < cf->desc.bNumInterfaces; i++) {
if (cf->intf_cache[i])
- kref_put(&cf->intf_cache[i]->ref,
+ kref_put(&cf->intf_cache[i]->ref,
usb_release_interface_cache);
}
}
@@ -525,7 +527,7 @@ int usb_get_configuration(struct usb_device *dev)
unsigned int cfgno, length;
unsigned char *buffer;
unsigned char *bigbuffer;
- struct usb_config_descriptor *desc;
+ struct usb_config_descriptor *desc;
cfgno = 0;
if (dev->authorized == 0) /* Not really an error */
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 87c794d60aa..83d9dc379d9 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -89,7 +89,7 @@ static const char *format_string_serialnumber =
static const char *format_bandwidth =
/* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */
"B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n";
-
+
static const char *format_device1 =
/* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */
"D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n";
@@ -101,7 +101,7 @@ static const char *format_device2 =
static const char *format_config =
/* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
"C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
-
+
static const char *format_iad =
/* A: FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */
"A: FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n";
@@ -122,7 +122,7 @@ static const char *format_endpt =
*/
static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq);
-static unsigned int conndiscevcnt = 0;
+static unsigned int conndiscevcnt;
/* this struct stores the poll state for <mountpoint>/devices pollers */
struct usb_device_status {
@@ -172,12 +172,8 @@ static const char *class_decode(const int class)
return clas_info[ix].class_name;
}
-static char *usb_dump_endpoint_descriptor(
- int speed,
- char *start,
- char *end,
- const struct usb_endpoint_descriptor *desc
-)
+static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,
+ const struct usb_endpoint_descriptor *desc)
{
char dir, unit, *type;
unsigned interval, bandwidth = 1;
@@ -235,22 +231,24 @@ static char *usb_dump_endpoint_descriptor(
start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
desc->bmAttributes, type,
- (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) * bandwidth,
+ (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) *
+ bandwidth,
interval, unit);
return start;
}
static char *usb_dump_interface_descriptor(char *start, char *end,
- const struct usb_interface_cache *intfc,
- const struct usb_interface *iface,
- int setno)
+ const struct usb_interface_cache *intfc,
+ const struct usb_interface *iface,
+ int setno)
{
- const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc;
+ const struct usb_interface_descriptor *desc;
const char *driver_name = "";
int active = 0;
if (start > end)
return start;
+ desc = &intfc->altsetting[setno].desc;
if (iface) {
driver_name = (iface->dev.driver
? iface->dev.driver->name
@@ -270,14 +268,10 @@ static char *usb_dump_interface_descriptor(char *start, char *end,
return start;
}
-static char *usb_dump_interface(
- int speed,
- char *start,
- char *end,
- const struct usb_interface_cache *intfc,
- const struct usb_interface *iface,
- int setno
-) {
+static char *usb_dump_interface(int speed, char *start, char *end,
+ const struct usb_interface_cache *intfc,
+ const struct usb_interface *iface, int setno)
+{
const struct usb_host_interface *desc = &intfc->altsetting[setno];
int i;
@@ -292,7 +286,7 @@ static char *usb_dump_interface(
}
static char *usb_dump_iad_descriptor(char *start, char *end,
- const struct usb_interface_assoc_descriptor *iad)
+ const struct usb_interface_assoc_descriptor *iad)
{
if (start > end)
return start;
@@ -311,13 +305,15 @@ static char *usb_dump_iad_descriptor(char *start, char *end,
* 1. marking active interface altsettings (code lists all, but should mark
* which ones are active, if any)
*/
-
-static char *usb_dump_config_descriptor(char *start, char *end, const struct usb_config_descriptor *desc, int active)
+static char *usb_dump_config_descriptor(char *start, char *end,
+ const struct usb_config_descriptor *desc,
+ int active)
{
if (start > end)
return start;
start += sprintf(start, format_config,
- active ? '*' : ' ', /* mark active/actual/current cfg. */
+ /* mark active/actual/current cfg. */
+ active ? '*' : ' ',
desc->bNumInterfaces,
desc->bConfigurationValue,
desc->bmAttributes,
@@ -325,13 +321,8 @@ static char *usb_dump_config_descriptor(char *start, char *end, const struct usb
return start;
}
-static char *usb_dump_config (
- int speed,
- char *start,
- char *end,
- const struct usb_host_config *config,
- int active
-)
+static char *usb_dump_config(int speed, char *start, char *end,
+ const struct usb_host_config *config, int active)
{
int i, j;
struct usb_interface_cache *intfc;
@@ -339,7 +330,8 @@ static char *usb_dump_config (
if (start > end)
return start;
- if (!config) /* getting these some in 2.3.7; none in 2.3.6 */
+ if (!config)
+ /* getting these some in 2.3.7; none in 2.3.6 */
return start + sprintf(start, "(null Cfg. desc.)\n");
start = usb_dump_config_descriptor(start, end, &config->desc, active);
for (i = 0; i < USB_MAXIADS; i++) {
@@ -364,7 +356,8 @@ static char *usb_dump_config (
/*
* Dump the different USB descriptors.
*/
-static char *usb_dump_device_descriptor(char *start, char *end, const struct usb_device_descriptor *desc)
+static char *usb_dump_device_descriptor(char *start, char *end,
+ const struct usb_device_descriptor *desc)
{
u16 bcdUSB = le16_to_cpu(desc->bcdUSB);
u16 bcdDevice = le16_to_cpu(desc->bcdDevice);
@@ -374,7 +367,7 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb
start += sprintf(start, format_device1,
bcdUSB >> 8, bcdUSB & 0xff,
desc->bDeviceClass,
- class_decode (desc->bDeviceClass),
+ class_decode(desc->bDeviceClass),
desc->bDeviceSubClass,
desc->bDeviceProtocol,
desc->bMaxPacketSize0,
@@ -391,12 +384,14 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb
/*
* Dump the different strings that this device holds.
*/
-static char *usb_dump_device_strings(char *start, char *end, struct usb_device *dev)
+static char *usb_dump_device_strings(char *start, char *end,
+ struct usb_device *dev)
{
if (start > end)
return start;
if (dev->manufacturer)
- start += sprintf(start, format_string_manufacturer, dev->manufacturer);
+ start += sprintf(start, format_string_manufacturer,
+ dev->manufacturer);
if (start > end)
goto out;
if (dev->product)
@@ -405,7 +400,8 @@ static char *usb_dump_device_strings(char *start, char *end, struct usb_device *
goto out;
#ifdef ALLOW_SERIAL_NUMBER
if (dev->serial)
- start += sprintf(start, format_string_serialnumber, dev->serial);
+ start += sprintf(start, format_string_serialnumber,
+ dev->serial);
#endif
out:
return start;
@@ -417,12 +413,12 @@ static char *usb_dump_desc(char *start, char *end, struct usb_device *dev)
if (start > end)
return start;
-
+
start = usb_dump_device_descriptor(start, end, &dev->descriptor);
if (start > end)
return start;
-
+
start = usb_dump_device_strings(start, end, dev);
for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
@@ -439,7 +435,8 @@ static char *usb_dump_desc(char *start, char *end, struct usb_device *dev)
#ifdef PROC_EXTRA /* TBD: may want to add this code later */
-static char *usb_dump_hub_descriptor(char *start, char *end, const struct usb_hub_descriptor * desc)
+static char *usb_dump_hub_descriptor(char *start, char *end,
+ const struct usb_hub_descriptor *desc)
{
int leng = USB_DT_HUB_NONVAR_SIZE;
unsigned char *ptr = (unsigned char *)desc;
@@ -455,13 +452,16 @@ static char *usb_dump_hub_descriptor(char *start, char *end, const struct usb_hu
return start;
}
-static char *usb_dump_string(char *start, char *end, const struct usb_device *dev, char *id, int index)
+static char *usb_dump_string(char *start, char *end,
+ const struct usb_device *dev, char *id, int index)
{
if (start > end)
return start;
start += sprintf(start, "Interface:");
- if (index <= dev->maxstring && dev->stringindex && dev->stringindex[index])
- start += sprintf(start, "%s: %.100s ", id, dev->stringindex[index]);
+ if (index <= dev->maxstring && dev->stringindex &&
+ dev->stringindex[index])
+ start += sprintf(start, "%s: %.100s ", id,
+ dev->stringindex[index]);
return start;
}
@@ -476,8 +476,10 @@ static char *usb_dump_string(char *start, char *end, const struct usb_device *de
* file_offset - the offset into the devices file on completion
* The caller must own the device lock.
*/
-static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
- struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count)
+static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
+ loff_t *skip_bytes, loff_t *file_offset,
+ struct usb_device *usbdev, struct usb_bus *bus,
+ int level, int index, int count)
{
int chix;
int ret, cnt = 0;
@@ -485,17 +487,19 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
char *pages_start, *data_end, *speed;
unsigned int length;
ssize_t total_written = 0;
-
+
/* don't bother with anything else if we're not writing any data */
if (*nbytes <= 0)
return 0;
-
+
if (level > MAX_TOPO_LEVEL)
return 0;
- /* allocate 2^1 pages = 8K (on i386); should be more than enough for one device */
- if (!(pages_start = (char*) __get_free_pages(GFP_KERNEL,1)))
- return -ENOMEM;
-
+ /* allocate 2^1 pages = 8K (on i386);
+ * should be more than enough for one device */
+ pages_start = (char *)__get_free_pages(GFP_KERNEL, 1);
+ if (!pages_start)
+ return -ENOMEM;
+
if (usbdev->parent && usbdev->parent->devnum != -1)
parent_devnum = usbdev->parent->devnum;
/*
@@ -541,15 +545,16 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
bus->bandwidth_allocated, max,
(100 * bus->bandwidth_allocated + max / 2)
/ max,
- bus->bandwidth_int_reqs,
- bus->bandwidth_isoc_reqs);
-
+ bus->bandwidth_int_reqs,
+ bus->bandwidth_isoc_reqs);
+
}
- data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, usbdev);
-
+ data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256,
+ usbdev);
+
if (data_end > (pages_start + (2 * PAGE_SIZE) - 256))
data_end += sprintf(data_end, "(truncated)\n");
-
+
length = data_end - pages_start;
/* if we can start copying some data to the user */
if (length > *skip_bytes) {
@@ -567,17 +572,18 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
*skip_bytes = 0;
} else
*skip_bytes -= length;
-
+
free_pages((unsigned long)pages_start, 1);
-
+
/* Now look at all of this device's children. */
for (chix = 0; chix < usbdev->maxchild; chix++) {
struct usb_device *childdev = usbdev->children[chix];
if (childdev) {
usb_lock_device(childdev);
- ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev,
- bus, level + 1, chix, ++cnt);
+ ret = usb_device_dump(buffer, nbytes, skip_bytes,
+ file_offset, childdev, bus,
+ level + 1, chix, ++cnt);
usb_unlock_device(childdev);
if (ret == -EFAULT)
return total_written;
@@ -587,7 +593,8 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
return total_written;
}
-static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+static ssize_t usb_device_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos)
{
struct usb_bus *bus;
ssize_t ret, total_written = 0;
@@ -607,7 +614,8 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte
if (!bus->root_hub)
continue;
usb_lock_device(bus->root_hub);
- ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
+ ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos,
+ bus->root_hub, bus, 0, 0, 0);
usb_unlock_device(bus->root_hub);
if (ret < 0) {
mutex_unlock(&usb_bus_list_lock);
@@ -620,7 +628,8 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte
}
/* Kernel lock for "lastev" protection */
-static unsigned int usb_device_poll(struct file *file, struct poll_table_struct *wait)
+static unsigned int usb_device_poll(struct file *file,
+ struct poll_table_struct *wait)
{
struct usb_device_status *st = file->private_data;
unsigned int mask = 0;
@@ -629,7 +638,8 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
if (!st) {
st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
- /* we may have dropped BKL - need to check for having lost the race */
+ /* we may have dropped BKL -
+ * need to check for having lost the race */
if (file->private_data) {
kfree(st);
st = file->private_data;
@@ -652,7 +662,7 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
}
lost_race:
if (file->f_mode & FMODE_READ)
- poll_wait(file, &deviceconndiscwq, wait);
+ poll_wait(file, &deviceconndiscwq, wait);
if (st->lastev != conndiscevcnt)
mask |= POLLIN;
st->lastev = conndiscevcnt;
@@ -662,18 +672,18 @@ lost_race:
static int usb_device_open(struct inode *inode, struct file *file)
{
- file->private_data = NULL;
- return 0;
+ file->private_data = NULL;
+ return 0;
}
static int usb_device_release(struct inode *inode, struct file *file)
{
kfree(file->private_data);
file->private_data = NULL;
- return 0;
+ return 0;
}
-static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig)
+static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig)
{
loff_t ret;
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 1f4f6d02fe2..ae94176c64e 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -75,14 +75,14 @@ struct async {
u32 secid;
};
-static int usbfs_snoop = 0;
-module_param (usbfs_snoop, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic");
+static int usbfs_snoop;
+module_param(usbfs_snoop, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic");
#define snoop(dev, format, arg...) \
do { \
if (usbfs_snoop) \
- dev_info( dev , format , ## arg); \
+ dev_info(dev , format , ## arg); \
} while (0)
#define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0)
@@ -90,7 +90,7 @@ MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic");
#define MAX_USBFS_BUFFER_SIZE 16384
-static inline int connected (struct dev_state *ps)
+static inline int connected(struct dev_state *ps)
{
return (!list_empty(&ps->list) &&
ps->dev->state != USB_STATE_NOTATTACHED);
@@ -120,7 +120,8 @@ static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)
return ret;
}
-static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes,
+ loff_t *ppos)
{
struct dev_state *ps = file->private_data;
struct usb_device *dev = ps->dev;
@@ -140,7 +141,8 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l
}
if (pos < sizeof(struct usb_device_descriptor)) {
- struct usb_device_descriptor temp_desc ; /* 18 bytes - fits on the stack */
+ /* 18 bytes - fits on the stack */
+ struct usb_device_descriptor temp_desc;
memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor));
le16_to_cpus(&temp_desc.bcdUSB);
@@ -210,17 +212,17 @@ err:
static struct async *alloc_async(unsigned int numisoframes)
{
- unsigned int assize = sizeof(struct async) + numisoframes * sizeof(struct usb_iso_packet_descriptor);
- struct async *as = kzalloc(assize, GFP_KERNEL);
+ struct async *as;
- if (!as)
- return NULL;
+ as = kzalloc(sizeof(struct async), GFP_KERNEL);
+ if (!as)
+ return NULL;
as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL);
if (!as->urb) {
kfree(as);
return NULL;
}
- return as;
+ return as;
}
static void free_async(struct async *as)
@@ -234,52 +236,54 @@ static void free_async(struct async *as)
static inline void async_newpending(struct async *as)
{
- struct dev_state *ps = as->ps;
- unsigned long flags;
-
- spin_lock_irqsave(&ps->lock, flags);
- list_add_tail(&as->asynclist, &ps->async_pending);
- spin_unlock_irqrestore(&ps->lock, flags);
+ struct dev_state *ps = as->ps;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ps->lock, flags);
+ list_add_tail(&as->asynclist, &ps->async_pending);
+ spin_unlock_irqrestore(&ps->lock, flags);
}
static inline void async_removepending(struct async *as)
{
- struct dev_state *ps = as->ps;
- unsigned long flags;
-
- spin_lock_irqsave(&ps->lock, flags);
- list_del_init(&as->asynclist);
- spin_unlock_irqrestore(&ps->lock, flags);
+ struct dev_state *ps = as->ps;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ps->lock, flags);
+ list_del_init(&as->asynclist);
+ spin_unlock_irqrestore(&ps->lock, flags);
}
static inline struct async *async_getcompleted(struct dev_state *ps)
{
- unsigned long flags;
- struct async *as = NULL;
-
- spin_lock_irqsave(&ps->lock, flags);
- if (!list_empty(&ps->async_completed)) {
- as = list_entry(ps->async_completed.next, struct async, asynclist);
- list_del_init(&as->asynclist);
- }
- spin_unlock_irqrestore(&ps->lock, flags);
- return as;
+ unsigned long flags;
+ struct async *as = NULL;
+
+ spin_lock_irqsave(&ps->lock, flags);
+ if (!list_empty(&ps->async_completed)) {
+ as = list_entry(ps->async_completed.next, struct async,
+ asynclist);
+ list_del_init(&as->asynclist);
+ }
+ spin_unlock_irqrestore(&ps->lock, flags);
+ return as;
}
-static inline struct async *async_getpending(struct dev_state *ps, void __user *userurb)
+static inline struct async *async_getpending(struct dev_state *ps,
+ void __user *userurb)
{
- unsigned long flags;
- struct async *as;
+ unsigned long flags;
+ struct async *as;
- spin_lock_irqsave(&ps->lock, flags);
+ spin_lock_irqsave(&ps->lock, flags);
list_for_each_entry(as, &ps->async_pending, asynclist)
if (as->userurb == userurb) {
list_del_init(&as->asynclist);
spin_unlock_irqrestore(&ps->lock, flags);
return as;
}
- spin_unlock_irqrestore(&ps->lock, flags);
- return NULL;
+ spin_unlock_irqrestore(&ps->lock, flags);
+ return NULL;
}
static void snoop_urb(struct urb *urb, void __user *userurb)
@@ -298,19 +302,19 @@ static void snoop_urb(struct urb *urb, void __user *userurb)
dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length);
dev_info(&urb->dev->dev, "data: ");
for (j = 0; j < urb->transfer_buffer_length; ++j)
- printk ("%02x ", data[j]);
+ printk("%02x ", data[j]);
printk("\n");
}
static void async_completed(struct urb *urb)
{
- struct async *as = urb->context;
- struct dev_state *ps = as->ps;
+ struct async *as = urb->context;
+ struct dev_state *ps = as->ps;
struct siginfo sinfo;
- spin_lock(&ps->lock);
- list_move_tail(&as->asynclist, &ps->async_completed);
- spin_unlock(&ps->lock);
+ spin_lock(&ps->lock);
+ list_move_tail(&as->asynclist, &ps->async_completed);
+ spin_unlock(&ps->lock);
as->status = urb->status;
if (as->signr) {
sinfo.si_signo = as->signr;
@@ -325,7 +329,7 @@ static void async_completed(struct urb *urb)
wake_up(&ps->wait);
}
-static void destroy_async (struct dev_state *ps, struct list_head *list)
+static void destroy_async(struct dev_state *ps, struct list_head *list)
{
struct async *as;
unsigned long flags;
@@ -348,7 +352,8 @@ static void destroy_async (struct dev_state *ps, struct list_head *list)
}
}
-static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum)
+static void destroy_async_on_interface(struct dev_state *ps,
+ unsigned int ifnum)
{
struct list_head *p, *q, hitlist;
unsigned long flags;
@@ -364,7 +369,7 @@ static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum
static inline void destroy_all_async(struct dev_state *ps)
{
- destroy_async(ps, &ps->async_pending);
+ destroy_async(ps, &ps->async_pending);
}
/*
@@ -373,15 +378,15 @@ static inline void destroy_all_async(struct dev_state *ps)
* they're also undone when devices disconnect.
*/
-static int driver_probe (struct usb_interface *intf,
- const struct usb_device_id *id)
+static int driver_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
return -ENODEV;
}
static void driver_disconnect(struct usb_interface *intf)
{
- struct dev_state *ps = usb_get_intfdata (intf);
+ struct dev_state *ps = usb_get_intfdata(intf);
unsigned int ifnum = intf->altsetting->desc.bInterfaceNumber;
if (!ps)
@@ -396,16 +401,31 @@ static void driver_disconnect(struct usb_interface *intf)
else
warn("interface number %u out of range", ifnum);
- usb_set_intfdata (intf, NULL);
+ usb_set_intfdata(intf, NULL);
/* force async requests to complete */
destroy_async_on_interface(ps, ifnum);
}
+/* The following routines are merely placeholders. There is no way
+ * to inform a user task about suspend or resumes.
+ */
+static int driver_suspend(struct usb_interface *intf, pm_message_t msg)
+{
+ return 0;
+}
+
+static int driver_resume(struct usb_interface *intf)
+{
+ return 0;
+}
+
struct usb_driver usbfs_driver = {
.name = "usbfs",
.probe = driver_probe,
.disconnect = driver_disconnect,
+ .suspend = driver_suspend,
+ .resume = driver_resume,
};
static int claimintf(struct dev_state *ps, unsigned int ifnum)
@@ -459,15 +479,16 @@ static int checkintf(struct dev_state *ps, unsigned int ifnum)
if (test_bit(ifnum, &ps->ifclaimed))
return 0;
/* if not yet claimed, claim it for the driver */
- dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim interface %u before use\n",
- task_pid_nr(current), current->comm, ifnum);
+ dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim "
+ "interface %u before use\n", task_pid_nr(current),
+ current->comm, ifnum);
return claimintf(ps, ifnum);
}
static int findintfep(struct usb_device *dev, unsigned int ep)
{
unsigned int i, j, e;
- struct usb_interface *intf;
+ struct usb_interface *intf;
struct usb_host_interface *alts;
struct usb_endpoint_descriptor *endpt;
@@ -478,7 +499,7 @@ static int findintfep(struct usb_device *dev, unsigned int ep)
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
intf = dev->actconfig->interface[i];
for (j = 0; j < intf->num_altsetting; j++) {
- alts = &intf->altsetting[j];
+ alts = &intf->altsetting[j];
for (e = 0; e < alts->desc.bNumEndpoints; e++) {
endpt = &alts->endpoint[e].desc;
if (endpt->bEndpointAddress == ep)
@@ -486,10 +507,11 @@ static int findintfep(struct usb_device *dev, unsigned int ep)
}
}
}
- return -ENOENT;
+ return -ENOENT;
}
-static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsigned int index)
+static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
+ unsigned int index)
{
int ret = 0;
@@ -502,7 +524,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
index &= 0xff;
switch (requesttype & USB_RECIP_MASK) {
case USB_RECIP_ENDPOINT:
- if ((ret = findintfep(ps->dev, index)) >= 0)
+ ret = findintfep(ps->dev, index);
+ if (ret >= 0)
ret = checkintf(ps, ret);
break;
@@ -546,7 +569,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
mutex_lock(&usbfs_mutex);
ret = -ENOMEM;
- if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
+ ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL);
+ if (!ps)
goto out;
ret = -ENOENT;
@@ -627,15 +651,18 @@ static int proc_control(struct dev_state *ps, void __user *arg)
if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
return -EFAULT;
- if ((ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex)))
+ ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex);
+ if (ret)
return ret;
if (ctrl.wLength > PAGE_SIZE)
return -EINVAL;
- if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))
+ tbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
+ if (!tbuf)
return -ENOMEM;
tmo = ctrl.timeout;
if (ctrl.bRequestType & 0x80) {
- if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data, ctrl.wLength)) {
+ if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data,
+ ctrl.wLength)) {
free_page((unsigned long)tbuf);
return -EINVAL;
}
@@ -646,14 +673,15 @@ static int proc_control(struct dev_state *ps, void __user *arg)
ctrl.wIndex, ctrl.wLength);
usb_unlock_device(dev);
- i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType,
- ctrl.wValue, ctrl.wIndex, tbuf, ctrl.wLength, tmo);
+ i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest,
+ ctrl.bRequestType, ctrl.wValue, ctrl.wIndex,
+ tbuf, ctrl.wLength, tmo);
usb_lock_device(dev);
if ((i > 0) && ctrl.wLength) {
if (usbfs_snoop) {
dev_info(&dev->dev, "control read: data ");
for (j = 0; j < i; ++j)
- printk("%02x ", (unsigned char)(tbuf)[j]);
+ printk("%02x ", (u8)(tbuf)[j]);
printk("\n");
}
if (copy_to_user(ctrl.data, tbuf, i)) {
@@ -680,12 +708,13 @@ static int proc_control(struct dev_state *ps, void __user *arg)
printk("\n");
}
usb_unlock_device(dev);
- i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType,
- ctrl.wValue, ctrl.wIndex, tbuf, ctrl.wLength, tmo);
+ i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest,
+ ctrl.bRequestType, ctrl.wValue, ctrl.wIndex,
+ tbuf, ctrl.wLength, tmo);
usb_lock_device(dev);
}
free_page((unsigned long)tbuf);
- if (i<0 && i != -EPIPE) {
+ if (i < 0 && i != -EPIPE) {
dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL "
"failed cmd %s rqt %u rq %u len %u ret %d\n",
current->comm, ctrl.bRequestType, ctrl.bRequest,
@@ -705,9 +734,11 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
if (copy_from_user(&bulk, arg, sizeof(bulk)))
return -EFAULT;
- if ((ret = findintfep(ps->dev, bulk.ep)) < 0)
+ ret = findintfep(ps->dev, bulk.ep);
+ if (ret < 0)
return ret;
- if ((ret = checkintf(ps, ret)))
+ ret = checkintf(ps, ret);
+ if (ret)
return ret;
if (bulk.ep & USB_DIR_IN)
pipe = usb_rcvbulkpipe(dev, bulk.ep & 0x7f);
@@ -735,7 +766,7 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)
if (usbfs_snoop) {
dev_info(&dev->dev, "bulk read: data ");
for (j = 0; j < len2; ++j)
- printk("%02x ", (unsigned char)(tbuf)[j]);
+ printk("%02x ", (u8)(tbuf)[j]);
printk("\n");
}
if (copy_to_user(bulk.data, tbuf, len2)) {
@@ -775,9 +806,11 @@ static int proc_resetep(struct dev_state *ps, void __user *arg)
if (get_user(ep, (unsigned int __user *)arg))
return -EFAULT;
- if ((ret = findintfep(ps->dev, ep)) < 0)
+ ret = findintfep(ps->dev, ep);
+ if (ret < 0)
return ret;
- if ((ret = checkintf(ps, ret)))
+ ret = checkintf(ps, ret);
+ if (ret)
return ret;
usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0);
return 0;
@@ -791,18 +824,19 @@ static int proc_clearhalt(struct dev_state *ps, void __user *arg)
if (get_user(ep, (unsigned int __user *)arg))
return -EFAULT;
- if ((ret = findintfep(ps->dev, ep)) < 0)
+ ret = findintfep(ps->dev, ep);
+ if (ret < 0)
return ret;
- if ((ret = checkintf(ps, ret)))
+ ret = checkintf(ps, ret);
+ if (ret)
return ret;
if (ep & USB_DIR_IN)
- pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f);
- else
- pipe = usb_sndbulkpipe(ps->dev, ep & 0x7f);
+ pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f);
+ else
+ pipe = usb_sndbulkpipe(ps->dev, ep & 0x7f);
return usb_clear_halt(ps->dev, pipe);
}
-
static int proc_getdriver(struct dev_state *ps, void __user *arg)
{
@@ -856,23 +890,23 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg)
{
int u;
int status = 0;
- struct usb_host_config *actconfig;
+ struct usb_host_config *actconfig;
if (get_user(u, (int __user *)arg))
return -EFAULT;
- actconfig = ps->dev->actconfig;
-
- /* Don't touch the device if any interfaces are claimed.
- * It could interfere with other drivers' operations, and if
+ actconfig = ps->dev->actconfig;
+
+ /* Don't touch the device if any interfaces are claimed.
+ * It could interfere with other drivers' operations, and if
* an interface is claimed by usbfs it could easily deadlock.
*/
- if (actconfig) {
- int i;
-
- for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) {
- if (usb_interface_claimed(actconfig->interface[i])) {
- dev_warn (&ps->dev->dev,
+ if (actconfig) {
+ int i;
+
+ for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) {
+ if (usb_interface_claimed(actconfig->interface[i])) {
+ dev_warn(&ps->dev->dev,
"usbfs: interface %d claimed by %s "
"while '%s' sets config #%d\n",
actconfig->interface[i]
@@ -881,11 +915,11 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg)
actconfig->interface[i]
->dev.driver->name,
current->comm, u);
- status = -EBUSY;
+ status = -EBUSY;
break;
}
- }
- }
+ }
+ }
/* SET_CONFIGURATION is often abused as a "cheap" driver reset,
* so avoid usb_set_configuration()'s kick to sysfs
@@ -901,8 +935,8 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg)
}
static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
- struct usbdevfs_iso_packet_desc __user *iso_frame_desc,
- void __user *arg)
+ struct usbdevfs_iso_packet_desc __user *iso_frame_desc,
+ void __user *arg)
{
struct usbdevfs_iso_packet_desc *isopkt = NULL;
struct usb_host_endpoint *ep;
@@ -917,12 +951,16 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
return -EINVAL;
if (!uurb->buffer)
return -EINVAL;
- if (uurb->signr != 0 && (uurb->signr < SIGRTMIN || uurb->signr > SIGRTMAX))
+ if (uurb->signr != 0 && (uurb->signr < SIGRTMIN ||
+ uurb->signr > SIGRTMAX))
return -EINVAL;
- if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
- if ((ifnum = findintfep(ps->dev, uurb->endpoint)) < 0)
+ if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
+ (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
+ ifnum = findintfep(ps->dev, uurb->endpoint);
+ if (ifnum < 0)
return ifnum;
- if ((ret = checkintf(ps, ifnum)))
+ ret = checkintf(ps, ifnum);
+ if (ret)
return ret;
}
if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) {
@@ -938,10 +976,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
case USBDEVFS_URB_TYPE_CONTROL:
if (!usb_endpoint_xfer_control(&ep->desc))
return -EINVAL;
- /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */
- if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE))
+ /* min 8 byte setup packet,
+ * max 8 byte setup plus an arbitrary data stage */
+ if (uurb->buffer_length < 8 ||
+ uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE))
return -EINVAL;
- if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL)))
+ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
+ if (!dr)
return -ENOMEM;
if (copy_from_user(dr, uurb->buffer, 8)) {
kfree(dr);
@@ -951,7 +992,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
kfree(dr);
return -EINVAL;
}
- if ((ret = check_ctrlrecip(ps, dr->bRequestType, le16_to_cpup(&dr->wIndex)))) {
+ ret = check_ctrlrecip(ps, dr->bRequestType,
+ le16_to_cpup(&dr->wIndex));
+ if (ret) {
kfree(dr);
return ret;
}
@@ -997,11 +1040,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
case USBDEVFS_URB_TYPE_ISO:
/* arbitrary limit */
- if (uurb->number_of_packets < 1 || uurb->number_of_packets > 128)
+ if (uurb->number_of_packets < 1 ||
+ uurb->number_of_packets > 128)
return -EINVAL;
if (!usb_endpoint_xfer_isoc(&ep->desc))
return -EINVAL;
- isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets;
+ isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) *
+ uurb->number_of_packets;
if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
return -ENOMEM;
if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) {
@@ -1009,7 +1054,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
return -EFAULT;
}
for (totlen = u = 0; u < uurb->number_of_packets; u++) {
- /* arbitrary limit, sufficient for USB 2.0 high-bandwidth iso */
+ /* arbitrary limit,
+ * sufficient for USB 2.0 high-bandwidth iso */
if (isopkt[u].length > 8192) {
kfree(isopkt);
return -EINVAL;
@@ -1039,25 +1085,27 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
default:
return -EINVAL;
}
- if (!(as = alloc_async(uurb->number_of_packets))) {
+ as = alloc_async(uurb->number_of_packets);
+ if (!as) {
kfree(isopkt);
kfree(dr);
return -ENOMEM;
}
- if (!(as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL))) {
+ as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL);
+ if (!as->urb->transfer_buffer) {
kfree(isopkt);
kfree(dr);
free_async(as);
return -ENOMEM;
}
- as->urb->dev = ps->dev;
- as->urb->pipe = (uurb->type << 30) |
+ as->urb->dev = ps->dev;
+ as->urb->pipe = (uurb->type << 30) |
__create_pipe(ps->dev, uurb->endpoint & 0xf) |
(uurb->endpoint & USB_DIR_IN);
- as->urb->transfer_flags = uurb->flags |
+ as->urb->transfer_flags = uurb->flags |
(is_in ? URB_DIR_IN : URB_DIR_OUT);
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->number_of_packets = uurb->number_of_packets;
if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
@@ -1065,8 +1113,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
as->urb->interval = 1 << min(15, ep->desc.bInterval - 1);
else
as->urb->interval = ep->desc.bInterval;
- as->urb->context = as;
- as->urb->complete = async_completed;
+ as->urb->context = as;
+ as->urb->complete = async_completed;
for (totlen = u = 0; u < uurb->number_of_packets; u++) {
as->urb->iso_frame_desc[u].offset = totlen;
as->urb->iso_frame_desc[u].length = isopkt[u].length;
@@ -1074,7 +1122,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
}
kfree(isopkt);
as->ps = ps;
- as->userurb = arg;
+ as->userurb = arg;
if (uurb->endpoint & USB_DIR_IN)
as->userbuffer = uurb->buffer;
else
@@ -1093,14 +1141,15 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
}
}
snoop_urb(as->urb, as->userurb);
- async_newpending(as);
- if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) {
- dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret);
- async_removepending(as);
- free_async(as);
- return ret;
- }
- return 0;
+ async_newpending(as);
+ if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) {
+ dev_printk(KERN_DEBUG, &ps->dev->dev,
+ "usbfs: usb_submit_urb returned %d\n", ret);
+ async_removepending(as);
+ free_async(as);
+ return ret;
+ }
+ return 0;
}
static int proc_submiturb(struct dev_state *ps, void __user *arg)
@@ -1110,7 +1159,9 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg)
if (copy_from_user(&uurb, arg, sizeof(uurb)))
return -EFAULT;
- return proc_do_submiturb(ps, &uurb, (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), arg);
+ return proc_do_submiturb(ps, &uurb,
+ (((struct usbdevfs_urb __user *)arg)->iso_frame_desc),
+ arg);
}
static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
@@ -1132,7 +1183,8 @@ static int processcompl(struct async *as, void __user * __user *arg)
unsigned int i;
if (as->userbuffer)
- if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length))
+ if (copy_to_user(as->userbuffer, urb->transfer_buffer,
+ urb->transfer_buffer_length))
return -EFAULT;
if (put_user(as->status, &userurb->status))
return -EFAULT;
@@ -1159,16 +1211,17 @@ static int processcompl(struct async *as, void __user * __user *arg)
return 0;
}
-static struct async* reap_as(struct dev_state *ps)
+static struct async *reap_as(struct dev_state *ps)
{
- DECLARE_WAITQUEUE(wait, current);
+ DECLARE_WAITQUEUE(wait, current);
struct async *as = NULL;
struct usb_device *dev = ps->dev;
add_wait_queue(&ps->wait, &wait);
for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
- if ((as = async_getcompleted(ps)))
+ as = async_getcompleted(ps);
+ if (as)
break;
if (signal_pending(current))
break;
@@ -1232,10 +1285,12 @@ static int proc_submiturb_compat(struct dev_state *ps, void __user *arg)
{
struct usbdevfs_urb uurb;
- if (get_urb32(&uurb,(struct usbdevfs_urb32 __user *)arg))
+ if (get_urb32(&uurb, (struct usbdevfs_urb32 __user *)arg))
return -EFAULT;
- return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, arg);
+ return proc_do_submiturb(ps, &uurb,
+ ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc,
+ arg);
}
static int processcompl_compat(struct async *as, void __user * __user *arg)
@@ -1246,7 +1301,8 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
unsigned int i;
if (as->userbuffer)
- if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length))
+ if (copy_to_user(as->userbuffer, urb->transfer_buffer,
+ urb->transfer_buffer_length))
return -EFAULT;
if (put_user(as->status, &userurb->status))
return -EFAULT;
@@ -1337,16 +1393,16 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
struct usb_driver *driver = NULL;
/* alloc buffer */
- if ((size = _IOC_SIZE (ctl->ioctl_code)) > 0) {
- if ((buf = kmalloc (size, GFP_KERNEL)) == NULL)
+ if ((size = _IOC_SIZE(ctl->ioctl_code)) > 0) {
+ if ((buf = kmalloc(size, GFP_KERNEL)) == NULL)
return -ENOMEM;
if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) {
- if (copy_from_user (buf, ctl->data, size)) {
+ if (copy_from_user(buf, ctl->data, size)) {
kfree(buf);
return -EFAULT;
}
} else {
- memset (buf, 0, size);
+ memset(buf, 0, size);
}
}
@@ -1357,15 +1413,15 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
if (ps->dev->state != USB_STATE_CONFIGURED)
retval = -EHOSTUNREACH;
- else if (!(intf = usb_ifnum_to_if (ps->dev, ctl->ifno)))
- retval = -EINVAL;
+ else if (!(intf = usb_ifnum_to_if(ps->dev, ctl->ifno)))
+ retval = -EINVAL;
else switch (ctl->ioctl_code) {
/* disconnect kernel driver from interface */
case USBDEVFS_DISCONNECT:
if (intf->dev.driver) {
driver = to_usb_driver(intf->dev.driver);
- dev_dbg (&intf->dev, "disconnect by usbfs\n");
+ dev_dbg(&intf->dev, "disconnect by usbfs\n");
usb_driver_release_interface(driver, intf);
} else
retval = -ENODATA;
@@ -1373,9 +1429,10 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
/* let kernel drivers try to (re)bind to the interface */
case USBDEVFS_CONNECT:
- usb_unlock_device(ps->dev);
- retval = bus_rescan_devices(intf->dev.bus);
- usb_lock_device(ps->dev);
+ if (!intf->dev.driver)
+ retval = device_attach(&intf->dev);
+ else
+ retval = -EBUSY;
break;
/* talk directly to the interface's driver */
@@ -1385,7 +1442,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
if (driver == NULL || driver->ioctl == NULL) {
retval = -ENOTTY;
} else {
- retval = driver->ioctl (intf, ctl->ioctl_code, buf);
+ retval = driver->ioctl(intf, ctl->ioctl_code, buf);
if (retval == -ENOIOCTLCMD)
retval = -ENOTTY;
}
@@ -1393,9 +1450,9 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl)
/* cleanup and return */
if (retval >= 0
- && (_IOC_DIR (ctl->ioctl_code) & _IOC_READ) != 0
+ && (_IOC_DIR(ctl->ioctl_code) & _IOC_READ) != 0
&& size > 0
- && copy_to_user (ctl->data, buf, size) != 0)
+ && copy_to_user(ctl->data, buf, size) != 0)
retval = -EFAULT;
kfree(buf);
@@ -1406,7 +1463,7 @@ static int proc_ioctl_default(struct dev_state *ps, void __user *arg)
{
struct usbdevfs_ioctl ctrl;
- if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
+ if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
return -EFAULT;
return proc_ioctl(ps, &ctrl);
}
@@ -1434,7 +1491,8 @@ static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg)
* are assuming that somehow the configuration has been prevented from
* changing. But there's no mechanism to ensure that...
*/
-static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static int usbdev_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct dev_state *ps = file->private_data;
struct usb_device *dev = ps->dev;
@@ -1577,7 +1635,8 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
}
/* No kernel lock - fine */
-static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wait)
+static unsigned int usbdev_poll(struct file *file,
+ struct poll_table_struct *wait)
{
struct dev_state *ps = file->private_data;
unsigned int mask = 0;
@@ -1648,7 +1707,7 @@ int __init usb_devio_init(void)
int retval;
retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
- "usb_device");
+ "usb_device");
if (retval) {
err("unable to register minors for usb_device");
goto out;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 8586817698a..801b6f142fa 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -91,8 +91,8 @@ static int usb_create_newid_file(struct usb_driver *usb_drv)
goto exit;
if (usb_drv->probe != NULL)
- error = sysfs_create_file(&usb_drv->drvwrap.driver.kobj,
- &driver_attr_new_id.attr);
+ error = driver_create_file(&usb_drv->drvwrap.driver,
+ &driver_attr_new_id);
exit:
return error;
}
@@ -103,8 +103,8 @@ static void usb_remove_newid_file(struct usb_driver *usb_drv)
return;
if (usb_drv->probe != NULL)
- sysfs_remove_file(&usb_drv->drvwrap.driver.kobj,
- &driver_attr_new_id.attr);
+ driver_remove_file(&usb_drv->drvwrap.driver,
+ &driver_attr_new_id);
}
static void usb_free_dynids(struct usb_driver *usb_drv)
@@ -202,10 +202,10 @@ static int usb_probe_interface(struct device *dev)
intf = to_usb_interface(dev);
udev = interface_to_usbdev(intf);
- if (udev->authorized == 0) {
- dev_err(&intf->dev, "Device is not authorized for usage\n");
- return -ENODEV;
- }
+ if (udev->authorized == 0) {
+ dev_err(&intf->dev, "Device is not authorized for usage\n");
+ return -ENODEV;
+ }
id = usb_match_id(intf, driver->id_table);
if (!id)
@@ -299,7 +299,7 @@ static int usb_unbind_interface(struct device *dev)
* lock.
*/
int usb_driver_claim_interface(struct usb_driver *driver,
- struct usb_interface *iface, void* priv)
+ struct usb_interface *iface, void *priv)
{
struct device *dev = &iface->dev;
struct usb_device *udev = interface_to_usbdev(iface);
@@ -325,7 +325,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
return retval;
}
-EXPORT_SYMBOL(usb_driver_claim_interface);
+EXPORT_SYMBOL_GPL(usb_driver_claim_interface);
/**
* usb_driver_release_interface - unbind a driver from an interface
@@ -370,7 +370,7 @@ void usb_driver_release_interface(struct usb_driver *driver,
iface->needs_remote_wakeup = 0;
usb_pm_unlock(udev);
}
-EXPORT_SYMBOL(usb_driver_release_interface);
+EXPORT_SYMBOL_GPL(usb_driver_release_interface);
/* returns 0 if no match, 1 if match */
int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
@@ -398,7 +398,7 @@ int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
return 0;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
- (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
+ (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))
return 0;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
@@ -534,15 +534,15 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface,
id->driver_info is the way to create an entry that
indicates that the driver want to examine every
device and interface. */
- for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
- id->driver_info; id++) {
+ for (; id->idVendor || id->idProduct || id->bDeviceClass ||
+ id->bInterfaceClass || id->driver_info; id++) {
if (usb_match_one_id(interface, id))
return id;
}
return NULL;
}
-EXPORT_SYMBOL_GPL_FUTURE(usb_match_id);
+EXPORT_SYMBOL_GPL(usb_match_id);
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
@@ -585,11 +585,8 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct usb_device *usb_dev;
- if (!dev)
- return -ENODEV;
-
/* driver is often null here; dev_dbg() would oops */
- pr_debug ("usb %s: uevent\n", dev->bus_id);
+ pr_debug("usb %s: uevent\n", dev->bus_id);
if (is_usb_device(dev))
usb_dev = to_usb_device(dev);
@@ -599,11 +596,11 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
}
if (usb_dev->devnum < 0) {
- pr_debug ("usb %s: already deleted?\n", dev->bus_id);
+ pr_debug("usb %s: already deleted?\n", dev->bus_id);
return -ENODEV;
}
if (!usb_dev->bus) {
- pr_debug ("usb %s: bus removed?\n", dev->bus_id);
+ pr_debug("usb %s: bus removed?\n", dev->bus_id);
return -ENODEV;
}
@@ -631,14 +628,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
usb_dev->descriptor.bDeviceProtocol))
return -ENOMEM;
- if (add_uevent_var(env, "BUSNUM=%03d",
- usb_dev->bus->busnum))
- return -ENOMEM;
-
- if (add_uevent_var(env, "DEVNUM=%03d",
- usb_dev->devnum))
- return -ENOMEM;
-
return 0;
}
@@ -756,7 +745,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
return retval;
}
-EXPORT_SYMBOL_GPL_FUTURE(usb_register_driver);
+EXPORT_SYMBOL_GPL(usb_register_driver);
/**
* usb_deregister - unregister a USB interface driver
@@ -780,7 +769,7 @@ void usb_deregister(struct usb_driver *driver)
usbfs_update_special();
}
-EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
+EXPORT_SYMBOL_GPL(usb_deregister);
#ifdef CONFIG_PM
@@ -865,8 +854,10 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
dev_err(&intf->dev, "%s error %d\n",
"suspend", status);
} else {
- // FIXME else if there's no suspend method, disconnect...
- // Not possible if auto_pm is set...
+ /*
+ * FIXME else if there's no suspend method, disconnect...
+ * Not possible if auto_pm is set...
+ */
dev_warn(&intf->dev, "no suspend for driver %s?\n",
driver->name);
mark_quiesced(intf);
@@ -905,7 +896,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
dev_err(&intf->dev, "%s error %d\n",
"reset_resume", status);
} else {
- // status = -EOPNOTSUPP;
+ /* status = -EOPNOTSUPP; */
dev_warn(&intf->dev, "no %s for driver %s?\n",
"reset_resume", driver->name);
}
@@ -916,7 +907,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
dev_err(&intf->dev, "%s error %d\n",
"resume", status);
} else {
- // status = -EOPNOTSUPP;
+ /* status = -EOPNOTSUPP; */
dev_warn(&intf->dev, "no %s for driver %s?\n",
"resume", driver->name);
}
@@ -1186,7 +1177,7 @@ static int usb_resume_both(struct usb_device *udev)
* so if a root hub's controller is suspended
* then we're stuck. */
status = usb_resume_device(udev);
- }
+ }
} else {
/* Needed for setting udev->dev.power.power_state.event,
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 5d860bc9b42..8133c99c6c5 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -204,7 +204,7 @@ int usb_register_dev(struct usb_interface *intf,
exit:
return retval;
}
-EXPORT_SYMBOL(usb_register_dev);
+EXPORT_SYMBOL_GPL(usb_register_dev);
/**
* usb_deregister_dev - deregister a USB device's dynamic minor.
@@ -245,4 +245,4 @@ void usb_deregister_dev(struct usb_interface *intf,
intf->minor = -1;
destroy_usb_class();
}
-EXPORT_SYMBOL(usb_deregister_dev);
+EXPORT_SYMBOL_GPL(usb_deregister_dev);
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 5cf6d5f9acb..84760ddbc33 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -1,6 +1,6 @@
/*
* (C) Copyright David Brownell 2000-2002
- *
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -55,7 +55,7 @@
*
* Store this function in the HCD's struct pci_driver as probe().
*/
-int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
+int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct hc_driver *driver;
struct usb_hcd *hcd;
@@ -64,87 +64,92 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
if (usb_disabled())
return -ENODEV;
- if (!id || !(driver = (struct hc_driver *) id->driver_data))
+ if (!id)
+ return -EINVAL;
+ driver = (struct hc_driver *)id->driver_data;
+ if (!driver)
return -EINVAL;
- if (pci_enable_device (dev) < 0)
+ if (pci_enable_device(dev) < 0)
return -ENODEV;
dev->current_state = PCI_D0;
dev->dev.power.power_state = PMSG_ON;
-
- if (!dev->irq) {
- dev_err (&dev->dev,
+
+ if (!dev->irq) {
+ dev_err(&dev->dev,
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
pci_name(dev));
- retval = -ENODEV;
+ retval = -ENODEV;
goto err1;
- }
+ }
- hcd = usb_create_hcd (driver, &dev->dev, pci_name(dev));
+ hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
if (!hcd) {
retval = -ENOMEM;
goto err1;
}
- if (driver->flags & HCD_MEMORY) { // EHCI, OHCI
- hcd->rsrc_start = pci_resource_start (dev, 0);
- hcd->rsrc_len = pci_resource_len (dev, 0);
- if (!request_mem_region (hcd->rsrc_start, hcd->rsrc_len,
+ if (driver->flags & HCD_MEMORY) {
+ /* EHCI, OHCI */
+ hcd->rsrc_start = pci_resource_start(dev, 0);
+ hcd->rsrc_len = pci_resource_len(dev, 0);
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description)) {
- dev_dbg (&dev->dev, "controller already in use\n");
+ dev_dbg(&dev->dev, "controller already in use\n");
retval = -EBUSY;
goto err2;
}
- hcd->regs = ioremap_nocache (hcd->rsrc_start, hcd->rsrc_len);
+ hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
if (hcd->regs == NULL) {
- dev_dbg (&dev->dev, "error mapping memory\n");
+ dev_dbg(&dev->dev, "error mapping memory\n");
retval = -EFAULT;
goto err3;
}
- } else { // UHCI
+ } else {
+ /* UHCI */
int region;
for (region = 0; region < PCI_ROM_RESOURCE; region++) {
- if (!(pci_resource_flags (dev, region) &
+ if (!(pci_resource_flags(dev, region) &
IORESOURCE_IO))
continue;
- hcd->rsrc_start = pci_resource_start (dev, region);
- hcd->rsrc_len = pci_resource_len (dev, region);
- if (request_region (hcd->rsrc_start, hcd->rsrc_len,
+ hcd->rsrc_start = pci_resource_start(dev, region);
+ hcd->rsrc_len = pci_resource_len(dev, region);
+ if (request_region(hcd->rsrc_start, hcd->rsrc_len,
driver->description))
break;
}
if (region == PCI_ROM_RESOURCE) {
- dev_dbg (&dev->dev, "no i/o regions available\n");
+ dev_dbg(&dev->dev, "no i/o regions available\n");
retval = -EBUSY;
goto err1;
}
}
- pci_set_master (dev);
+ pci_set_master(dev);
- retval = usb_add_hcd (hcd, dev->irq, IRQF_SHARED);
+ retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED);
if (retval != 0)
goto err4;
return retval;
err4:
if (driver->flags & HCD_MEMORY) {
- iounmap (hcd->regs);
+ iounmap(hcd->regs);
err3:
- release_mem_region (hcd->rsrc_start, hcd->rsrc_len);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
} else
- release_region (hcd->rsrc_start, hcd->rsrc_len);
+ release_region(hcd->rsrc_start, hcd->rsrc_len);
err2:
- usb_put_hcd (hcd);
+ usb_put_hcd(hcd);
err1:
- pci_disable_device (dev);
- dev_err (&dev->dev, "init %s fail, %d\n", pci_name(dev), retval);
+ pci_disable_device(dev);
+ dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval);
return retval;
-}
-EXPORT_SYMBOL (usb_hcd_pci_probe);
+}
+EXPORT_SYMBOL_GPL(usb_hcd_pci_probe);
/* may be called without controller electrically present */
@@ -161,7 +166,7 @@ EXPORT_SYMBOL (usb_hcd_pci_probe);
*
* Store this function in the HCD's struct pci_driver as remove().
*/
-void usb_hcd_pci_remove (struct pci_dev *dev)
+void usb_hcd_pci_remove(struct pci_dev *dev)
{
struct usb_hcd *hcd;
@@ -169,17 +174,17 @@ void usb_hcd_pci_remove (struct pci_dev *dev)
if (!hcd)
return;
- usb_remove_hcd (hcd);
+ usb_remove_hcd(hcd);
if (hcd->driver->flags & HCD_MEMORY) {
- iounmap (hcd->regs);
- release_mem_region (hcd->rsrc_start, hcd->rsrc_len);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
} else {
- release_region (hcd->rsrc_start, hcd->rsrc_len);
+ release_region(hcd->rsrc_start, hcd->rsrc_len);
}
- usb_put_hcd (hcd);
+ usb_put_hcd(hcd);
pci_disable_device(dev);
}
-EXPORT_SYMBOL (usb_hcd_pci_remove);
+EXPORT_SYMBOL_GPL(usb_hcd_pci_remove);
#ifdef CONFIG_PM
@@ -191,7 +196,7 @@ EXPORT_SYMBOL (usb_hcd_pci_remove);
*
* Store this function in the HCD's struct pci_driver as suspend().
*/
-int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
+int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
{
struct usb_hcd *hcd;
int retval = 0;
@@ -246,12 +251,18 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
/* no DMA or IRQs except when HC is active */
if (dev->current_state == PCI_D0) {
- pci_save_state (dev);
- pci_disable_device (dev);
+ pci_save_state(dev);
+ pci_disable_device(dev);
+ }
+
+ if (message.event == PM_EVENT_FREEZE ||
+ message.event == PM_EVENT_PRETHAW) {
+ dev_dbg(hcd->self.controller, "--> no state change\n");
+ goto done;
}
if (!has_pci_pm) {
- dev_dbg (hcd->self.controller, "--> PCI D0/legacy\n");
+ dev_dbg(hcd->self.controller, "--> PCI D0/legacy\n");
goto done;
}
@@ -260,30 +271,30 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
* PCI_D3 (but not PCI_D1 or PCI_D2) is allowed to reset
* some device state (e.g. as part of clock reinit).
*/
- retval = pci_set_power_state (dev, PCI_D3hot);
+ retval = pci_set_power_state(dev, PCI_D3hot);
suspend_report_result(pci_set_power_state, retval);
if (retval == 0) {
int wake = device_can_wakeup(&hcd->self.root_hub->dev);
wake = wake && device_may_wakeup(hcd->self.controller);
- dev_dbg (hcd->self.controller, "--> PCI D3%s\n",
+ dev_dbg(hcd->self.controller, "--> PCI D3%s\n",
wake ? "/wakeup" : "");
/* Ignore these return values. We rely on pci code to
* reject requests the hardware can't implement, rather
* than coding the same thing.
*/
- (void) pci_enable_wake (dev, PCI_D3hot, wake);
- (void) pci_enable_wake (dev, PCI_D3cold, wake);
+ (void) pci_enable_wake(dev, PCI_D3hot, wake);
+ (void) pci_enable_wake(dev, PCI_D3cold, wake);
} else {
- dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
+ dev_dbg(&dev->dev, "PCI D3 suspend fail, %d\n",
retval);
- (void) usb_hcd_pci_resume (dev);
+ (void) usb_hcd_pci_resume(dev);
}
} else if (hcd->state != HC_STATE_HALT) {
- dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n",
+ dev_dbg(hcd->self.controller, "hcd state %d; not suspended\n",
hcd->state);
WARN_ON(1);
retval = -EINVAL;
@@ -298,7 +309,7 @@ done:
if (machine_is(powermac)) {
struct device_node *of_node;
- of_node = pci_device_to_OF_node (dev);
+ of_node = pci_device_to_OF_node(dev);
if (of_node)
pmac_call_feature(PMAC_FTR_USB_ENABLE,
of_node, 0, 0);
@@ -308,7 +319,7 @@ done:
return retval;
}
-EXPORT_SYMBOL (usb_hcd_pci_suspend);
+EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend);
/**
* usb_hcd_pci_resume - power management resume of a PCI-based HCD
@@ -316,14 +327,14 @@ EXPORT_SYMBOL (usb_hcd_pci_suspend);
*
* Store this function in the HCD's struct pci_driver as resume().
*/
-int usb_hcd_pci_resume (struct pci_dev *dev)
+int usb_hcd_pci_resume(struct pci_dev *dev)
{
struct usb_hcd *hcd;
int retval;
hcd = pci_get_drvdata(dev);
if (hcd->state != HC_STATE_SUSPENDED) {
- dev_dbg (hcd->self.controller,
+ dev_dbg(hcd->self.controller,
"can't resume, not suspended!\n");
return 0;
}
@@ -333,9 +344,9 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
if (machine_is(powermac)) {
struct device_node *of_node;
- of_node = pci_device_to_OF_node (dev);
+ of_node = pci_device_to_OF_node(dev);
if (of_node)
- pmac_call_feature (PMAC_FTR_USB_ENABLE,
+ pmac_call_feature(PMAC_FTR_USB_ENABLE,
of_node, 0, 1);
}
#endif
@@ -374,8 +385,8 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
}
#endif
/* yes, ignore these results too... */
- (void) pci_enable_wake (dev, dev->current_state, 0);
- (void) pci_enable_wake (dev, PCI_D3cold, 0);
+ (void) pci_enable_wake(dev, dev->current_state, 0);
+ (void) pci_enable_wake(dev, PCI_D3cold, 0);
} else {
/* Same basic cases: clean (powered/not), dirty */
dev_dbg(hcd->self.controller, "PCI legacy resume\n");
@@ -386,14 +397,14 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
* but that won't re-enable bus mastering. Yet pci_disable_device()
* explicitly disables bus mastering...
*/
- retval = pci_enable_device (dev);
+ retval = pci_enable_device(dev);
if (retval < 0) {
- dev_err (hcd->self.controller,
+ dev_err(hcd->self.controller,
"can't re-enable after resume, %d!\n", retval);
return retval;
}
- pci_set_master (dev);
- pci_restore_state (dev);
+ pci_set_master(dev);
+ pci_restore_state(dev);
dev->dev.power.power_state = PMSG_ON;
@@ -402,15 +413,15 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
if (hcd->driver->resume) {
retval = hcd->driver->resume(hcd);
if (retval) {
- dev_err (hcd->self.controller,
+ dev_err(hcd->self.controller,
"PCI post-resume error %d!\n", retval);
- usb_hc_died (hcd);
+ usb_hc_died(hcd);
}
}
return retval;
}
-EXPORT_SYMBOL (usb_hcd_pci_resume);
+EXPORT_SYMBOL_GPL(usb_hcd_pci_resume);
#endif /* CONFIG_PM */
@@ -418,7 +429,7 @@ EXPORT_SYMBOL (usb_hcd_pci_resume);
* usb_hcd_pci_shutdown - shutdown host controller
* @dev: USB Host Controller being shutdown
*/
-void usb_hcd_pci_shutdown (struct pci_dev *dev)
+void usb_hcd_pci_shutdown(struct pci_dev *dev)
{
struct usb_hcd *hcd;
@@ -429,5 +440,5 @@ void usb_hcd_pci_shutdown (struct pci_dev *dev)
if (hcd->driver->shutdown)
hcd->driver->shutdown(hcd);
}
-EXPORT_SYMBOL (usb_hcd_pci_shutdown);
+EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 3dd997df850..e52ed1663b3 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -30,12 +30,12 @@
#include <linux/utsname.h>
#include <linux/mm.h>
#include <asm/io.h>
-#include <asm/scatterlist.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
@@ -132,8 +132,8 @@ static const u8 usb2_rh_dev_descriptor [18] = {
0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/
0x40, /* __u8 bMaxPacketSize0; 64 Bytes */
- 0x00, 0x00, /* __le16 idVendor; */
- 0x00, 0x00, /* __le16 idProduct; */
+ 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */
+ 0x02, 0x00, /* __le16 idProduct; device 0x0002 */
KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */
0x03, /* __u8 iManufacturer; */
@@ -155,8 +155,8 @@ static const u8 usb11_rh_dev_descriptor [18] = {
0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */
0x40, /* __u8 bMaxPacketSize0; 64 Bytes */
- 0x00, 0x00, /* __le16 idVendor; */
- 0x00, 0x00, /* __le16 idProduct; */
+ 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */
+ 0x01, 0x00, /* __le16 idProduct; device 0x0001 */
KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */
0x03, /* __u8 iManufacturer; */
@@ -808,13 +808,13 @@ static int usb_register_bus(struct usb_bus *bus)
}
set_bit (busnum, busmap.busmap);
bus->busnum = busnum;
- bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0),
- bus->controller, "usb_host%d",
- busnum);
- result = PTR_ERR(bus->class_dev);
- if (IS_ERR(bus->class_dev))
+
+ bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0),
+ "usb_host%d", busnum);
+ result = PTR_ERR(bus->dev);
+ if (IS_ERR(bus->dev))
goto error_create_class_dev;
- class_set_devdata(bus->class_dev, bus);
+ dev_set_drvdata(bus->dev, bus);
/* Add it to the local list of buses */
list_add (&bus->bus_list, &usb_bus_list);
@@ -858,7 +858,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
clear_bit (bus->busnum, busmap.busmap);
- class_device_unregister(bus->class_dev);
+ device_unregister(bus->dev);
}
/**
@@ -971,7 +971,7 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)
return -1;
}
}
-EXPORT_SYMBOL (usb_calc_bus_time);
+EXPORT_SYMBOL_GPL(usb_calc_bus_time);
/*-------------------------------------------------------------------------*/
@@ -1113,48 +1113,177 @@ void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb)
}
EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep);
-static void map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+/*
+ * Some usb host controllers can only perform dma using a small SRAM area.
+ * The usb core itself is however optimized for host controllers that can dma
+ * using regular system memory - like pci devices doing bus mastering.
+ *
+ * To support host controllers with limited dma capabilites we provide dma
+ * bounce buffers. This feature can be enabled using the HCD_LOCAL_MEM flag.
+ * For this to work properly the host controller code must first use the
+ * function dma_declare_coherent_memory() to point out which memory area
+ * that should be used for dma allocations.
+ *
+ * The HCD_LOCAL_MEM flag then tells the usb code to allocate all data for
+ * dma using dma_alloc_coherent() which in turn allocates from the memory
+ * area pointed out with dma_declare_coherent_memory().
+ *
+ * So, to summarize...
+ *
+ * - We need "local" memory, canonical example being
+ * a small SRAM on a discrete controller being the
+ * only memory that the controller can read ...
+ * (a) "normal" kernel memory is no good, and
+ * (b) there's not enough to share
+ *
+ * - The only *portable* hook for such stuff in the
+ * DMA framework is dma_declare_coherent_memory()
+ *
+ * - So we use that, even though the primary requirement
+ * is that the memory be "local" (hence addressible
+ * by that device), not "coherent".
+ *
+ */
+
+static int hcd_alloc_coherent(struct usb_bus *bus,
+ gfp_t mem_flags, dma_addr_t *dma_handle,
+ void **vaddr_handle, size_t size,
+ enum dma_data_direction dir)
{
+ unsigned char *vaddr;
+
+ vaddr = hcd_buffer_alloc(bus, size + sizeof(vaddr),
+ mem_flags, dma_handle);
+ if (!vaddr)
+ return -ENOMEM;
+
+ /*
+ * Store the virtual address of the buffer at the end
+ * of the allocated dma buffer. The size of the buffer
+ * may be uneven so use unaligned functions instead
+ * of just rounding up. It makes sense to optimize for
+ * memory footprint over access speed since the amount
+ * of memory available for dma may be limited.
+ */
+ put_unaligned((unsigned long)*vaddr_handle,
+ (unsigned long *)(vaddr + size));
+
+ if (dir == DMA_TO_DEVICE)
+ memcpy(vaddr, *vaddr_handle, size);
+
+ *vaddr_handle = vaddr;
+ return 0;
+}
+
+static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle,
+ void **vaddr_handle, size_t size,
+ enum dma_data_direction dir)
+{
+ unsigned char *vaddr = *vaddr_handle;
+
+ vaddr = (void *)get_unaligned((unsigned long *)(vaddr + size));
+
+ if (dir == DMA_FROM_DEVICE)
+ memcpy(vaddr, *vaddr_handle, size);
+
+ hcd_buffer_free(bus, size + sizeof(vaddr), *vaddr_handle, *dma_handle);
+
+ *vaddr_handle = vaddr;
+ *dma_handle = 0;
+}
+
+static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+{
+ enum dma_data_direction dir;
+ int ret = 0;
+
/* Map the URB's buffers for DMA access.
* Lower level HCD code should use *_dma exclusively,
* unless it uses pio or talks to another transport.
*/
- if (hcd->self.uses_dma && !is_root_hub(urb->dev)) {
- if (usb_endpoint_xfer_control(&urb->ep->desc)
- && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
- urb->setup_dma = dma_map_single (
+ if (is_root_hub(urb->dev))
+ return 0;
+
+ if (usb_endpoint_xfer_control(&urb->ep->desc)
+ && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
+ if (hcd->self.uses_dma)
+ urb->setup_dma = dma_map_single(
hcd->self.controller,
urb->setup_packet,
- sizeof (struct usb_ctrlrequest),
+ sizeof(struct usb_ctrlrequest),
DMA_TO_DEVICE);
- if (urb->transfer_buffer_length != 0
- && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
+ else if (hcd->driver->flags & HCD_LOCAL_MEM)
+ ret = hcd_alloc_coherent(
+ urb->dev->bus, mem_flags,
+ &urb->setup_dma,
+ (void **)&urb->setup_packet,
+ sizeof(struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
+ }
+
+ dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ if (ret == 0 && urb->transfer_buffer_length != 0
+ && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+ if (hcd->self.uses_dma)
urb->transfer_dma = dma_map_single (
hcd->self.controller,
urb->transfer_buffer,
urb->transfer_buffer_length,
- usb_urb_dir_in(urb)
- ? DMA_FROM_DEVICE
- : DMA_TO_DEVICE);
+ dir);
+ else if (hcd->driver->flags & HCD_LOCAL_MEM) {
+ ret = hcd_alloc_coherent(
+ urb->dev->bus, mem_flags,
+ &urb->transfer_dma,
+ &urb->transfer_buffer,
+ urb->transfer_buffer_length,
+ dir);
+
+ if (ret && usb_endpoint_xfer_control(&urb->ep->desc)
+ && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+ hcd_free_coherent(urb->dev->bus,
+ &urb->setup_dma,
+ (void **)&urb->setup_packet,
+ sizeof(struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
+ }
}
+ return ret;
}
static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
{
- if (hcd->self.uses_dma && !is_root_hub(urb->dev)) {
- if (usb_endpoint_xfer_control(&urb->ep->desc)
- && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+ enum dma_data_direction dir;
+
+ if (is_root_hub(urb->dev))
+ return;
+
+ if (usb_endpoint_xfer_control(&urb->ep->desc)
+ && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
+ if (hcd->self.uses_dma)
dma_unmap_single(hcd->self.controller, urb->setup_dma,
sizeof(struct usb_ctrlrequest),
DMA_TO_DEVICE);
- if (urb->transfer_buffer_length != 0
- && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
+ else if (hcd->driver->flags & HCD_LOCAL_MEM)
+ hcd_free_coherent(urb->dev->bus, &urb->setup_dma,
+ (void **)&urb->setup_packet,
+ sizeof(struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
+ }
+
+ dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ if (urb->transfer_buffer_length != 0
+ && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+ if (hcd->self.uses_dma)
dma_unmap_single(hcd->self.controller,
urb->transfer_dma,
urb->transfer_buffer_length,
- usb_urb_dir_in(urb)
- ? DMA_FROM_DEVICE
- : DMA_TO_DEVICE);
+ dir);
+ else if (hcd->driver->flags & HCD_LOCAL_MEM)
+ hcd_free_coherent(urb->dev->bus, &urb->transfer_dma,
+ &urb->transfer_buffer,
+ urb->transfer_buffer_length,
+ dir);
}
}
@@ -1186,7 +1315,12 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
* URBs must be submitted in process context with interrupts
* enabled.
*/
- map_urb_for_dma(hcd, urb);
+ status = map_urb_for_dma(hcd, urb, mem_flags);
+ if (unlikely(status)) {
+ usbmon_urb_submit_error(&hcd->self, urb, status);
+ goto error;
+ }
+
if (is_root_hub(urb->dev))
status = rh_urb_enqueue(hcd, urb);
else
@@ -1195,6 +1329,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
if (unlikely(status)) {
usbmon_urb_submit_error(&hcd->self, urb, status);
unmap_urb_for_dma(hcd, urb);
+ error:
urb->hcpriv = NULL;
INIT_LIST_HEAD(&urb->urb_list);
atomic_dec(&urb->use_count);
@@ -1292,7 +1427,7 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
wake_up (&usb_kill_urb_queue);
usb_put_urb (urb);
}
-EXPORT_SYMBOL (usb_hcd_giveback_urb);
+EXPORT_SYMBOL_GPL(usb_hcd_giveback_urb);
/*-------------------------------------------------------------------------*/
@@ -1312,8 +1447,8 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
hcd = bus_to_hcd(udev->bus);
/* No more submits can occur */
-rescan:
spin_lock_irq(&hcd_urb_list_lock);
+rescan:
list_for_each_entry (urb, &ep->urb_list, urb_list) {
int is_in;
@@ -1346,6 +1481,7 @@ rescan:
usb_put_urb (urb);
/* list contents may have changed */
+ spin_lock(&hcd_urb_list_lock);
goto rescan;
}
spin_unlock_irq(&hcd_urb_list_lock);
@@ -1531,7 +1667,7 @@ int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num)
mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(10));
return status;
}
-EXPORT_SYMBOL (usb_bus_start_enum);
+EXPORT_SYMBOL_GPL(usb_bus_start_enum);
#endif
@@ -1638,7 +1774,7 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
"USB Host Controller";
return hcd;
}
-EXPORT_SYMBOL (usb_create_hcd);
+EXPORT_SYMBOL_GPL(usb_create_hcd);
static void hcd_release (struct kref *kref)
{
@@ -1653,14 +1789,14 @@ struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd)
kref_get (&hcd->kref);
return hcd;
}
-EXPORT_SYMBOL (usb_get_hcd);
+EXPORT_SYMBOL_GPL(usb_get_hcd);
void usb_put_hcd (struct usb_hcd *hcd)
{
if (hcd)
kref_put (&hcd->kref, hcd_release);
}
-EXPORT_SYMBOL (usb_put_hcd);
+EXPORT_SYMBOL_GPL(usb_put_hcd);
/**
* usb_add_hcd - finish generic HCD structure initialization and register
@@ -1786,7 +1922,7 @@ err_register_bus:
hcd_buffer_destroy(hcd);
return retval;
}
-EXPORT_SYMBOL (usb_add_hcd);
+EXPORT_SYMBOL_GPL(usb_add_hcd);
/**
* usb_remove_hcd - shutdown processing for generic HCDs
@@ -1828,7 +1964,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
usb_deregister_bus(&hcd->self);
hcd_buffer_destroy(hcd);
}
-EXPORT_SYMBOL (usb_remove_hcd);
+EXPORT_SYMBOL_GPL(usb_remove_hcd);
void
usb_hcd_platform_shutdown(struct platform_device* dev)
@@ -1838,7 +1974,7 @@ usb_hcd_platform_shutdown(struct platform_device* dev)
if (hcd->driver->shutdown)
hcd->driver->shutdown(hcd);
}
-EXPORT_SYMBOL (usb_hcd_platform_shutdown);
+EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown);
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 98e24194a4a..2d1c3d5e47b 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -125,7 +125,7 @@ struct usb_hcd {
/* more shared queuing code would be good; it should support
* smarter scheduling, handle transaction translators, etc;
- * input size of periodic table to an interrupt scheduler.
+ * input size of periodic table to an interrupt scheduler.
* (ohci 32, uhci 1024, ehci 256/512/1024).
*/
@@ -133,16 +133,16 @@ struct usb_hcd {
* this structure.
*/
unsigned long hcd_priv[0]
- __attribute__ ((aligned (sizeof(unsigned long))));
+ __attribute__ ((aligned(sizeof(unsigned long))));
};
/* 2.4 does this a bit differently ... */
-static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
+static inline struct usb_bus *hcd_to_bus(struct usb_hcd *hcd)
{
return &hcd->self;
}
-static inline struct usb_hcd *bus_to_hcd (struct usb_bus *bus)
+static inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus)
{
return container_of(bus, struct usb_hcd, self);
}
@@ -165,6 +165,7 @@ struct hc_driver {
int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
+#define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
@@ -201,15 +202,18 @@ struct hc_driver {
struct usb_host_endpoint *ep);
/* root hub support */
- int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
- int (*hub_control) (struct usb_hcd *hcd,
+ int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
+ int (*hub_control) (struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
- int (*bus_suspend)(struct usb_hcd *);
- int (*bus_resume)(struct usb_hcd *);
- int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
- void (*hub_irq_enable)(struct usb_hcd *);
+ int (*bus_suspend)(struct usb_hcd *);
+ int (*bus_resume)(struct usb_hcd *);
+ 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 */
+ void (*relinquish_port)(struct usb_hcd *, int);
};
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
@@ -217,56 +221,56 @@ extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
int status);
extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb);
-extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags);
-extern int usb_hcd_unlink_urb (struct urb *urb, int status);
+extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags);
+extern int usb_hcd_unlink_urb(struct urb *urb, int status);
extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb,
int status);
extern void usb_hcd_flush_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
extern void usb_hcd_disable_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
-extern int usb_hcd_get_frame_number (struct usb_device *udev);
+extern int usb_hcd_get_frame_number(struct usb_device *udev);
-extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
+extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
struct device *dev, char *bus_name);
-extern struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd);
-extern void usb_put_hcd (struct usb_hcd *hcd);
+extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd);
+extern void usb_put_hcd(struct usb_hcd *hcd);
extern int usb_add_hcd(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags);
extern void usb_remove_hcd(struct usb_hcd *hcd);
struct platform_device;
-extern void usb_hcd_platform_shutdown(struct platform_device* dev);
+extern void usb_hcd_platform_shutdown(struct platform_device *dev);
#ifdef CONFIG_PCI
struct pci_dev;
struct pci_device_id;
-extern int usb_hcd_pci_probe (struct pci_dev *dev,
+extern int usb_hcd_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id);
-extern void usb_hcd_pci_remove (struct pci_dev *dev);
+extern void usb_hcd_pci_remove(struct pci_dev *dev);
#ifdef CONFIG_PM
-extern int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t state);
-extern int usb_hcd_pci_resume (struct pci_dev *dev);
+extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t state);
+extern int usb_hcd_pci_resume(struct pci_dev *dev);
#endif /* CONFIG_PM */
-extern void usb_hcd_pci_shutdown (struct pci_dev *dev);
+extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
#endif /* CONFIG_PCI */
/* pci-ish (pdev null is ok) buffer alloc/mapping support */
-int hcd_buffer_create (struct usb_hcd *hcd);
-void hcd_buffer_destroy (struct usb_hcd *hcd);
+int hcd_buffer_create(struct usb_hcd *hcd);
+void hcd_buffer_destroy(struct usb_hcd *hcd);
-void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
+void *hcd_buffer_alloc(struct usb_bus *bus, size_t size,
gfp_t mem_flags, dma_addr_t *dma);
-void hcd_buffer_free (struct usb_bus *bus, size_t size,
+void hcd_buffer_free(struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
/* generic bus glue, needed for host controllers that don't use PCI */
-extern irqreturn_t usb_hcd_irq (int irq, void *__hcd);
+extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
-extern void usb_hc_died (struct usb_hcd *hcd);
+extern void usb_hc_died(struct usb_hcd *hcd);
extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
/* -------------------------------------------------------------------------- */
@@ -319,9 +323,9 @@ extern void usb_destroy_configuration(struct usb_device *dev);
* Generic bandwidth allocation constants/support
*/
#define FRAME_TIME_USECS 1000L
-#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
+#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
/* Trying not to use worst-case bit-stuffing
- of (7/6 * 8 * bytecount) = 9.33 * bytecount */
+ * of (7/6 * 8 * bytecount) = 9.33 * bytecount */
/* bytecount = data payload byte count */
#define NS_TO_US(ns) ((ns + 500L) / 1000L)
@@ -333,9 +337,9 @@ extern void usb_destroy_configuration(struct usb_device *dev);
*/
#define BW_HOST_DELAY 1000L /* nanoseconds */
#define BW_HUB_LS_SETUP 333L /* nanoseconds */
- /* 4 full-speed bit times (est.) */
+ /* 4 full-speed bit times (est.) */
-#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
+#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
@@ -345,16 +349,16 @@ extern void usb_destroy_configuration(struct usb_device *dev);
* to preallocate bandwidth)
*/
#define USB2_HOST_DELAY 5 /* nsec, guess */
-#define HS_NSECS(bytes) ( ((55 * 8 * 2083) \
+#define HS_NSECS(bytes) (((55 * 8 * 2083) \
+ (2083UL * (3 + BitTime(bytes))))/1000 \
+ USB2_HOST_DELAY)
-#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083) \
+#define HS_NSECS_ISO(bytes) (((38 * 8 * 2083) \
+ (2083UL * (3 + BitTime(bytes))))/1000 \
+ USB2_HOST_DELAY)
#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes))
-extern long usb_calc_bus_time (int speed, int is_input,
+extern long usb_calc_bus_time(int speed, int is_input,
int isoc, int bytecount);
/*-------------------------------------------------------------------------*/
@@ -370,16 +374,16 @@ extern struct list_head usb_bus_list;
extern struct mutex usb_bus_list_lock;
extern wait_queue_head_t usb_kill_urb_queue;
-extern void usb_enable_root_hub_irq (struct usb_bus *bus);
+extern void usb_enable_root_hub_irq(struct usb_bus *bus);
-extern int usb_find_interface_driver (struct usb_device *dev,
+extern int usb_find_interface_driver(struct usb_device *dev,
struct usb_interface *interface);
#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
#ifdef CONFIG_PM
-extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
-extern void usb_root_hub_lost_power (struct usb_device *rhdev);
+extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd);
+extern void usb_root_hub_lost_power(struct usb_device *rhdev);
extern int hcd_bus_suspend(struct usb_device *rhdev);
extern int hcd_bus_resume(struct usb_device *rhdev);
#else
@@ -399,13 +403,13 @@ static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
* these are expected to be called from the USB core/hub thread
* with the kernel lock held
*/
-extern void usbfs_update_special (void);
+extern void usbfs_update_special(void);
extern int usbfs_init(void);
extern void usbfs_cleanup(void);
#else /* CONFIG_USB_DEVICEFS */
-static inline void usbfs_update_special (void) {}
+static inline void usbfs_update_special(void) {}
static inline int usbfs_init(void) { return 0; }
static inline void usbfs_cleanup(void) { }
@@ -460,7 +464,7 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
/*-------------------------------------------------------------------------*/
/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
-// bleech -- resurfaced in 2.4.11 or 2.4.12
+/* bleech -- resurfaced in 2.4.11 or 2.4.12 */
#define bitmap DeviceRemovable
@@ -468,8 +472,8 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
/* random stuff */
-#define RUN_CONTEXT (in_irq () ? "in_irq" \
- : (in_interrupt () ? "in_interrupt" : "can sleep"))
+#define RUN_CONTEXT (in_irq() ? "in_irq" \
+ : (in_interrupt() ? "in_interrupt" : "can sleep"))
/* This rwsem is for use only by the hub driver and ehci-hcd.
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 036c3dea855..68fc5219ca1 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -37,6 +37,13 @@
#define USB_PERSIST 0
#endif
+/* if we are in debug mode, always announce new devices */
+#ifdef DEBUG
+#ifndef CONFIG_USB_ANNOUNCE_NEW_DEVICES
+#define CONFIG_USB_ANNOUNCE_NEW_DEVICES
+#endif
+#endif
+
struct usb_hub {
struct device *intfdev; /* the "interface" device */
struct usb_device *hdev;
@@ -335,7 +342,7 @@ static void kick_khubd(struct usb_hub *hub)
to_usb_interface(hub->intfdev)->pm_usage_cnt = 1;
spin_lock_irqsave(&hub_event_lock, flags);
- if (!hub->disconnected & list_empty(&hub->event_list)) {
+ if (!hub->disconnected && list_empty(&hub->event_list)) {
list_add_tail(&hub->event_list, &hub_event_list);
wake_up(&khubd_wait);
}
@@ -487,6 +494,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
schedule_work (&tt->kevent);
spin_unlock_irqrestore (&tt->lock, flags);
}
+EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
static void hub_power_on(struct usb_hub *hub)
{
@@ -522,9 +530,9 @@ static void hub_quiesce(struct usb_hub *hub)
/* (blocking) stop khubd and related activity */
usb_kill_urb(hub->urb);
if (hub->has_indicators)
- cancel_delayed_work(&hub->leds);
- if (hub->has_indicators || hub->tt.hub)
- flush_scheduled_work();
+ cancel_delayed_work_sync(&hub->leds);
+ if (hub->tt.hub)
+ cancel_work_sync(&hub->tt.kevent);
}
static void hub_activate(struct usb_hub *hub)
@@ -1027,8 +1035,10 @@ static void recursively_mark_NOTATTACHED(struct usb_device *udev)
if (udev->children[i])
recursively_mark_NOTATTACHED(udev->children[i]);
}
- if (udev->state == USB_STATE_SUSPENDED)
+ if (udev->state == USB_STATE_SUSPENDED) {
udev->discon_suspended = 1;
+ udev->active_duration -= jiffies;
+ }
udev->state = USB_STATE_NOTATTACHED;
}
@@ -1077,6 +1087,12 @@ void usb_set_device_state(struct usb_device *udev,
else
device_init_wakeup(&udev->dev, 0);
}
+ if (udev->state == USB_STATE_SUSPENDED &&
+ new_state != USB_STATE_SUSPENDED)
+ udev->active_duration -= jiffies;
+ else if (new_state == USB_STATE_SUSPENDED &&
+ udev->state != USB_STATE_SUSPENDED)
+ udev->active_duration += jiffies;
udev->state = new_state;
} else
recursively_mark_NOTATTACHED(udev);
@@ -1207,7 +1223,7 @@ void usb_disconnect(struct usb_device **pdev)
put_device(&udev->dev);
}
-#ifdef DEBUG
+#ifdef CONFIG_USB_ANNOUNCE_NEW_DEVICES
static void show_string(struct usb_device *udev, char *id, char *string)
{
if (!string)
@@ -1215,12 +1231,24 @@ static void show_string(struct usb_device *udev, char *id, char *string)
dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, string);
}
+static void announce_device(struct usb_device *udev)
+{
+ dev_info(&udev->dev, "New USB device found, idVendor=%04x, idProduct=%04x\n",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+ dev_info(&udev->dev, "New USB device strings: Mfr=%d, Product=%d, "
+ "SerialNumber=%d\n",
+ udev->descriptor.iManufacturer,
+ udev->descriptor.iProduct,
+ udev->descriptor.iSerialNumber);
+ show_string(udev, "Product", udev->product);
+ show_string(udev, "Manufacturer", udev->manufacturer);
+ show_string(udev, "SerialNumber", udev->serial);
+}
#else
-static inline void show_string(struct usb_device *udev, char *id, char *string)
-{}
+static inline void announce_device(struct usb_device *udev) { }
#endif
-
#ifdef CONFIG_USB_OTG
#include "otg_whitelist.h"
#endif
@@ -1390,14 +1418,7 @@ int usb_new_device(struct usb_device *udev)
}
/* Tell the world! */
- dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, "
- "SerialNumber=%d\n",
- udev->descriptor.iManufacturer,
- udev->descriptor.iProduct,
- udev->descriptor.iSerialNumber);
- show_string(udev, "Product", udev->product);
- show_string(udev, "Manufacturer", udev->manufacturer);
- show_string(udev, "SerialNumber", udev->serial);
+ announce_device(udev);
return err;
fail:
@@ -2482,6 +2503,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
{
struct usb_device *hdev = hub->hdev;
struct device *hub_dev = hub->intfdev;
+ struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
int status, i;
@@ -2645,6 +2667,8 @@ loop:
done:
hub_port_disable(hub, port1, 1);
+ if (hcd->driver->relinquish_port && !hub->hdev->parent)
+ hcd->driver->relinquish_port(hcd, port1);
}
static void hub_events(void)
@@ -2946,7 +2970,7 @@ static int config_descriptors_changed(struct usb_device *udev)
if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
len = le16_to_cpu(udev->config[index].desc.wTotalLength);
}
- buf = kmalloc (len, GFP_KERNEL);
+ buf = kmalloc(len, GFP_NOIO);
if (buf == NULL) {
dev_err(&udev->dev, "no mem to re-read configs after reset\n");
/* assume the worst */
@@ -3093,7 +3117,7 @@ re_enumerate:
hub_port_logical_disconnect(parent_hub, port1);
return -ENODEV;
}
-EXPORT_SYMBOL(usb_reset_device);
+EXPORT_SYMBOL_GPL(usb_reset_device);
/**
* usb_reset_composite_device - warn interface drivers and perform a USB port reset
@@ -3110,16 +3134,12 @@ EXPORT_SYMBOL(usb_reset_device);
* this from a driver probe() routine after downloading new firmware.
* For calls that might not occur during probe(), drivers should lock
* the device using usb_lock_device_for_reset().
- *
- * The interface locks are acquired during the pre_reset stage and released
- * during the post_reset stage. However if iface is not NULL and is
- * currently being probed, we assume that the caller already owns its
- * lock.
*/
int usb_reset_composite_device(struct usb_device *udev,
struct usb_interface *iface)
{
int ret;
+ int i;
struct usb_host_config *config = udev->actconfig;
if (udev->state == USB_STATE_NOTATTACHED ||
@@ -3136,16 +3156,11 @@ int usb_reset_composite_device(struct usb_device *udev,
iface = NULL;
if (config) {
- int i;
- struct usb_interface *cintf;
- struct usb_driver *drv;
-
for (i = 0; i < config->desc.bNumInterfaces; ++i) {
- cintf = config->interface[i];
- if (cintf != iface)
- down(&cintf->dev.sem);
- if (device_is_registered(&cintf->dev) &&
- cintf->dev.driver) {
+ struct usb_interface *cintf = config->interface[i];
+ struct usb_driver *drv;
+
+ if (cintf->dev.driver) {
drv = to_usb_driver(cintf->dev.driver);
if (drv->pre_reset)
(drv->pre_reset)(cintf);
@@ -3157,25 +3172,20 @@ int usb_reset_composite_device(struct usb_device *udev,
ret = usb_reset_device(udev);
if (config) {
- int i;
- struct usb_interface *cintf;
- struct usb_driver *drv;
-
for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) {
- cintf = config->interface[i];
- if (device_is_registered(&cintf->dev) &&
- cintf->dev.driver) {
+ struct usb_interface *cintf = config->interface[i];
+ struct usb_driver *drv;
+
+ if (cintf->dev.driver) {
drv = to_usb_driver(cintf->dev.driver);
if (drv->post_reset)
(drv->post_reset)(cintf);
/* FIXME: Unbind if post_reset returns an error or isn't defined */
}
- if (cintf != iface)
- up(&cintf->dev.sem);
}
}
usb_autosuspend_device(udev);
return ret;
}
-EXPORT_SYMBOL(usb_reset_composite_device);
+EXPORT_SYMBOL_GPL(usb_reset_composite_device);
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index cf9559c6c9b..1551aed65e0 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -55,16 +55,16 @@
#define USB_PORT_FEAT_TEST 21
#define USB_PORT_FEAT_INDICATOR 22
-/*
+/*
* Hub Status and Hub Change results
* See USB 2.0 spec Table 11-19 and Table 11-20
*/
struct usb_port_status {
__le16 wPortStatus;
- __le16 wPortChange;
+ __le16 wPortChange;
} __attribute__ ((packed));
-/*
+/*
* wPortStatus bit field
* See USB 2.0 spec Table 11-21
*/
@@ -81,7 +81,7 @@ struct usb_port_status {
#define USB_PORT_STAT_INDICATOR 0x1000
/* bits 13 to 15 are reserved */
-/*
+/*
* wPortChange bit field
* See USB 2.0 spec Table 11-22
* Bits 0 to 4 shown, bits 5 to 15 are reserved
@@ -93,7 +93,7 @@ struct usb_port_status {
#define USB_PORT_STAT_C_RESET 0x0010
/*
- * wHubCharacteristics (masks)
+ * wHubCharacteristics (masks)
* See USB 2.0 spec Table 11-13, offset 3
*/
#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
@@ -119,8 +119,8 @@ struct usb_hub_status {
#define HUB_CHANGE_OVERCURRENT 0x0002
-/*
- * Hub descriptor
+/*
+ * Hub descriptor
* See USB 2.0 spec Table 11-13
*/
@@ -134,7 +134,7 @@ struct usb_hub_descriptor {
__le16 wHubCharacteristics;
__u8 bPwrOn2PwrGood;
__u8 bHubContrCurrent;
- /* add 1 bit for hub status change; round to bytes */
+ /* add 1 bit for hub status change; round to bytes */
__u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
__u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
} __attribute__ ((packed));
@@ -190,6 +190,6 @@ struct usb_tt_clear {
u16 devinfo;
};
-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);
#endif /* __LINUX_HUB_H */
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index cd4f1115728..83a373e9cc3 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -38,10 +38,15 @@
#include <linux/usbdevice_fs.h>
#include <linux/parser.h>
#include <linux/notifier.h>
+#include <linux/seq_file.h>
#include <asm/byteorder.h>
#include "usb.h"
#include "hcd.h"
+#define USBFS_DEFAULT_DEVMODE (S_IWUSR | S_IRUGO)
+#define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO)
+#define USBFS_DEFAULT_LISTMODE S_IRUGO
+
static struct super_operations usbfs_ops;
static const struct file_operations default_file_operations;
static struct vfsmount *usbfs_mount;
@@ -57,9 +62,33 @@ static uid_t listuid; /* = 0 */
static gid_t devgid; /* = 0 */
static gid_t busgid; /* = 0 */
static gid_t listgid; /* = 0 */
-static umode_t devmode = S_IWUSR | S_IRUGO;
-static umode_t busmode = S_IXUGO | S_IRUGO;
-static umode_t listmode = S_IRUGO;
+static umode_t devmode = USBFS_DEFAULT_DEVMODE;
+static umode_t busmode = USBFS_DEFAULT_BUSMODE;
+static umode_t listmode = USBFS_DEFAULT_LISTMODE;
+
+static int usbfs_show_options(struct seq_file *seq, struct vfsmount *mnt)
+{
+ if (devuid != 0)
+ seq_printf(seq, ",devuid=%u", devuid);
+ if (devgid != 0)
+ seq_printf(seq, ",devgid=%u", devgid);
+ if (devmode != USBFS_DEFAULT_DEVMODE)
+ seq_printf(seq, ",devmode=%o", devmode);
+ if (busuid != 0)
+ seq_printf(seq, ",busuid=%u", busuid);
+ if (busgid != 0)
+ seq_printf(seq, ",busgid=%u", busgid);
+ if (busmode != USBFS_DEFAULT_BUSMODE)
+ seq_printf(seq, ",busmode=%o", busmode);
+ if (listuid != 0)
+ seq_printf(seq, ",listuid=%u", listuid);
+ if (listgid != 0)
+ seq_printf(seq, ",listgid=%u", listgid);
+ if (listmode != USBFS_DEFAULT_LISTMODE)
+ seq_printf(seq, ",listmode=%o", listmode);
+
+ return 0;
+}
enum {
Opt_devuid, Opt_devgid, Opt_devmode,
@@ -93,9 +122,9 @@ static int parse_options(struct super_block *s, char *data)
devgid = 0;
busgid = 0;
listgid = 0;
- devmode = S_IWUSR | S_IRUGO;
- busmode = S_IXUGO | S_IRUGO;
- listmode = S_IRUGO;
+ devmode = USBFS_DEFAULT_DEVMODE;
+ busmode = USBFS_DEFAULT_BUSMODE;
+ listmode = USBFS_DEFAULT_LISTMODE;
while ((p = strsep(&data, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS];
@@ -418,6 +447,7 @@ static struct super_operations usbfs_ops = {
.statfs = simple_statfs,
.drop_inode = generic_delete_inode,
.remount_fs = remount,
+ .show_options = usbfs_show_options,
};
static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index eb4ac47612a..fefb92296e8 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -39,7 +39,7 @@ static void usb_api_blocking_completion(struct urb *urb)
* own interruptible routines.
*/
static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
-{
+{
struct api_context ctx;
unsigned long expire;
int retval;
@@ -74,9 +74,9 @@ out:
}
/*-------------------------------------------------------------------*/
-// returns status (negative) or length (positive)
+/* returns status (negative) or length (positive) */
static int usb_internal_control_msg(struct usb_device *usb_dev,
- unsigned int pipe,
+ unsigned int pipe,
struct usb_ctrlrequest *cmd,
void *data, int len, int timeout)
{
@@ -87,7 +87,7 @@ static int usb_internal_control_msg(struct usb_device *usb_dev,
urb = usb_alloc_urb(0, GFP_NOIO);
if (!urb)
return -ENOMEM;
-
+
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
len, usb_api_blocking_completion, NULL);
@@ -99,47 +99,51 @@ static int usb_internal_control_msg(struct usb_device *usb_dev,
}
/**
- * usb_control_msg - Builds a control urb, sends it off and waits for completion
- * @dev: pointer to the usb device to send the message to
- * @pipe: endpoint "pipe" to send the message to
- * @request: USB message request value
- * @requesttype: USB message request type value
- * @value: USB message value
- * @index: USB message index value
- * @data: pointer to the data to send
- * @size: length in bytes of the data to send
- * @timeout: time in msecs to wait for the message to complete before
- * timing out (if 0 the wait is forever)
- * Context: !in_interrupt ()
- *
- * This function sends a simple control message to a specified endpoint
- * and waits for the message to complete, or timeout.
- *
- * If successful, it returns the number of bytes transferred, otherwise a negative error number.
- *
- * Don't use this function from within an interrupt context, like a
- * bottom half handler. If you need an asynchronous message, or need to send
- * a message from within interrupt context, use usb_submit_urb()
- * If a thread in your driver uses this call, make sure your disconnect()
- * method can wait for it to complete. Since you don't have a handle on
- * the URB used, you can't cancel the request.
+ * usb_control_msg - Builds a control urb, sends it off and waits for completion
+ * @dev: pointer to the usb device to send the message to
+ * @pipe: endpoint "pipe" to send the message to
+ * @request: USB message request value
+ * @requesttype: USB message request type value
+ * @value: USB message value
+ * @index: USB message index value
+ * @data: pointer to the data to send
+ * @size: length in bytes of the data to send
+ * @timeout: time in msecs to wait for the message to complete before timing
+ * out (if 0 the wait is forever)
+ *
+ * Context: !in_interrupt ()
+ *
+ * This function sends a simple control message to a specified endpoint and
+ * waits for the message to complete, or timeout.
+ *
+ * If successful, it returns the number of bytes transferred, otherwise a
+ * negative error number.
+ *
+ * Don't use this function from within an interrupt context, like a bottom half
+ * handler. If you need an asynchronous message, or need to send a message
+ * from within interrupt context, use usb_submit_urb().
+ * If a thread in your driver uses this call, make sure your disconnect()
+ * method can wait for it to complete. Since you don't have a handle on the
+ * URB used, you can't cancel the request.
*/
-int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
- __u16 value, __u16 index, void *data, __u16 size, int timeout)
+int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
+ __u8 requesttype, __u16 value, __u16 index, void *data,
+ __u16 size, int timeout)
{
- struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
+ struct usb_ctrlrequest *dr;
int ret;
-
+
+ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
if (!dr)
return -ENOMEM;
- dr->bRequestType= requesttype;
+ dr->bRequestType = requesttype;
dr->bRequest = request;
dr->wValue = cpu_to_le16p(&value);
dr->wIndex = cpu_to_le16p(&index);
dr->wLength = cpu_to_le16p(&size);
- //dbg("usb_control_msg");
+ /* dbg("usb_control_msg"); */
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
@@ -147,7 +151,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u
return ret;
}
-
+EXPORT_SYMBOL_GPL(usb_control_msg);
/**
* usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion
@@ -155,9 +159,11 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u
* @pipe: endpoint "pipe" to send the message to
* @data: pointer to the data to send
* @len: length in bytes of the data to send
- * @actual_length: pointer to a location to put the actual length transferred in bytes
+ * @actual_length: pointer to a location to put the actual length transferred
+ * in bytes
* @timeout: time in msecs to wait for the message to complete before
* timing out (if 0 the wait is forever)
+ *
* Context: !in_interrupt ()
*
* This function sends a simple interrupt message to a specified endpoint and
@@ -181,38 +187,38 @@ int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
EXPORT_SYMBOL_GPL(usb_interrupt_msg);
/**
- * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion
- * @usb_dev: pointer to the usb device to send the message to
- * @pipe: endpoint "pipe" to send the message to
- * @data: pointer to the data to send
- * @len: length in bytes of the data to send
- * @actual_length: pointer to a location to put the actual length transferred in bytes
- * @timeout: time in msecs to wait for the message to complete before
- * timing out (if 0 the wait is forever)
- * Context: !in_interrupt ()
- *
- * This function sends a simple bulk message to a specified endpoint
- * and waits for the message to complete, or timeout.
- *
- * If successful, it returns 0, otherwise a negative error number.
- * The number of actual bytes transferred will be stored in the
- * actual_length paramater.
- *
- * Don't use this function from within an interrupt context, like a
- * bottom half handler. If you need an asynchronous message, or need to
- * send a message from within interrupt context, use usb_submit_urb()
- * If a thread in your driver uses this call, make sure your disconnect()
- * method can wait for it to complete. Since you don't have a handle on
- * the URB used, you can't cancel the request.
- *
- * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT
- * ioctl, users are forced to abuse this routine by using it to submit
- * URBs for interrupt endpoints. We will take the liberty of creating
- * an interrupt URB (with the default interval) if the target is an
- * interrupt endpoint.
+ * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion
+ * @usb_dev: pointer to the usb device to send the message to
+ * @pipe: endpoint "pipe" to send the message to
+ * @data: pointer to the data to send
+ * @len: length in bytes of the data to send
+ * @actual_length: pointer to a location to put the actual length transferred
+ * in bytes
+ * @timeout: time in msecs to wait for the message to complete before
+ * timing out (if 0 the wait is forever)
+ *
+ * Context: !in_interrupt ()
+ *
+ * This function sends a simple bulk message to a specified endpoint
+ * and waits for the message to complete, or timeout.
+ *
+ * If successful, it returns 0, otherwise a negative error number. The number
+ * of actual bytes transferred will be stored in the actual_length paramater.
+ *
+ * Don't use this function from within an interrupt context, like a bottom half
+ * handler. If you need an asynchronous message, or need to send a message
+ * from within interrupt context, use usb_submit_urb() If a thread in your
+ * driver uses this call, make sure your disconnect() method can wait for it to
+ * complete. Since you don't have a handle on the URB used, you can't cancel
+ * the request.
+ *
+ * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT ioctl,
+ * users are forced to abuse this routine by using it to submit URBs for
+ * interrupt endpoints. We will take the liberty of creating an interrupt URB
+ * (with the default interval) if the target is an interrupt endpoint.
*/
-int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
- void *data, int len, int *actual_length, int timeout)
+int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
+ void *data, int len, int *actual_length, int timeout)
{
struct urb *urb;
struct usb_host_endpoint *ep;
@@ -238,29 +244,30 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
return usb_start_wait_urb(urb, timeout, actual_length);
}
+EXPORT_SYMBOL_GPL(usb_bulk_msg);
/*-------------------------------------------------------------------*/
-static void sg_clean (struct usb_sg_request *io)
+static void sg_clean(struct usb_sg_request *io)
{
if (io->urbs) {
while (io->entries--)
- usb_free_urb (io->urbs [io->entries]);
- kfree (io->urbs);
+ usb_free_urb(io->urbs [io->entries]);
+ kfree(io->urbs);
io->urbs = NULL;
}
if (io->dev->dev.dma_mask != NULL)
- usb_buffer_unmap_sg (io->dev, usb_pipein(io->pipe),
- io->sg, io->nents);
+ usb_buffer_unmap_sg(io->dev, usb_pipein(io->pipe),
+ io->sg, io->nents);
io->dev = NULL;
}
-static void sg_complete (struct urb *urb)
+static void sg_complete(struct urb *urb)
{
- struct usb_sg_request *io = urb->context;
+ struct usb_sg_request *io = urb->context;
int status = urb->status;
- spin_lock (&io->lock);
+ spin_lock(&io->lock);
/* In 2.5 we require hcds' endpoint queues not to progress after fault
* reports, until the completion callback (this!) returns. That lets
@@ -276,13 +283,13 @@ static void sg_complete (struct urb *urb)
&& (io->status != -ECONNRESET
|| status != -ECONNRESET)
&& urb->actual_length) {
- dev_err (io->dev->bus->controller,
+ dev_err(io->dev->bus->controller,
"dev %s ep%d%s scatterlist error %d/%d\n",
io->dev->devpath,
usb_endpoint_num(&urb->ep->desc),
usb_urb_dir_in(urb) ? "in" : "out",
status, io->status);
- // BUG ();
+ /* BUG (); */
}
if (io->status == 0 && status && status != -ECONNRESET) {
@@ -294,22 +301,22 @@ static void sg_complete (struct urb *urb)
* unlink pending urbs so they won't rx/tx bad data.
* careful: unlink can sometimes be synchronous...
*/
- spin_unlock (&io->lock);
+ spin_unlock(&io->lock);
for (i = 0, found = 0; i < io->entries; i++) {
if (!io->urbs [i] || !io->urbs [i]->dev)
continue;
if (found) {
- retval = usb_unlink_urb (io->urbs [i]);
+ retval = usb_unlink_urb(io->urbs [i]);
if (retval != -EINPROGRESS &&
retval != -ENODEV &&
retval != -EBUSY)
- dev_err (&io->dev->dev,
+ dev_err(&io->dev->dev,
"%s, unlink --> %d\n",
__FUNCTION__, retval);
} else if (urb == io->urbs [i])
found = 1;
}
- spin_lock (&io->lock);
+ spin_lock(&io->lock);
}
urb->dev = NULL;
@@ -317,9 +324,9 @@ static void sg_complete (struct urb *urb)
io->bytes += urb->actual_length;
io->count--;
if (!io->count)
- complete (&io->complete);
+ complete(&io->complete);
- spin_unlock (&io->lock);
+ spin_unlock(&io->lock);
}
@@ -348,28 +355,21 @@ static void sg_complete (struct urb *urb)
* The request may be canceled with usb_sg_cancel(), either before or after
* usb_sg_wait() is called.
*/
-int usb_sg_init (
- struct usb_sg_request *io,
- struct usb_device *dev,
- unsigned pipe,
- unsigned period,
- struct scatterlist *sg,
- int nents,
- size_t length,
- gfp_t mem_flags
-)
+int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
+ unsigned pipe, unsigned period, struct scatterlist *sg,
+ int nents, size_t length, gfp_t mem_flags)
{
- int i;
- int urb_flags;
- int dma;
+ int i;
+ int urb_flags;
+ int dma;
if (!io || !dev || !sg
- || usb_pipecontrol (pipe)
- || usb_pipeisoc (pipe)
+ || usb_pipecontrol(pipe)
+ || usb_pipeisoc(pipe)
|| nents <= 0)
return -EINVAL;
- spin_lock_init (&io->lock);
+ spin_lock_init(&io->lock);
io->dev = dev;
io->pipe = pipe;
io->sg = sg;
@@ -381,7 +381,7 @@ int usb_sg_init (
dma = (dev->dev.dma_mask != NULL);
if (dma)
io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe),
- sg, nents);
+ sg, nents);
else
io->entries = nents;
@@ -390,30 +390,30 @@ int usb_sg_init (
return io->entries;
io->count = io->entries;
- io->urbs = kmalloc (io->entries * sizeof *io->urbs, mem_flags);
+ io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags);
if (!io->urbs)
goto nomem;
urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;
- if (usb_pipein (pipe))
+ if (usb_pipein(pipe))
urb_flags |= URB_SHORT_NOT_OK;
for (i = 0; i < io->entries; i++) {
- unsigned len;
+ unsigned len;
- io->urbs [i] = usb_alloc_urb (0, mem_flags);
- if (!io->urbs [i]) {
+ io->urbs[i] = usb_alloc_urb(0, mem_flags);
+ if (!io->urbs[i]) {
io->entries = i;
goto nomem;
}
- io->urbs [i]->dev = NULL;
- io->urbs [i]->pipe = pipe;
- io->urbs [i]->interval = period;
- io->urbs [i]->transfer_flags = urb_flags;
+ io->urbs[i]->dev = NULL;
+ io->urbs[i]->pipe = pipe;
+ io->urbs[i]->interval = period;
+ io->urbs[i]->transfer_flags = urb_flags;
- io->urbs [i]->complete = sg_complete;
- io->urbs [i]->context = io;
+ io->urbs[i]->complete = sg_complete;
+ io->urbs[i]->context = io;
/*
* Some systems need to revert to PIO when DMA is temporarily
@@ -432,40 +432,40 @@ int usb_sg_init (
* to prevent stale pointers and to help spot bugs.
*/
if (dma) {
- io->urbs [i]->transfer_dma = sg_dma_address (sg + i);
- len = sg_dma_len (sg + i);
-#if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU)
+ io->urbs[i]->transfer_dma = sg_dma_address(sg + i);
+ len = sg_dma_len(sg + i);
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_GART_IOMMU)
io->urbs[i]->transfer_buffer = NULL;
#else
io->urbs[i]->transfer_buffer = sg_virt(&sg[i]);
#endif
} else {
/* hc may use _only_ transfer_buffer */
- io->urbs [i]->transfer_buffer = sg_virt(&sg[i]);
- len = sg [i].length;
+ io->urbs[i]->transfer_buffer = sg_virt(&sg[i]);
+ len = sg[i].length;
}
if (length) {
- len = min_t (unsigned, len, length);
+ len = min_t(unsigned, len, length);
length -= len;
if (length == 0)
io->entries = i + 1;
}
- io->urbs [i]->transfer_buffer_length = len;
+ io->urbs[i]->transfer_buffer_length = len;
}
- io->urbs [--i]->transfer_flags &= ~URB_NO_INTERRUPT;
+ io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT;
/* transaction state */
io->status = 0;
io->bytes = 0;
- init_completion (&io->complete);
+ init_completion(&io->complete);
return 0;
nomem:
- sg_clean (io);
+ sg_clean(io);
return -ENOMEM;
}
-
+EXPORT_SYMBOL_GPL(usb_sg_init);
/**
* usb_sg_wait - synchronously execute scatter/gather request
@@ -506,31 +506,32 @@ nomem:
* speed interrupt endpoints, which allow at most one packet per millisecond,
* of at most 8 or 64 bytes (respectively).
*/
-void usb_sg_wait (struct usb_sg_request *io)
+void usb_sg_wait(struct usb_sg_request *io)
{
- int i, entries = io->entries;
+ int i;
+ int entries = io->entries;
/* queue the urbs. */
- spin_lock_irq (&io->lock);
+ spin_lock_irq(&io->lock);
i = 0;
while (i < entries && !io->status) {
- int retval;
+ int retval;
- io->urbs [i]->dev = io->dev;
- retval = usb_submit_urb (io->urbs [i], GFP_ATOMIC);
+ io->urbs[i]->dev = io->dev;
+ retval = usb_submit_urb(io->urbs [i], GFP_ATOMIC);
/* after we submit, let completions or cancelations fire;
* we handshake using io->status.
*/
- spin_unlock_irq (&io->lock);
+ spin_unlock_irq(&io->lock);
switch (retval) {
/* maybe we retrying will recover */
- case -ENXIO: // hc didn't queue this one
+ case -ENXIO: /* hc didn't queue this one */
case -EAGAIN:
case -ENOMEM:
io->urbs[i]->dev = NULL;
retval = 0;
- yield ();
+ yield();
break;
/* no error? continue immediately.
@@ -541,34 +542,35 @@ void usb_sg_wait (struct usb_sg_request *io)
*/
case 0:
++i;
- cpu_relax ();
+ cpu_relax();
break;
/* fail any uncompleted urbs */
default:
- io->urbs [i]->dev = NULL;
- io->urbs [i]->status = retval;
- dev_dbg (&io->dev->dev, "%s, submit --> %d\n",
+ io->urbs[i]->dev = NULL;
+ io->urbs[i]->status = retval;
+ dev_dbg(&io->dev->dev, "%s, submit --> %d\n",
__FUNCTION__, retval);
- usb_sg_cancel (io);
+ usb_sg_cancel(io);
}
- spin_lock_irq (&io->lock);
+ spin_lock_irq(&io->lock);
if (retval && (io->status == 0 || io->status == -ECONNRESET))
io->status = retval;
}
io->count -= entries - i;
if (io->count == 0)
- complete (&io->complete);
- spin_unlock_irq (&io->lock);
+ complete(&io->complete);
+ spin_unlock_irq(&io->lock);
/* OK, yes, this could be packaged as non-blocking.
* So could the submit loop above ... but it's easier to
* solve neither problem than to solve both!
*/
- wait_for_completion (&io->complete);
+ wait_for_completion(&io->complete);
- sg_clean (io);
+ sg_clean(io);
}
+EXPORT_SYMBOL_GPL(usb_sg_wait);
/**
* usb_sg_cancel - stop scatter/gather i/o issued by usb_sg_wait()
@@ -578,32 +580,33 @@ void usb_sg_wait (struct usb_sg_request *io)
* It can also prevents one initialized by usb_sg_init() from starting,
* so that call just frees resources allocated to the request.
*/
-void usb_sg_cancel (struct usb_sg_request *io)
+void usb_sg_cancel(struct usb_sg_request *io)
{
- unsigned long flags;
+ unsigned long flags;
- spin_lock_irqsave (&io->lock, flags);
+ spin_lock_irqsave(&io->lock, flags);
/* shut everything down, if it didn't already */
if (!io->status) {
- int i;
+ int i;
io->status = -ECONNRESET;
- spin_unlock (&io->lock);
+ spin_unlock(&io->lock);
for (i = 0; i < io->entries; i++) {
- int retval;
+ int retval;
if (!io->urbs [i]->dev)
continue;
- retval = usb_unlink_urb (io->urbs [i]);
+ retval = usb_unlink_urb(io->urbs [i]);
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);
}
- spin_lock (&io->lock);
+ spin_lock(&io->lock);
}
- spin_unlock_irqrestore (&io->lock, flags);
+ spin_unlock_irqrestore(&io->lock, flags);
}
+EXPORT_SYMBOL_GPL(usb_sg_cancel);
/*-------------------------------------------------------------------*/
@@ -629,12 +632,13 @@ void usb_sg_cancel (struct usb_sg_request *io)
* Returns the number of bytes received on success, or else the status code
* returned by the underlying usb_control_msg() call.
*/
-int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
+int usb_get_descriptor(struct usb_device *dev, unsigned char type,
+ unsigned char index, void *buf, int size)
{
int i;
int result;
-
- memset(buf,0,size); // Make sure we parse really received data
+
+ memset(buf, 0, size); /* Make sure we parse really received data */
for (i = 0; i < 3; ++i) {
/* retry on length 0 or error; some devices are flakey */
@@ -652,6 +656,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
}
return result;
}
+EXPORT_SYMBOL_GPL(usb_get_descriptor);
/**
* usb_get_string - gets a string descriptor
@@ -708,7 +713,7 @@ static void usb_try_string_workarounds(unsigned char *buf, int *length)
}
static int usb_string_sub(struct usb_device *dev, unsigned int langid,
- unsigned int index, unsigned char *buf)
+ unsigned int index, unsigned char *buf)
{
int rc;
@@ -751,7 +756,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
* @buf: where to put the string
* @size: how big is "buf"?
* Context: !in_interrupt ()
- *
+ *
* This converts the UTF-16LE encoded strings returned by devices, from
* usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones
* that are more usable in most kernel contexts. Note that all characters
@@ -787,23 +792,23 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
if (!dev->have_langid) {
err = usb_string_sub(dev, 0, 0, tbuf);
if (err < 0) {
- dev_err (&dev->dev,
+ dev_err(&dev->dev,
"string descriptor 0 read error: %d\n",
err);
goto errout;
} else if (err < 4) {
- dev_err (&dev->dev, "string descriptor 0 too short\n");
+ dev_err(&dev->dev, "string descriptor 0 too short\n");
err = -EINVAL;
goto errout;
} else {
dev->have_langid = 1;
- dev->string_langid = tbuf[2] | (tbuf[3]<< 8);
- /* always use the first langid listed */
- dev_dbg (&dev->dev, "default language 0x%04x\n",
+ dev->string_langid = tbuf[2] | (tbuf[3] << 8);
+ /* always use the first langid listed */
+ dev_dbg(&dev->dev, "default language 0x%04x\n",
dev->string_langid);
}
}
-
+
err = usb_string_sub(dev, dev->string_langid, index, tbuf);
if (err < 0)
goto errout;
@@ -821,12 +826,15 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
err = idx;
if (tbuf[1] != USB_DT_STRING)
- dev_dbg(&dev->dev, "wrong descriptor type %02x for string %d (\"%s\")\n", tbuf[1], index, buf);
+ dev_dbg(&dev->dev,
+ "wrong descriptor type %02x for string %d (\"%s\")\n",
+ tbuf[1], index, buf);
errout:
kfree(tbuf);
return err;
}
+EXPORT_SYMBOL_GPL(usb_string);
/**
* usb_cache_string - read a string descriptor and cache it for later use
@@ -842,9 +850,15 @@ char *usb_cache_string(struct usb_device *udev, int index)
char *smallbuf = NULL;
int len;
- if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) {
- if ((len = usb_string(udev, index, buf, 256)) > 0) {
- if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL)
+ if (index <= 0)
+ return NULL;
+
+ buf = kmalloc(256, GFP_KERNEL);
+ if (buf) {
+ len = usb_string(udev, index, buf, 256);
+ if (len > 0) {
+ smallbuf = kmalloc(++len, GFP_KERNEL);
+ if (!smallbuf)
return buf;
memcpy(smallbuf, buf, len);
}
@@ -883,7 +897,7 @@ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
return -ENOMEM;
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
- if (ret >= 0)
+ if (ret >= 0)
memcpy(&dev->descriptor, desc, size);
kfree(desc);
return ret;
@@ -927,6 +941,7 @@ int usb_get_status(struct usb_device *dev, int type, int target, void *data)
kfree(status);
return ret;
}
+EXPORT_SYMBOL_GPL(usb_get_status);
/**
* usb_clear_halt - tells device to clear endpoint halt/stall condition
@@ -955,8 +970,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
{
int result;
int endp = usb_pipeendpoint(pipe);
-
- if (usb_pipein (pipe))
+
+ if (usb_pipein(pipe))
endp |= USB_DIR_IN;
/* we don't care if it wasn't halted first. in fact some devices
@@ -985,6 +1000,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
return 0;
}
+EXPORT_SYMBOL_GPL(usb_clear_halt);
/**
* usb_disable_endpoint -- Disable an endpoint by address
@@ -1038,7 +1054,7 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf)
}
}
-/*
+/**
* usb_disable_device - Disable all the endpoints for a USB device
* @dev: the device whose endpoints are being disabled
* @skip_ep0: 0 to disable endpoint 0, 1 to skip it.
@@ -1053,7 +1069,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
int i;
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __FUNCTION__,
- skip_ep0 ? "non-ep0" : "all");
+ skip_ep0 ? "non-ep0" : "all");
for (i = skip_ep0; i < 16; ++i) {
usb_disable_endpoint(dev, i);
usb_disable_endpoint(dev, i + USB_DIR_IN);
@@ -1071,17 +1087,17 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
interface = dev->actconfig->interface[i];
if (!device_is_registered(&interface->dev))
continue;
- dev_dbg (&dev->dev, "unregistering interface %s\n",
+ dev_dbg(&dev->dev, "unregistering interface %s\n",
interface->dev.bus_id);
usb_remove_sysfs_intf_files(interface);
- device_del (&interface->dev);
+ device_del(&interface->dev);
}
/* Now that the interfaces are unbound, nobody should
* try to access them.
*/
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
- put_device (&dev->actconfig->interface[i]->dev);
+ put_device(&dev->actconfig->interface[i]->dev);
dev->actconfig->interface[i] = NULL;
}
dev->actconfig = NULL;
@@ -1090,8 +1106,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
}
}
-
-/*
+/**
* usb_enable_endpoint - Enable an endpoint for USB communications
* @dev: the device whose interface is being enabled
* @ep: the endpoint
@@ -1116,7 +1131,7 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
ep->enabled = 1;
}
-/*
+/**
* usb_enable_interface - Enable all the endpoints for an interface
* @dev: the device whose interface is being enabled
* @intf: pointer to the interface descriptor
@@ -1172,7 +1187,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
struct usb_host_interface *alt;
int ret;
int manual = 0;
- int changed;
+ unsigned int epaddr;
+ unsigned int pipe;
if (dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
@@ -1212,8 +1228,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
*/
/* prevent submissions using previous endpoint settings */
- changed = (iface->cur_altsetting != alt);
- if (changed && device_is_registered(&iface->dev))
+ if (iface->cur_altsetting != alt && device_is_registered(&iface->dev))
usb_remove_sysfs_intf_files(iface);
usb_disable_interface(dev, iface);
@@ -1228,11 +1243,11 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
int i;
for (i = 0; i < alt->desc.bNumEndpoints; i++) {
- unsigned int epaddr =
- alt->endpoint[i].desc.bEndpointAddress;
- unsigned int pipe =
- __create_pipe(dev, USB_ENDPOINT_NUMBER_MASK & epaddr)
- | (usb_endpoint_out(epaddr) ? USB_DIR_OUT : USB_DIR_IN);
+ epaddr = alt->endpoint[i].desc.bEndpointAddress;
+ pipe = __create_pipe(dev,
+ USB_ENDPOINT_NUMBER_MASK & epaddr) |
+ (usb_endpoint_out(epaddr) ?
+ USB_DIR_OUT : USB_DIR_IN);
usb_clear_halt(dev, pipe);
}
@@ -1250,11 +1265,12 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
* (Likewise, EP0 never "halts" on well designed devices.)
*/
usb_enable_interface(dev, iface);
- if (changed && device_is_registered(&iface->dev))
+ if (device_is_registered(&iface->dev))
usb_create_sysfs_intf_files(iface);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_set_interface);
/**
* usb_reset_configuration - lightweight device reset
@@ -1330,6 +1346,7 @@ int usb_reset_configuration(struct usb_device *dev)
}
return 0;
}
+EXPORT_SYMBOL_GPL(usb_reset_configuration);
static void usb_release_interface(struct device *dev)
{
@@ -1348,34 +1365,10 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
struct usb_interface *intf;
struct usb_host_interface *alt;
- if (!dev)
- return -ENODEV;
-
- /* driver is often null here; dev_dbg() would oops */
- pr_debug ("usb %s: uevent\n", dev->bus_id);
-
intf = to_usb_interface(dev);
usb_dev = interface_to_usbdev(intf);
alt = intf->cur_altsetting;
-#ifdef CONFIG_USB_DEVICEFS
- if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
- usb_dev->bus->busnum, usb_dev->devnum))
- return -ENOMEM;
-#endif
-
- if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
- le16_to_cpu(usb_dev->descriptor.idVendor),
- le16_to_cpu(usb_dev->descriptor.idProduct),
- le16_to_cpu(usb_dev->descriptor.bcdDevice)))
- return -ENOMEM;
-
- if (add_uevent_var(env, "TYPE=%d/%d/%d",
- usb_dev->descriptor.bDeviceClass,
- usb_dev->descriptor.bDeviceSubClass,
- usb_dev->descriptor.bDeviceProtocol))
- return -ENOMEM;
-
if (add_uevent_var(env, "INTERFACE=%d/%d/%d",
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
@@ -1383,7 +1376,8 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
return -ENOMEM;
if (add_uevent_var(env,
- "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+ "MODALIAS=usb:"
+ "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice),
@@ -1413,8 +1407,8 @@ struct device_type usb_if_device_type = {
};
static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
- struct usb_host_config *config,
- u8 inum)
+ struct usb_host_config *config,
+ u8 inum)
{
struct usb_interface_assoc_descriptor *retval = NULL;
struct usb_interface_assoc_descriptor *intf_assoc;
@@ -1441,7 +1435,6 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
return retval;
}
-
/*
* usb_set_configuration - Makes a particular device setting be current
* @dev: the device whose configuration is being updated
@@ -1559,12 +1552,12 @@ free_interfaces:
* getting rid of old interfaces means unbinding their drivers.
*/
if (dev->state != USB_STATE_ADDRESS)
- usb_disable_device (dev, 1); // Skip ep0
-
- if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
- NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
+ usb_disable_device(dev, 1); /* Skip ep0 */
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
+ NULL, 0, USB_CTRL_SET_TIMEOUT);
+ if (ret < 0) {
/* All the old state is gone, so what else can we do?
* The device is probably useless now anyway.
*/
@@ -1611,11 +1604,11 @@ free_interfaces:
intf->dev.bus = &usb_bus_type;
intf->dev.type = &usb_if_device_type;
intf->dev.dma_mask = dev->dev.dma_mask;
- device_initialize (&intf->dev);
+ device_initialize(&intf->dev);
mark_quiesced(intf);
- sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
- dev->bus->busnum, dev->devpath,
- configuration, alt->desc.bInterfaceNumber);
+ sprintf(&intf->dev.bus_id[0], "%d-%s:%d.%d",
+ dev->bus->busnum, dev->devpath,
+ configuration, alt->desc.bInterfaceNumber);
}
kfree(new_interfaces);
@@ -1631,22 +1624,16 @@ free_interfaces:
for (i = 0; i < nintf; ++i) {
struct usb_interface *intf = cp->interface[i];
- dev_dbg (&dev->dev,
+ dev_dbg(&dev->dev,
"adding %s (config #%d, interface %d)\n",
intf->dev.bus_id, configuration,
intf->cur_altsetting->desc.bInterfaceNumber);
- ret = device_add (&intf->dev);
+ ret = device_add(&intf->dev);
if (ret != 0) {
dev_err(&dev->dev, "device_add(%s) --> %d\n",
intf->dev.bus_id, ret);
continue;
}
-
- /* The driver's probe method can call usb_set_interface(),
- * which would mean the interface's sysfs files are already
- * created. Just in case, we'll remove them first.
- */
- usb_remove_sysfs_intf_files(intf);
usb_create_sysfs_intf_files(intf);
}
@@ -1709,22 +1696,3 @@ int usb_driver_set_configuration(struct usb_device *udev, int config)
return 0;
}
EXPORT_SYMBOL_GPL(usb_driver_set_configuration);
-
-// synchronous request completion model
-EXPORT_SYMBOL(usb_control_msg);
-EXPORT_SYMBOL(usb_bulk_msg);
-
-EXPORT_SYMBOL(usb_sg_init);
-EXPORT_SYMBOL(usb_sg_cancel);
-EXPORT_SYMBOL(usb_sg_wait);
-
-// synchronous control message convenience routines
-EXPORT_SYMBOL(usb_get_descriptor);
-EXPORT_SYMBOL(usb_get_status);
-EXPORT_SYMBOL(usb_string);
-
-// synchronous calls that also maintain usbcore state
-EXPORT_SYMBOL(usb_clear_halt);
-EXPORT_SYMBOL(usb_reset_configuration);
-EXPORT_SYMBOL(usb_set_interface);
-
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c
index 6b36897ca15..7542dce3f5a 100644
--- a/drivers/usb/core/notify.c
+++ b/drivers/usb/core/notify.c
@@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(usb_register_notify);
* usb_unregister_notify - unregister a notifier callback
* @nb: pointer to the notifier block for the callback events.
*
- * usb_register_notifier() must have been previously called for this function
+ * usb_register_notify() must have been previously called for this function
* to work properly.
*/
void usb_unregister_notify(struct notifier_block *nb)
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
index 7f31a495a25..e8cdce571bb 100644
--- a/drivers/usb/core/otg_whitelist.h
+++ b/drivers/usb/core/otg_whitelist.h
@@ -14,7 +14,7 @@
* mostly use of USB_DEVICE() or USB_DEVICE_VER() entries..
*
* YOU _SHOULD_ CHANGE THIS LIST TO MATCH YOUR PRODUCT AND ITS TESTING!
- */
+ */
static struct usb_device_id whitelist_table [] = {
@@ -55,7 +55,7 @@ static int is_targeted(struct usb_device *dev)
return 1;
/* HNP test device is _never_ targeted (see OTG spec 6.6.6) */
- if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
le16_to_cpu(dev->descriptor.idProduct) == 0xbadd))
return 0;
@@ -86,7 +86,7 @@ static int is_targeted(struct usb_device *dev)
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
- (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
+ (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index b04afd06e50..a37ccbd1e00 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -72,7 +72,7 @@ set_bConfigurationValue(struct device *dev, struct device_attribute *attr,
return (value < 0) ? value : count;
}
-static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR,
show_bConfigurationValue, set_bConfigurationValue);
/* String fields */
@@ -249,6 +249,41 @@ static void remove_persist_attributes(struct device *dev)
#ifdef CONFIG_USB_SUSPEND
static ssize_t
+show_connected_duration(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_device *udev = to_usb_device(dev);
+
+ return sprintf(buf, "%u\n",
+ jiffies_to_msecs(jiffies - udev->connect_time));
+}
+
+static DEVICE_ATTR(connected_duration, S_IRUGO, show_connected_duration, NULL);
+
+/*
+ * If the device is resumed, the last time the device was suspended has
+ * been pre-subtracted from active_duration. We add the current time to
+ * get the duration that the device was actually active.
+ *
+ * If the device is suspended, the active_duration is up-to-date.
+ */
+static ssize_t
+show_active_duration(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ int duration;
+
+ if (udev->state != USB_STATE_SUSPENDED)
+ duration = jiffies_to_msecs(jiffies + udev->active_duration);
+ else
+ duration = jiffies_to_msecs(udev->active_duration);
+ return sprintf(buf, "%u\n", duration);
+}
+
+static DEVICE_ATTR(active_duration, S_IRUGO, show_active_duration, NULL);
+
+static ssize_t
show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev = to_usb_device(dev);
@@ -365,6 +400,14 @@ static int add_power_attributes(struct device *dev)
rc = sysfs_add_file_to_group(&dev->kobj,
&dev_attr_level.attr,
power_group);
+ if (rc == 0)
+ rc = sysfs_add_file_to_group(&dev->kobj,
+ &dev_attr_connected_duration.attr,
+ power_group);
+ if (rc == 0)
+ rc = sysfs_add_file_to_group(&dev->kobj,
+ &dev_attr_active_duration.attr,
+ power_group);
}
return rc;
}
@@ -372,6 +415,12 @@ static int add_power_attributes(struct device *dev)
static void remove_power_attributes(struct device *dev)
{
sysfs_remove_file_from_group(&dev->kobj,
+ &dev_attr_active_duration.attr,
+ power_group);
+ sysfs_remove_file_from_group(&dev->kobj,
+ &dev_attr_connected_duration.attr,
+ power_group);
+ sysfs_remove_file_from_group(&dev->kobj,
&dev_attr_level.attr,
power_group);
sysfs_remove_file_from_group(&dev->kobj,
@@ -601,21 +650,21 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)
/* Interface Accociation Descriptor fields */
#define usb_intf_assoc_attr(field, format_string) \
static ssize_t \
-show_iad_##field (struct device *dev, struct device_attribute *attr, \
+show_iad_##field(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
- struct usb_interface *intf = to_usb_interface (dev); \
+ struct usb_interface *intf = to_usb_interface(dev); \
\
- return sprintf (buf, format_string, \
- intf->intf_assoc->field); \
+ return sprintf(buf, format_string, \
+ intf->intf_assoc->field); \
} \
static DEVICE_ATTR(iad_##field, S_IRUGO, show_iad_##field, NULL);
-usb_intf_assoc_attr (bFirstInterface, "%02x\n")
-usb_intf_assoc_attr (bInterfaceCount, "%02d\n")
-usb_intf_assoc_attr (bFunctionClass, "%02x\n")
-usb_intf_assoc_attr (bFunctionSubClass, "%02x\n")
-usb_intf_assoc_attr (bFunctionProtocol, "%02x\n")
+usb_intf_assoc_attr(bFirstInterface, "%02x\n")
+usb_intf_assoc_attr(bInterfaceCount, "%02d\n")
+usb_intf_assoc_attr(bFunctionClass, "%02x\n")
+usb_intf_assoc_attr(bFunctionSubClass, "%02x\n")
+usb_intf_assoc_attr(bFunctionProtocol, "%02x\n")
/* Interface fields */
#define usb_intf_attr(field, format_string) \
@@ -735,6 +784,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
struct usb_host_interface *alt = intf->cur_altsetting;
int retval;
+ if (intf->sysfs_files_created)
+ return 0;
retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
if (retval)
return retval;
@@ -746,6 +797,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
if (intf->intf_assoc)
retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
usb_create_intf_ep_files(intf, udev);
+ intf->sysfs_files_created = 1;
return 0;
}
@@ -753,8 +805,11 @@ void usb_remove_sysfs_intf_files(struct usb_interface *intf)
{
struct device *dev = &intf->dev;
+ if (!intf->sysfs_files_created)
+ return;
usb_remove_intf_ep_files(intf);
device_remove_file(dev, &dev_attr_interface);
sysfs_remove_group(&dev->kobj, &intf_attr_grp);
sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp);
+ intf->sysfs_files_created = 0;
}
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index d05ead20081..9d7e63292c0 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -42,6 +42,7 @@ void usb_init_urb(struct urb *urb)
INIT_LIST_HEAD(&urb->anchor_list);
}
}
+EXPORT_SYMBOL_GPL(usb_init_urb);
/**
* usb_alloc_urb - creates a new urb for a USB driver to use
@@ -73,6 +74,7 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
usb_init_urb(urb);
return urb;
}
+EXPORT_SYMBOL_GPL(usb_alloc_urb);
/**
* usb_free_urb - frees the memory used by a urb when all users of it are finished
@@ -89,6 +91,7 @@ void usb_free_urb(struct urb *urb)
if (urb)
kref_put(&urb->kref, urb_destroy);
}
+EXPORT_SYMBOL_GPL(usb_free_urb);
/**
* usb_get_urb - increments the reference count of the urb
@@ -100,12 +103,13 @@ void usb_free_urb(struct urb *urb)
*
* A pointer to the urb with the incremented reference counter is returned.
*/
-struct urb * usb_get_urb(struct urb *urb)
+struct urb *usb_get_urb(struct urb *urb)
{
if (urb)
kref_get(&urb->kref);
return urb;
}
+EXPORT_SYMBOL_GPL(usb_get_urb);
/**
* usb_anchor_urb - anchors an URB while it is processed
@@ -172,7 +176,7 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
* describing that request to the USB subsystem. Request completion will
* be indicated later, asynchronously, by calling the completion handler.
* The three types of completion are success, error, and unlink
- * (a software-induced fault, also called "request cancellation").
+ * (a software-induced fault, also called "request cancellation").
*
* URBs may be submitted in interrupt context.
*
@@ -255,7 +259,7 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
* semaphores), or
* (c) current->state != TASK_RUNNING, this is the case only after
* you've changed it.
- *
+ *
* GFP_NOIO is used in the block io path and error handling of storage
* devices.
*
@@ -284,7 +288,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
- if (!(dev = urb->dev) || dev->state < USB_STATE_DEFAULT)
+ dev = urb->dev;
+ if ((!dev) || (dev->state < USB_STATE_DEFAULT))
return -ENODEV;
/* For now, get the endpoint from the pipe. Eventually drivers
@@ -347,11 +352,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
max *= mult;
}
- if (urb->number_of_packets <= 0)
+ if (urb->number_of_packets <= 0)
return -EINVAL;
for (n = 0; n < urb->number_of_packets; n++) {
len = urb->iso_frame_desc[n].length;
- if (len < 0 || len > max)
+ if (len < 0 || len > max)
return -EMSGSIZE;
urb->iso_frame_desc[n].status = -EXDEV;
urb->iso_frame_desc[n].actual_length = 0;
@@ -416,7 +421,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
/* too big? */
switch (dev->speed) {
case USB_SPEED_HIGH: /* units are microframes */
- // NOTE usb handles 2^15
+ /* NOTE usb handles 2^15 */
if (urb->interval > (1024 * 8))
urb->interval = 1024 * 8;
max = 1024 * 8;
@@ -426,12 +431,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (xfertype == USB_ENDPOINT_XFER_INT) {
if (urb->interval > 255)
return -EINVAL;
- // NOTE ohci only handles up to 32
+ /* NOTE ohci only handles up to 32 */
max = 128;
} else {
if (urb->interval > 1024)
urb->interval = 1024;
- // NOTE usb and ohci handle up to 2^15
+ /* NOTE usb and ohci handle up to 2^15 */
max = 1024;
}
break;
@@ -444,6 +449,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
return usb_hcd_submit_urb(urb, mem_flags);
}
+EXPORT_SYMBOL_GPL(usb_submit_urb);
/*-------------------------------------------------------------------*/
@@ -514,6 +520,7 @@ int usb_unlink_urb(struct urb *urb)
return -EIDRM;
return usb_hcd_unlink_urb(urb, -ECONNRESET);
}
+EXPORT_SYMBOL_GPL(usb_unlink_urb);
/**
* usb_kill_urb - cancel a transfer request and wait for it to finish
@@ -553,6 +560,7 @@ void usb_kill_urb(struct urb *urb)
--urb->reject;
mutex_unlock(&reject_mutex);
}
+EXPORT_SYMBOL_GPL(usb_kill_urb);
/**
* usb_kill_anchored_urbs - cancel transfer requests en masse
@@ -567,7 +575,8 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
spin_lock_irq(&anchor->lock);
while (!list_empty(&anchor->urb_list)) {
- victim = list_entry(anchor->urb_list.prev, struct urb, anchor_list);
+ victim = list_entry(anchor->urb_list.prev, struct urb,
+ anchor_list);
/* we must make sure the URB isn't freed before we kill it*/
usb_get_urb(victim);
spin_unlock_irq(&anchor->lock);
@@ -595,11 +604,3 @@ int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
msecs_to_jiffies(timeout));
}
EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout);
-
-EXPORT_SYMBOL(usb_init_urb);
-EXPORT_SYMBOL(usb_alloc_urb);
-EXPORT_SYMBOL(usb_free_urb);
-EXPORT_SYMBOL(usb_get_urb);
-EXPORT_SYMBOL(usb_submit_urb);
-EXPORT_SYMBOL(usb_unlink_urb);
-EXPORT_SYMBOL(usb_kill_urb);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 69aa68287d3..4e984060c98 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -36,7 +36,7 @@
#include <linux/workqueue.h>
#include <asm/io.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
@@ -96,6 +96,7 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev,
return NULL;
}
+EXPORT_SYMBOL_GPL(usb_ifnum_to_if);
/**
* usb_altnum_to_altsetting - get the altsetting structure with a given
@@ -115,8 +116,9 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev,
* Don't call this function unless you are bound to the intf interface
* or you have locked the device!
*/
-struct usb_host_interface *usb_altnum_to_altsetting(const struct usb_interface *intf,
- unsigned int altnum)
+struct usb_host_interface *usb_altnum_to_altsetting(
+ const struct usb_interface *intf,
+ unsigned int altnum)
{
int i;
@@ -126,13 +128,14 @@ struct usb_host_interface *usb_altnum_to_altsetting(const struct usb_interface *
}
return NULL;
}
+EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting);
struct find_interface_arg {
int minor;
struct usb_interface *interface;
};
-static int __find_interface(struct device * dev, void * data)
+static int __find_interface(struct device *dev, void *data)
{
struct find_interface_arg *arg = data;
struct usb_interface *intf;
@@ -154,7 +157,7 @@ static int __find_interface(struct device * dev, void * data)
* @drv: the driver whose current configuration is considered
* @minor: the minor number of the desired device
*
- * This walks the driver device list and returns a pointer to the interface
+ * This walks the driver device list and returns a pointer to the interface
* with the matching minor. Note, this only works for devices that share the
* USB major number.
*/
@@ -170,6 +173,7 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
__find_interface);
return argb.interface;
}
+EXPORT_SYMBOL_GPL(usb_find_interface);
/**
* usb_release_dev - free a usb device structure when all users of it are finished.
@@ -192,9 +196,34 @@ static void usb_release_dev(struct device *dev)
kfree(udev);
}
+#ifdef CONFIG_HOTPLUG
+static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct usb_device *usb_dev;
+
+ usb_dev = to_usb_device(dev);
+
+ if (add_uevent_var(env, "BUSNUM=%03d", usb_dev->bus->busnum))
+ return -ENOMEM;
+
+ if (add_uevent_var(env, "DEVNUM=%03d", usb_dev->devnum))
+ return -ENOMEM;
+
+ return 0;
+}
+
+#else
+
+static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_HOTPLUG */
+
struct device_type usb_device_type = {
.name = "usb_device",
.release = usb_release_dev,
+ .uevent = usb_dev_uevent,
};
#ifdef CONFIG_PM
@@ -205,7 +234,7 @@ static int ksuspend_usb_init(void)
* singlethreaded. Its job doesn't justify running on more
* than one CPU.
*/
- ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
+ ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd");
if (!ksuspend_usb_wq)
return -ENOMEM;
return 0;
@@ -244,8 +273,8 @@ static unsigned usb_bus_is_wusb(struct usb_bus *bus)
*
* This call may not be used in a non-sleeping context.
*/
-struct usb_device *
-usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
+struct usb_device *usb_alloc_dev(struct usb_device *parent,
+ struct usb_bus *bus, unsigned port1)
{
struct usb_device *dev;
struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self);
@@ -314,6 +343,8 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
mutex_init(&dev->pm_mutex);
INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
dev->autosuspend_delay = usb_autosuspend_delay * HZ;
+ dev->connect_time = jiffies;
+ dev->active_duration = -jiffies;
#endif
if (root_hub) /* Root hub always ok [and always wired] */
dev->authorized = 1;
@@ -342,6 +373,7 @@ struct usb_device *usb_get_dev(struct usb_device *dev)
get_device(&dev->dev);
return dev;
}
+EXPORT_SYMBOL_GPL(usb_get_dev);
/**
* usb_put_dev - release a use of the usb device structure
@@ -355,6 +387,7 @@ void usb_put_dev(struct usb_device *dev)
if (dev)
put_device(&dev->dev);
}
+EXPORT_SYMBOL_GPL(usb_put_dev);
/**
* usb_get_intf - increments the reference count of the usb interface structure
@@ -375,6 +408,7 @@ struct usb_interface *usb_get_intf(struct usb_interface *intf)
get_device(&intf->dev);
return intf;
}
+EXPORT_SYMBOL_GPL(usb_get_intf);
/**
* usb_put_intf - release a use of the usb interface structure
@@ -389,7 +423,7 @@ void usb_put_intf(struct usb_interface *intf)
if (intf)
put_device(&intf->dev);
}
-
+EXPORT_SYMBOL_GPL(usb_put_intf);
/* USB device locking
*
@@ -436,11 +470,11 @@ int usb_lock_device_for_reset(struct usb_device *udev,
return -EHOSTUNREACH;
if (iface) {
switch (iface->condition) {
- case USB_INTERFACE_BINDING:
+ case USB_INTERFACE_BINDING:
return 0;
- case USB_INTERFACE_BOUND:
+ case USB_INTERFACE_BOUND:
break;
- default:
+ default:
return -EINTR;
}
}
@@ -462,7 +496,7 @@ int usb_lock_device_for_reset(struct usb_device *udev,
}
return 1;
}
-
+EXPORT_SYMBOL_GPL(usb_lock_device_for_reset);
static struct usb_device *match_device(struct usb_device *dev,
u16 vendor_id, u16 product_id)
@@ -515,10 +549,10 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id)
struct list_head *buslist;
struct usb_bus *bus;
struct usb_device *dev = NULL;
-
+
mutex_lock(&usb_bus_list_lock);
for (buslist = usb_bus_list.next;
- buslist != &usb_bus_list;
+ buslist != &usb_bus_list;
buslist = buslist->next) {
bus = container_of(buslist, struct usb_bus, bus_list);
if (!bus->root_hub)
@@ -551,6 +585,7 @@ int usb_get_current_frame_number(struct usb_device *dev)
{
return usb_hcd_get_frame_number(dev);
}
+EXPORT_SYMBOL_GPL(usb_get_current_frame_number);
/*-------------------------------------------------------------------*/
/*
@@ -559,7 +594,7 @@ int usb_get_current_frame_number(struct usb_device *dev)
*/
int __usb_get_extra_descriptor(char *buffer, unsigned size,
- unsigned char type, void **ptr)
+ unsigned char type, void **ptr)
{
struct usb_descriptor_header *header;
@@ -570,7 +605,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
printk(KERN_ERR
"%s: bogus descriptor, type %d length %d\n",
usbcore_name,
- header->bDescriptorType,
+ header->bDescriptorType,
header->bLength);
return -1;
}
@@ -585,6 +620,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
}
return -1;
}
+EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
/**
* usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
@@ -608,17 +644,14 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
*
* When the buffer is no longer used, free it with usb_buffer_free().
*/
-void *usb_buffer_alloc(
- struct usb_device *dev,
- size_t size,
- gfp_t mem_flags,
- dma_addr_t *dma
-)
+void *usb_buffer_alloc(struct usb_device *dev, size_t size, gfp_t mem_flags,
+ dma_addr_t *dma)
{
if (!dev || !dev->bus)
return NULL;
return hcd_buffer_alloc(dev->bus, size, mem_flags, dma);
}
+EXPORT_SYMBOL_GPL(usb_buffer_alloc);
/**
* usb_buffer_free - free memory allocated with usb_buffer_alloc()
@@ -631,12 +664,8 @@ void *usb_buffer_alloc(
* been allocated using usb_buffer_alloc(), and the parameters must match
* those provided in that allocation request.
*/
-void usb_buffer_free(
- struct usb_device *dev,
- size_t size,
- void *addr,
- dma_addr_t dma
-)
+void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
+ dma_addr_t dma)
{
if (!dev || !dev->bus)
return;
@@ -644,6 +673,7 @@ void usb_buffer_free(
return;
hcd_buffer_free(dev->bus, size, addr, dma);
}
+EXPORT_SYMBOL_GPL(usb_buffer_free);
/**
* usb_buffer_map - create DMA mapping(s) for an urb
@@ -683,14 +713,15 @@ struct urb *usb_buffer_map(struct urb *urb)
urb->setup_packet,
sizeof(struct usb_ctrlrequest),
DMA_TO_DEVICE);
- // FIXME generic api broken like pci, can't report errors
- // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
+ /* FIXME generic api broken like pci, can't report errors */
+ /* if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; */
} else
urb->transfer_dma = ~0;
urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
| URB_NO_SETUP_DMA_MAP);
return urb;
}
+EXPORT_SYMBOL_GPL(usb_buffer_map);
#endif /* 0 */
/* XXX DISABLED, no users currently. If you wish to re-enable this
@@ -728,6 +759,7 @@ void usb_buffer_dmasync(struct urb *urb)
DMA_TO_DEVICE);
}
}
+EXPORT_SYMBOL_GPL(usb_buffer_dmasync);
#endif
/**
@@ -763,6 +795,7 @@ void usb_buffer_unmap(struct urb *urb)
urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP
| URB_NO_SETUP_DMA_MAP);
}
+EXPORT_SYMBOL_GPL(usb_buffer_unmap);
#endif /* 0 */
/**
@@ -803,10 +836,11 @@ int usb_buffer_map_sg(const struct usb_device *dev, int is_in,
|| !controller->dma_mask)
return -1;
- // FIXME generic api broken like pci, can't report errors
+ /* FIXME generic api broken like pci, can't report errors */
return dma_map_sg(controller, sg, nents,
is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
}
+EXPORT_SYMBOL_GPL(usb_buffer_map_sg);
/* XXX DISABLED, no users currently. If you wish to re-enable this
* XXX please determine whether the sync is to transfer ownership of
@@ -840,6 +874,7 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in,
dma_sync_sg(controller, sg, n_hw_ents,
is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
}
+EXPORT_SYMBOL_GPL(usb_buffer_dmasync_sg);
#endif
/**
@@ -866,6 +901,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in,
dma_unmap_sg(controller, sg, n_hw_ents,
is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
}
+EXPORT_SYMBOL_GPL(usb_buffer_unmap_sg);
/* format to disable USB on kernel command line is: nousb */
__module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444);
@@ -877,6 +913,7 @@ int usb_disabled(void)
{
return nousb;
}
+EXPORT_SYMBOL_GPL(usb_disabled);
/*
* Init
@@ -893,7 +930,7 @@ static int __init usb_init(void)
if (retval)
goto out;
retval = bus_register(&usb_bus_type);
- if (retval)
+ if (retval)
goto bus_register_failed;
retval = usb_host_init();
if (retval)
@@ -958,45 +995,4 @@ static void __exit usb_exit(void)
subsys_initcall(usb_init);
module_exit(usb_exit);
-
-/*
- * USB may be built into the kernel or be built as modules.
- * These symbols are exported for device (or host controller)
- * driver modules to use.
- */
-
-EXPORT_SYMBOL(usb_disabled);
-
-EXPORT_SYMBOL_GPL(usb_get_intf);
-EXPORT_SYMBOL_GPL(usb_put_intf);
-
-EXPORT_SYMBOL(usb_put_dev);
-EXPORT_SYMBOL(usb_get_dev);
-EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
-
-EXPORT_SYMBOL(usb_lock_device_for_reset);
-
-EXPORT_SYMBOL(usb_find_interface);
-EXPORT_SYMBOL(usb_ifnum_to_if);
-EXPORT_SYMBOL(usb_altnum_to_altsetting);
-
-EXPORT_SYMBOL(__usb_get_extra_descriptor);
-
-EXPORT_SYMBOL(usb_get_current_frame_number);
-
-EXPORT_SYMBOL(usb_buffer_alloc);
-EXPORT_SYMBOL(usb_buffer_free);
-
-#if 0
-EXPORT_SYMBOL(usb_buffer_map);
-EXPORT_SYMBOL(usb_buffer_dmasync);
-EXPORT_SYMBOL(usb_buffer_unmap);
-#endif
-
-EXPORT_SYMBOL(usb_buffer_map_sg);
-#if 0
-EXPORT_SYMBOL(usb_buffer_dmasync_sg);
-#endif
-EXPORT_SYMBOL(usb_buffer_unmap_sg);
-
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index c52626c51f7..2375194a9d4 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -1,22 +1,23 @@
/* Functions local to drivers/usb/core/ */
-extern int usb_create_sysfs_dev_files (struct usb_device *dev);
-extern void usb_remove_sysfs_dev_files (struct usb_device *dev);
-extern int usb_create_sysfs_intf_files (struct usb_interface *intf);
-extern void usb_remove_sysfs_intf_files (struct usb_interface *intf);
-extern int usb_create_ep_files(struct device *parent, struct usb_host_endpoint *endpoint,
+extern int usb_create_sysfs_dev_files(struct usb_device *dev);
+extern void usb_remove_sysfs_dev_files(struct usb_device *dev);
+extern int usb_create_sysfs_intf_files(struct usb_interface *intf);
+extern void usb_remove_sysfs_intf_files(struct usb_interface *intf);
+extern int usb_create_ep_files(struct device *parent,
+ struct usb_host_endpoint *endpoint,
struct usb_device *udev);
extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint);
extern void usb_enable_endpoint(struct usb_device *dev,
struct usb_host_endpoint *ep);
-extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr);
-extern void usb_disable_interface (struct usb_device *dev,
+extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr);
+extern void usb_disable_interface(struct usb_device *dev,
struct usb_interface *intf);
extern void usb_release_interface_cache(struct kref *ref);
-extern void usb_disable_device (struct usb_device *dev, int skip_ep0);
-extern int usb_deauthorize_device (struct usb_device *);
-extern int usb_authorize_device (struct usb_device *);
+extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
+extern int usb_deauthorize_device(struct usb_device *);
+extern int usb_authorize_device(struct usb_device *);
extern void usb_detect_quirks(struct usb_device *udev);
extern int usb_get_device_descriptor(struct usb_device *dev,