Commit c2a84d00 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/linus-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 6188af0c 27f49742
......@@ -113,6 +113,9 @@ APISOURCES := $(TOPDIR)/drivers/media/video/videodev.c \
$(TOPDIR)/drivers/net/wan/syncppp.c \
$(TOPDIR)/drivers/net/wan/z85230.c \
$(TOPDIR)/drivers/usb/core/hcd.c \
$(TOPDIR)/drivers/usb/core/urb.c \
$(TOPDIR)/drivers/usb/core/message.c \
$(TOPDIR)/drivers/usb/core/config.c \
$(TOPDIR)/drivers/usb/core/usb.c \
$(TOPDIR)/drivers/video/fbmem.c \
$(TOPDIR)/drivers/video/fbcmap.c \
......
......@@ -282,6 +282,9 @@
</sect1>
<sect1><title>USB Core APIs</title>
!Edrivers/usb/core/urb.c
!Edrivers/usb/core/config.c
!Edrivers/usb/core/message.c
!Edrivers/usb/core/usb.c
</sect1>
......
......@@ -2,9 +2,10 @@
# Makefile for USB Core files and filesystem
#
export-objs := usb.o hcd.o
export-objs := usb.o hcd.o urb.o message.o config.o
usbcore-objs := usb.o usb-debug.o hub.o hcd.o
usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o message.o \
config.o
ifeq ($(CONFIG_USB_DEVICEFS),y)
usbcore-objs += devio.o inode.o drivers.o devices.o
......
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size)
{
struct usb_descriptor_header *header;
unsigned char *begin;
int parsed = 0, len, numskipped;
header = (struct usb_descriptor_header *)buffer;
/* Everything should be fine being passed into here, but we sanity */
/* check JIC */
if (header->bLength > size) {
err("ran out of descriptors parsing");
return -1;
}
if (header->bDescriptorType != USB_DT_ENDPOINT) {
warn("unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X",
endpoint->bDescriptorType, USB_DT_ENDPOINT);
return parsed;
}
if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)
memcpy(endpoint, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
else
memcpy(endpoint, buffer, USB_DT_ENDPOINT_SIZE);
le16_to_cpus(&endpoint->wMaxPacketSize);
buffer += header->bLength;
size -= header->bLength;
parsed += header->bLength;
/* Skip over the rest of the Class Specific or Vendor Specific */
/* descriptors */
begin = buffer;
numskipped = 0;
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength < 2) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
dbg("skipping descriptor 0x%X",
header->bDescriptorType);
numskipped++;
buffer += header->bLength;
size -= header->bLength;
parsed += header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for drivers */
/* to later parse */
len = (int)(buffer - begin);
if (!len) {
endpoint->extra = NULL;
endpoint->extralen = 0;
return parsed;
}
endpoint->extra = kmalloc(len, GFP_KERNEL);
if (!endpoint->extra) {
err("couldn't allocate memory for endpoint extra descriptors");
endpoint->extralen = 0;
return parsed;
}
memcpy(endpoint->extra, begin, len);
endpoint->extralen = len;
return parsed;
}
static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size)
{
int i, len, numskipped, retval, parsed = 0;
struct usb_descriptor_header *header;
struct usb_interface_descriptor *ifp;
unsigned char *begin;
interface->act_altsetting = 0;
interface->num_altsetting = 0;
interface->max_altsetting = USB_ALTSETTINGALLOC;
interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
if (!interface->altsetting) {
err("couldn't kmalloc interface->altsetting");
return -1;
}
while (size > 0) {
if (interface->num_altsetting >= interface->max_altsetting) {
void *ptr;
int oldmas;
oldmas = interface->max_altsetting;
interface->max_altsetting += USB_ALTSETTINGALLOC;
if (interface->max_altsetting > USB_MAXALTSETTING) {
warn("too many alternate settings (max %d)",
USB_MAXALTSETTING);
return -1;
}
ptr = interface->altsetting;
interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
if (!interface->altsetting) {
err("couldn't kmalloc interface->altsetting");
interface->altsetting = ptr;
return -1;
}
memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas);
kfree(ptr);
}
ifp = interface->altsetting + interface->num_altsetting;
ifp->endpoint = NULL;
ifp->extra = NULL;
ifp->extralen = 0;
interface->num_altsetting++;
memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
/* Skip over the interface */
buffer += ifp->bLength;
parsed += ifp->bLength;
size -= ifp->bLength;
begin = buffer;
numskipped = 0;
/* Skip over any interface, class or vendor descriptors */
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength < 2) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
numskipped++;
buffer += header->bLength;
parsed += header->bLength;
size -= header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific interface descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for */
/* drivers to later parse */
len = (int)(buffer - begin);
if (len) {
ifp->extra = kmalloc(len, GFP_KERNEL);
if (!ifp->extra) {
err("couldn't allocate memory for interface extra descriptors");
ifp->extralen = 0;
return -1;
}
memcpy(ifp->extra, begin, len);
ifp->extralen = len;
}
/* Did we hit an unexpected descriptor? */
header = (struct usb_descriptor_header *)buffer;
if ((size >= sizeof(struct usb_descriptor_header)) &&
((header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE)))
return parsed;
if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
warn("too many endpoints");
return -1;
}
ifp->endpoint = (struct usb_endpoint_descriptor *)
kmalloc(ifp->bNumEndpoints *
sizeof(struct usb_endpoint_descriptor), GFP_KERNEL);
if (!ifp->endpoint) {
err("out of memory");
return -1;
}
memset(ifp->endpoint, 0, ifp->bNumEndpoints *
sizeof(struct usb_endpoint_descriptor));
for (i = 0; i < ifp->bNumEndpoints; i++) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength > size) {
err("ran out of descriptors parsing");
return -1;
}
retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
if (retval < 0)
return retval;
buffer += retval;
parsed += retval;
size -= retval;
}
/* We check to see if it's an alternate to this one */
ifp = (struct usb_interface_descriptor *)buffer;
if (size < USB_DT_INTERFACE_SIZE ||
ifp->bDescriptorType != USB_DT_INTERFACE ||
!ifp->bAlternateSetting)
return parsed;
}
return parsed;
}
int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer)
{
int i, retval, size;
struct usb_descriptor_header *header;
memcpy(config, buffer, USB_DT_CONFIG_SIZE);
le16_to_cpus(&config->wTotalLength);
size = config->wTotalLength;
if (config->bNumInterfaces > USB_MAXINTERFACES) {
warn("too many interfaces");
return -1;
}
config->interface = (struct usb_interface *)
kmalloc(config->bNumInterfaces *
sizeof(struct usb_interface), GFP_KERNEL);
dbg("kmalloc IF %p, numif %i", config->interface, config->bNumInterfaces);
if (!config->interface) {
err("out of memory");
return -1;
}
memset(config->interface, 0,
config->bNumInterfaces * sizeof(struct usb_interface));
buffer += config->bLength;
size -= config->bLength;
config->extra = NULL;
config->extralen = 0;
for (i = 0; i < config->bNumInterfaces; i++) {
int numskipped, len;
char *begin;
/* Skip over the rest of the Class Specific or Vendor */
/* Specific descriptors */
begin = buffer;
numskipped = 0;
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if ((header->bLength > size) || (header->bLength < 2)) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
dbg("skipping descriptor 0x%X", header->bDescriptorType);
numskipped++;
buffer += header->bLength;
size -= header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for */
/* drivers to later parse */
len = (int)(buffer - begin);
if (len) {
if (config->extralen) {
warn("extra config descriptor");
} else {
config->extra = kmalloc(len, GFP_KERNEL);
if (!config->extra) {
err("couldn't allocate memory for config extra descriptors");
config->extralen = 0;
return -1;
}
memcpy(config->extra, begin, len);
config->extralen = len;
}
}
retval = usb_parse_interface(config->interface + i, buffer, size);
if (retval < 0)
return retval;
buffer += retval;
size -= retval;
}
return size;
}
// 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, j, k;
if (!dev->config)
return;
if (dev->rawdescriptors) {
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
kfree(dev->rawdescriptors[i]);
kfree(dev->rawdescriptors);
}
for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
struct usb_config_descriptor *cf = &dev->config[c];
if (!cf->interface)
break;
for (i = 0; i < cf->bNumInterfaces; i++) {
struct usb_interface *ifp =
&cf->interface[i];
if (!ifp->altsetting)
break;
for (j = 0; j < ifp->num_altsetting; j++) {
struct usb_interface_descriptor *as =
&ifp->altsetting[j];
if(as->extra) {
kfree(as->extra);
}
if (!as->endpoint)
break;
for(k = 0; k < as->bNumEndpoints; k++) {
if(as->endpoint[k].extra) {
kfree(as->endpoint[k].extra);
}
}
kfree(as->endpoint);
}
kfree(ifp->altsetting);
}
kfree(cf->interface);
}
kfree(dev->config);
}
// hub-only!! ... and only in reset path, or usb_new_device()
// (used by real hubs and virtual root hubs)
int usb_get_configuration(struct usb_device *dev)
{
int result;
unsigned int cfgno, length;
unsigned char *buffer;
unsigned char *bigbuffer;
struct usb_config_descriptor *desc;
if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
warn("too many configurations");
return -EINVAL;
}
if (dev->descriptor.bNumConfigurations < 1) {
warn("not enough configurations");
return -EINVAL;
}
dev->config = (struct usb_config_descriptor *)
kmalloc(dev->descriptor.bNumConfigurations *
sizeof(struct usb_config_descriptor), GFP_KERNEL);
if (!dev->config) {
err("out of memory");
return -ENOMEM;
}
memset(dev->config, 0, dev->descriptor.bNumConfigurations *
sizeof(struct usb_config_descriptor));
dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
dev->descriptor.bNumConfigurations, GFP_KERNEL);
if (!dev->rawdescriptors) {
err("out of memory");
return -ENOMEM;
}
buffer = kmalloc(8, GFP_KERNEL);
if (!buffer) {
err("unable to allocate memory for configuration descriptors");
return -ENOMEM;
}
desc = (struct usb_config_descriptor *)buffer;
for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
/* We grab the first 8 bytes so we know how long the whole */
/* configuration is */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
if (result < 8) {
if (result < 0)
err("unable to get descriptor");
else {
err("config descriptor too short (expected %i, got %i)", 8, result);
result = -EINVAL;
}
goto err;
}
/* Get the full buffer */
length = le16_to_cpu(desc->wTotalLength);
bigbuffer = kmalloc(length, GFP_KERNEL);
if (!bigbuffer) {
err("unable to allocate memory for configuration descriptors");
result = -ENOMEM;
goto err;
}
/* Now that we know the length, get the whole thing */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);
if (result < 0) {
err("couldn't get all of config descriptors");
kfree(bigbuffer);
goto err;
}
if (result < length) {
err("config descriptor too short (expected %i, got %i)", length, result);
result = -EINVAL;
kfree(bigbuffer);
goto err;
}
dev->rawdescriptors[cfgno] = bigbuffer;
result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
if (result > 0)
dbg("descriptor data left");
else if (result < 0) {
result = -EINVAL;
goto err;
}
}
kfree(buffer);
return 0;
err:
kfree(buffer);
dev->descriptor.bNumConfigurations = cfgno;
return result;
}
/*
* message.c - synchronous message handling
*/
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <asm/byteorder.h>
struct usb_api_data {
wait_queue_head_t wqh;
int done;
};
static void usb_api_blocking_completion(struct urb *urb)
{
struct usb_api_data *awd = (struct usb_api_data *)urb->context;
awd->done = 1;
wmb();
wake_up(&awd->wqh);
}
// Starts urb and waits for completion or timeout
static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
{
DECLARE_WAITQUEUE(wait, current);
struct usb_api_data awd;
int status;
init_waitqueue_head(&awd.wqh);
awd.done = 0;
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&awd.wqh, &wait);
urb->context = &awd;
status = usb_submit_urb(urb, GFP_KERNEL);
if (status) {
// something went wrong
usb_free_urb(urb);
set_current_state(TASK_RUNNING);
remove_wait_queue(&awd.wqh, &wait);
return status;
}
while (timeout && !awd.done)
{
timeout = schedule_timeout(timeout);
set_current_state(TASK_UNINTERRUPTIBLE);
rmb();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&awd.wqh, &wait);
if (!timeout && !awd.done) {
if (urb->status != -EINPROGRESS) { /* No callback?!! */
printk(KERN_ERR "usb: raced timeout, "
"pipe 0x%x status %d time left %d\n",
urb->pipe, urb->status, timeout);
status = urb->status;
} else {
printk("usb_control/bulk_msg: timeout\n");
usb_unlink_urb(urb); // remove urb safely
status = -ETIMEDOUT;
}
} else
status = urb->status;
if (actual_length)
*actual_length = urb->actual_length;
usb_free_urb(urb);
return status;
}
/*-------------------------------------------------------------------*/
// returns status (negative) or length (positive)
int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
struct usb_ctrlrequest *cmd, void *data, int len, int timeout)
{
struct urb *urb;
int retv;
int length;
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return -ENOMEM;
FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len,
usb_api_blocking_completion, 0);
retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0)
return retv;
else
return length;
}
/**
* 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 jiffies 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()
*/
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_KERNEL);
int ret;
if (!dr)
return -ENOMEM;
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");
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
kfree(dr);
return ret;
}
/**
* 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 jiffies 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()
*/
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout)
{
struct urb *urb;
if (len < 0)
return -EINVAL;
urb=usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return -ENOMEM;
FILL_BULK_URB(urb, usb_dev, pipe, data, len,
usb_api_blocking_completion, 0);
return usb_start_wait_urb(urb,timeout,actual_length);
}
/**
* usb_get_descriptor - issues a generic GET_DESCRIPTOR request
* @dev: the device whose descriptor is being retrieved
* @type: the descriptor type (USB_DT_*)
* @index: the number of the descriptor
* @buf: where to put the descriptor
* @size: how big is "buf"?
* Context: !in_interrupt ()
*
* Gets a USB descriptor. Convenience functions exist to simplify
* getting some types of descriptors. Use
* usb_get_device_descriptor() for USB_DT_DEVICE,
* and usb_get_string() or usb_string() for USB_DT_STRING.
* Configuration descriptors (USB_DT_CONFIG) are part of the device
* structure, at least for the current configuration.
* In addition to a number of USB-standard descriptors, some
* devices also use class-specific or vendor-specific descriptors.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* 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 i = 5;
int result;
memset(buf,0,size); // Make sure we parse really received data
while (i--) {
/* retries if the returned length was 0; flakey device */
if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
HZ * USB_CTRL_GET_TIMEOUT)) > 0
|| result == -EPIPE)
break;
}
return result;
}
/**
* usb_get_string - gets a string descriptor
* @dev: the device whose string descriptor is being retrieved
* @langid: code for language chosen (from string descriptor zero)
* @index: the number of the descriptor
* @buf: where to put the string
* @size: how big is "buf"?
* Context: !in_interrupt ()
*
* Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character,
* in little-endian byte order).
* The usb_string() function will often be a convenient way to turn
* these strings into kernel-printable form.
*
* Strings may be referenced in device, configuration, interface, or other
* descriptors, and could also be used in vendor-specific ways.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns the number of bytes received on success, or else the status code
* returned by the underlying usb_control_msg() call.
*/
int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(USB_DT_STRING << 8) + index, langid, buf, size,
HZ * USB_CTRL_GET_TIMEOUT);
}
/**
* usb_get_device_descriptor - (re)reads the device descriptor
* @dev: the device whose device descriptor is being updated
* Context: !in_interrupt ()
*
* Updates the copy of the device descriptor stored in the device structure,
* which dedicates space for this purpose. Note that several fields are
* converted to the host CPU's byte order: the USB version (bcdUSB), and
* vendors product and version fields (idVendor, idProduct, and bcdDevice).
* That lets device drivers compare against non-byteswapped constants.
*
* There's normally no need to use this call, although some devices
* will change their descriptors after events like updating firmware.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns the number of bytes received on success, or else the status code
* returned by the underlying usb_control_msg() call.
*/
int usb_get_device_descriptor(struct usb_device *dev)
{
int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor,
sizeof(dev->descriptor));
if (ret >= 0) {
le16_to_cpus(&dev->descriptor.bcdUSB);
le16_to_cpus(&dev->descriptor.idVendor);
le16_to_cpus(&dev->descriptor.idProduct);
le16_to_cpus(&dev->descriptor.bcdDevice);
}
return ret;
}
/**
* usb_get_status - issues a GET_STATUS call
* @dev: the device whose status is being checked
* @type: USB_RECIP_*; for device, interface, or endpoint
* @target: zero (for device), else interface or endpoint number
* @data: pointer to two bytes of bitmap data
* Context: !in_interrupt ()
*
* Returns device, interface, or endpoint status. Normally only of
* interest to see if the device is self powered, or has enabled the
* remote wakeup facility; or whether a bulk or interrupt endpoint
* is halted ("stalled").
*
* Bits in these status bitmaps are set using the SET_FEATURE request,
* and cleared using the CLEAR_FEATURE request. The usb_clear_halt()
* function should be used to clear halt ("stall") status.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns the number of bytes received on success, or else the status code
* returned by the underlying usb_control_msg() call.
*/
int usb_get_status(struct usb_device *dev, int type, int target, void *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2,
HZ * USB_CTRL_GET_TIMEOUT);
}
// hub-only!! ... and only exported for reset/reinit path.
// otherwise used internally, for config/altsetting reconfig.
void usb_set_maxpacket(struct usb_device *dev)
{
int i, b;
for (i=0; i<dev->actconfig->bNumInterfaces; i++) {
struct usb_interface *ifp = dev->actconfig->interface + i;
struct usb_interface_descriptor *as = ifp->altsetting + ifp->act_altsetting;
struct usb_endpoint_descriptor *ep = as->endpoint;
int e;
for (e=0; e<as->bNumEndpoints; e++) {
b = ep[e].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
if ((ep[e].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_CONTROL) { /* Control => bidirectional */
dev->epmaxpacketout[b] = ep[e].wMaxPacketSize;
dev->epmaxpacketin [b] = ep[e].wMaxPacketSize;
}
else if (usb_endpoint_out(ep[e].bEndpointAddress)) {
if (ep[e].wMaxPacketSize > dev->epmaxpacketout[b])
dev->epmaxpacketout[b] = ep[e].wMaxPacketSize;
}
else {
if (ep[e].wMaxPacketSize > dev->epmaxpacketin [b])
dev->epmaxpacketin [b] = ep[e].wMaxPacketSize;
}
}
}
}
/**
* usb_clear_halt - tells device to clear endpoint halt/stall condition
* @dev: device whose endpoint is halted
* @pipe: endpoint "pipe" being cleared
* Context: !in_interrupt ()
*
* This is used to clear halt conditions for bulk and interrupt endpoints,
* as reported by URB completion status. Endpoints that are halted are
* sometimes referred to as being "stalled". Such endpoints are unable
* to transmit or receive data until the halt status is cleared. Any URBs
* queued queued for such an endpoint should normally be unlinked before
* clearing the halt condition.
*
* Note that control and isochronous endpoints don't halt, although control
* endpoints report "protocol stall" (for unsupported requests) using the
* same status code used to report a true stall.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns zero on success, or else the status code returned by the
* underlying usb_control_msg() call.
*/
int usb_clear_halt(struct usb_device *dev, int pipe)
{
int result;
__u16 status;
unsigned char *buffer;
int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
/*
if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp)))
return 0;
*/
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0,
HZ * USB_CTRL_SET_TIMEOUT);
/* don't clear if failed */
if (result < 0)
return result;
buffer = kmalloc(sizeof(status), GFP_KERNEL);
if (!buffer) {
err("unable to allocate memory for configuration descriptors");
return -ENOMEM;
}
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
// FIXME USB_CTRL_GET_TIMEOUT, yes? why not usb_get_status() ?
buffer, sizeof(status), HZ * USB_CTRL_SET_TIMEOUT);
memcpy(&status, buffer, sizeof(status));
kfree(buffer);
if (result < 0)
return result;
if (le16_to_cpu(status) & 1)
return -EPIPE; /* still halted */
usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
/* toggle is reset on clear */
usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
return 0;
}
/**
* usb_set_interface - Makes a particular alternate setting be current
* @dev: the device whose interface is being updated
* @interface: the interface being updated
* @alternate: the setting being chosen.
* Context: !in_interrupt ()
*
* This is used to enable data transfers on interfaces that may not
* be enabled by default. Not all devices support such configurability.
*
* Within any given configuration, each interface may have several
* alternative settings. These are often used to control levels of
* bandwidth consumption. For example, the default setting for a high
* speed interrupt endpoint may not send more than about 4KBytes per
* microframe, and isochronous endpoints may never be part of a an
* interface's default setting. To access such bandwidth, alternate
* interface setting must be made current.
*
* Note that in the Linux USB subsystem, bandwidth associated with
* an endpoint in a given alternate setting is not reserved until an
* is submitted that needs that bandwidth. Some other operating systems
* allocate bandwidth early, when a configuration is chosen.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns zero on success, or else the status code returned by the
* underlying usb_control_msg() call.
*/
int usb_set_interface(struct usb_device *dev, int interface, int alternate)
{
struct usb_interface *iface;
struct usb_interface_descriptor *iface_as;
int i, ret;
iface = usb_ifnum_to_if(dev, interface);
if (!iface) {
warn("selecting invalid interface %d", interface);
return -EINVAL;
}
/* 9.4.10 says devices don't need this, if the interface
only has one alternate setting */
if (iface->num_altsetting == 1) {
dbg("ignoring set_interface for dev %d, iface %d, alt %d",
dev->devnum, interface, alternate);
return 0;
}
if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,
interface, NULL, 0, HZ * 5)) < 0)
return ret;
iface->act_altsetting = alternate;
/* 9.1.1.5: reset toggles for all endpoints affected by this iface-as
*
* Note:
* Despite EP0 is always present in all interfaces/AS, the list of
* endpoints from the descriptor does not contain EP0. Due to its
* omnipresence one might expect EP0 being considered "affected" by
* any SetInterface request and hence assume toggles need to be reset.
* However, EP0 toggles are re-synced for every individual transfer
* during the SETUP stage - hence EP0 toggles are "don't care" here.
*/
iface_as = &iface->altsetting[alternate];
for (i = 0; i < iface_as->bNumEndpoints; i++) {
u8 ep = iface_as->endpoint[i].bEndpointAddress;
usb_settoggle(dev, ep&USB_ENDPOINT_NUMBER_MASK, usb_endpoint_out(ep), 0);
}
/* usb_set_maxpacket() sets the maxpacket size for all EP in all
* interfaces but it shouldn't do any harm here: we have changed
* the AS for the requested interface only, hence for unaffected
* interfaces it's just re-application of still-valid values.
*/
usb_set_maxpacket(dev);
return 0;
}
/**
* usb_set_configuration - Makes a particular device setting be current
* @dev: the device whose configuration is being updated
* @configuration: the configuration being chosen.
* Context: !in_interrupt ()
*
* This is used to enable non-default device modes. Not all devices
* support this kind of configurability. By default, configuration
* zero is selected after enumeration; many devices only have a single
* configuration.
*
* USB devices may support one or more configurations, which affect
* power consumption and the functionality available. For example,
* the default configuration is limited to using 100mA of bus power,
* so that when certain device functionality requires more power,
* and the device is bus powered, that functionality will be in some
* non-default device configuration. Other device modes may also be
* reflected as configuration options, such as whether two ISDN
* channels are presented as independent 64Kb/s interfaces or as one
* bonded 128Kb/s interface.
*
* Note that USB has an additional level of device configurability,
* associated with interfaces. That configurability is accessed using
* usb_set_interface().
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns zero on success, or else the status code returned by the
* underlying usb_control_msg() call.
*/
int usb_set_configuration(struct usb_device *dev, int configuration)
{
int i, ret;
struct usb_config_descriptor *cp = NULL;
for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
if (dev->config[i].bConfigurationValue == configuration) {
cp = &dev->config[i];
break;
}
}
if (!cp) {
warn("selecting invalid configuration %d", configuration);
return -EINVAL;
}
if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0)
return ret;
dev->actconfig = cp;
dev->toggle[0] = 0;
dev->toggle[1] = 0;
usb_set_maxpacket(dev);
return 0;
}
/**
* usb_string - returns ISO 8859-1 version of a string descriptor
* @dev: the device whose string descriptor is being retrieved
* @index: the number of the descriptor
* @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
* in the chosen descriptor that can't be encoded using ISO-8859-1
* are converted to the question mark ("?") character, and this function
* chooses strings in the first language supported by the device.
*
* The ASCII (or, redundantly, "US-ASCII") character set is the seven-bit
* subset of ISO 8859-1. ISO-8859-1 is the eight-bit subset of Unicode,
* and is appropriate for use many uses of English and several other
* Western European languages. (But it doesn't include the "Euro" symbol.)
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns length of the string (>= 0) or usb_control_msg status (< 0).
*/
int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
{
unsigned char *tbuf;
int err;
unsigned int u, idx;
if (size <= 0 || !buf || !index)
return -EINVAL;
buf[0] = 0;
tbuf = kmalloc(256, GFP_KERNEL);
if (!tbuf)
return -ENOMEM;
/* get langid for strings if it's not yet known */
if (!dev->have_langid) {
err = usb_get_string(dev, 0, 0, tbuf, 4);
if (err < 0) {
err("error getting string descriptor 0 (error=%d)", err);
goto errout;
} else if (tbuf[0] < 4) {
err("string descriptor 0 too short");
err = -EINVAL;
goto errout;
} else {
dev->have_langid = -1;
dev->string_langid = tbuf[2] | (tbuf[3]<< 8);
/* always use the first langid listed */
dbg("USB device number %d default language ID 0x%x",
dev->devnum, dev->string_langid);
}
}
/*
* Just ask for a maximum length string and then take the length
* that was returned.
*/
err = usb_get_string(dev, dev->string_langid, index, tbuf, 255);
if (err < 0)
goto errout;
size--; /* leave room for trailing NULL char in output buffer */
for (idx = 0, u = 2; u < err; u += 2) {
if (idx >= size)
break;
if (tbuf[u+1]) /* high byte */
buf[idx++] = '?'; /* non ISO-8859-1 character */
else
buf[idx++] = tbuf[u];
}
buf[idx] = 0;
err = idx;
errout:
kfree(tbuf);
return err;
}
// synchronous request completion model
EXPORT_SYMBOL(usb_control_msg);
EXPORT_SYMBOL(usb_bulk_msg);
// synchronous control message convenience routines
EXPORT_SYMBOL(usb_get_descriptor);
EXPORT_SYMBOL(usb_get_device_descriptor);
EXPORT_SYMBOL(usb_get_status);
EXPORT_SYMBOL(usb_get_string);
EXPORT_SYMBOL(usb_string);
EXPORT_SYMBOL(usb_clear_halt);
EXPORT_SYMBOL(usb_set_configuration);
EXPORT_SYMBOL(usb_set_interface);
#include <linux/config.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/init.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
#include "hcd.h"
/**
* usb_alloc_urb - creates a new urb for a USB driver to use
* @iso_packets: number of iso packets for this urb
* @mem_flags: the type of memory to allocate, see kmalloc() for a list of
* valid options for this.
*
* Creates an urb for the USB driver to use, initializes a few internal
* structures, incrementes the usage counter, and returns a pointer to it.
*
* If no memory is available, NULL is returned.
*
* If the driver want to use this urb for interrupt, control, or bulk
* endpoints, pass '0' as the number of iso packets.
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
struct urb *usb_alloc_urb(int iso_packets, int mem_flags)
{
struct urb *urb;
urb = (struct urb *)kmalloc(sizeof(struct urb) +
iso_packets * sizeof(struct usb_iso_packet_descriptor),
mem_flags);
if (!urb) {
err("alloc_urb: kmalloc failed");
return NULL;
}
memset(urb, 0, sizeof(*urb));
urb->count = (atomic_t)ATOMIC_INIT(1);
spin_lock_init(&urb->lock);
return urb;
}
/**
* usb_free_urb - frees the memory used by a urb when all users of it are finished
* @urb: pointer to the urb to free
*
* Must be called when a user of a urb is finished with it. When the last user
* of the urb calls this function, the memory of the urb is freed.
*
* Note: The transfer buffer associated with the urb is not freed, that must be
* done elsewhere.
*/
void usb_free_urb(struct urb *urb)
{
if (urb)
if (atomic_dec_and_test(&urb->count))
kfree(urb);
}
/**
* usb_get_urb - increments the reference count of the urb
* @urb: pointer to the urb to modify
*
* This must be called whenever a urb is transfered from a device driver to a
* host controller driver. This allows proper reference counting to happen
* for urbs.
*
* A pointer to the urb with the incremented reference counter is returned.
*/
struct urb * usb_get_urb(struct urb *urb)
{
if (urb) {
atomic_inc(&urb->count);
return urb;
} else
return NULL;
}
/*-------------------------------------------------------------------*/
/**
* usb_submit_urb - asynchronously issue a transfer request for an endpoint
* @urb: pointer to the urb describing the request
* @mem_flags: the type of memory to allocate, see kmalloc() for a list
* of valid options for this.
*
* This submits a transfer request, and transfers control of the URB
* describing that request to the USB subsystem. Request completion will
* indicated later, asynchronously, by calling the completion handler.
* This call may be issued in interrupt context.
*
* The caller must have correctly initialized the URB before submitting
* it. Functions such as usb_fill_bulk_urb() and usb_fill_control_urb() are
* available to ensure that most fields are correctly initialized, for
* the particular kind of transfer, although they will not initialize
* any transfer flags.
*
* Successful submissions return 0; otherwise this routine returns a
* negative error number. If the submission is successful, the complete
* fuction of the urb will be called when the USB host driver is
* finished with the urb (either a successful transmission, or some
* error case.)
*
* Unreserved Bandwidth Transfers:
*
* Bulk or control requests complete only once. When the completion
* function is called, control of the URB is returned to the device
* driver which issued the request. The completion handler may then
* immediately free or reuse that URB.
*
* Bulk URBs will be queued if the USB_QUEUE_BULK transfer flag is set
* in the URB. This can be used to maximize bandwidth utilization by
* letting the USB controller start work on the next URB without any
* delay to report completion (scheduling and processing an interrupt)
* and then submit that next request.
*
* For control endpoints, the synchronous usb_control_msg() call is
* often used (in non-interrupt context) instead of this call.
*
* Reserved Bandwidth Transfers:
*
* Periodic URBs (interrupt or isochronous) are completed repeatedly,
* until the original request is aborted. When the completion callback
* indicates the URB has been unlinked (with a special status code),
* control of that URB returns to the device driver. Otherwise, the
* completion handler does not control the URB, and should not change
* any of its fields.
*
* Note that isochronous URBs should be submitted in a "ring" data
* structure (using urb->next) to ensure that they are resubmitted
* appropriately.
*
* If the USB subsystem can't reserve sufficient bandwidth to perform
* the periodic request, and bandwidth reservation is being done for
* this controller, submitting such a periodic request will fail.
*
* Memory Flags:
*
* General rules for how to decide which mem_flags to use:
*
* Basically the rules are the same as for kmalloc. There are four
* different possible values; GFP_KERNEL, GFP_NOFS, GFP_NOIO and
* GFP_ATOMIC.
*
* GFP_NOFS is not ever used, as it has not been implemented yet.
*
* There are three situations you must use GFP_ATOMIC.
* a) you are inside a completion handler, an interrupt, bottom half,
* tasklet or timer.
* b) you are holding a spinlock or rwlock (does not apply to
* semaphores)
* 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.
*
* All other situations use GFP_KERNEL.
*
* Specfic rules for how to decide which mem_flags to use:
*
* - start_xmit, timeout, and receive methods of network drivers must
* use GFP_ATOMIC (spinlock)
* - queuecommand methods of scsi drivers must use GFP_ATOMIC (spinlock)
* - If you use a kernel thread with a network driver you must use
* GFP_NOIO, unless b) or c) apply
* - After you have done a down() you use GFP_KERNEL, unless b) or c)
* apply or your are in a storage driver's block io path
* - probe and disconnect use GFP_KERNEL unless b) or c) apply
* - Changing firmware on a running storage or net device uses
* GFP_NOIO, unless b) or c) apply
*
*/
int usb_submit_urb(struct urb *urb, int mem_flags)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) {
if (usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)) <= 0) {
err("%s: pipe %x has invalid size (<= 0)", __FUNCTION__, urb->pipe);
return -EMSGSIZE;
}
return urb->dev->bus->op->submit_urb(urb, mem_flags);
}
return -ENODEV;
}
/*-------------------------------------------------------------------*/
/**
* usb_unlink_urb - abort/cancel a transfer request for an endpoint
* @urb: pointer to urb describing a previously submitted request
*
* This routine cancels an in-progress request. The requests's
* completion handler will be called with a status code indicating
* that the request has been canceled, and that control of the URB
* has been returned to that device driver. This is the only way
* to stop an interrupt transfer, so long as the device is connected.
*
* When the USB_ASYNC_UNLINK transfer flag for the URB is clear, this
* request is synchronous. Success is indicated by returning zero,
* at which time the urb will have been unlinked,
* and the completion function will see status -ENOENT. Failure is
* indicated by any other return value. This mode may not be used
* when unlinking an urb from an interrupt context, such as a bottom
* half or a completion handler,
*
* When the USB_ASYNC_UNLINK transfer flag for the URB is set, this
* request is asynchronous. Success is indicated by returning -EINPROGRESS,
* at which time the urb will normally not have been unlinked,
* and the completion function will see status -ECONNRESET. Failure is
* indicated by any other return value.
*/
int usb_unlink_urb(struct urb *urb)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
return urb->dev->bus->op->unlink_urb(urb);
else
return -ENODEV;
}
// asynchronous request completion model
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);
......@@ -33,7 +33,6 @@
#include <linux/devfs_fs_kernel.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <asm/byteorder.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
......@@ -1014,401 +1013,6 @@ void usb_free_dev(struct usb_device *dev)
}
}
/**
* usb_alloc_urb - creates a new urb for a USB driver to use
* @iso_packets: number of iso packets for this urb
* @mem_flags: the type of memory to allocate, see kmalloc() for a list of
* valid options for this.
*
* Creates an urb for the USB driver to use, initializes a few internal
* structures, incrementes the usage counter, and returns a pointer to it.
*
* If no memory is available, NULL is returned.
*
* If the driver want to use this urb for interrupt, control, or bulk
* endpoints, pass '0' as the number of iso packets.
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
struct urb *usb_alloc_urb(int iso_packets, int mem_flags)
{
struct urb *urb;
urb = (struct urb *)kmalloc(sizeof(struct urb) +
iso_packets * sizeof(struct usb_iso_packet_descriptor),
mem_flags);
if (!urb) {
err("alloc_urb: kmalloc failed");
return NULL;
}
memset(urb, 0, sizeof(*urb));
urb->count = (atomic_t)ATOMIC_INIT(1);
spin_lock_init(&urb->lock);
return urb;
}
/**
* usb_free_urb - frees the memory used by a urb when all users of it are finished
* @urb: pointer to the urb to free
*
* Must be called when a user of a urb is finished with it. When the last user
* of the urb calls this function, the memory of the urb is freed.
*
* Note: The transfer buffer associated with the urb is not freed, that must be
* done elsewhere.
*/
void usb_free_urb(struct urb *urb)
{
if (urb)
if (atomic_dec_and_test(&urb->count))
kfree(urb);
}
/**
* usb_get_urb - increments the reference count of the urb
* @urb: pointer to the urb to modify
*
* This must be called whenever a urb is transfered from a device driver to a
* host controller driver. This allows proper reference counting to happen
* for urbs.
*
* A pointer to the urb with the incremented reference counter is returned.
*/
struct urb * usb_get_urb(struct urb *urb)
{
if (urb) {
atomic_inc(&urb->count);
return urb;
} else
return NULL;
}
/*-------------------------------------------------------------------*/
/**
* usb_submit_urb - asynchronously issue a transfer request for an endpoint
* @urb: pointer to the urb describing the request
* @mem_flags: the type of memory to allocate, see kmalloc() for a list
* of valid options for this.
*
* This submits a transfer request, and transfers control of the URB
* describing that request to the USB subsystem. Request completion will
* indicated later, asynchronously, by calling the completion handler.
* This call may be issued in interrupt context.
*
* The caller must have correctly initialized the URB before submitting
* it. Functions such as usb_fill_bulk_urb() and usb_fill_control_urb() are
* available to ensure that most fields are correctly initialized, for
* the particular kind of transfer, although they will not initialize
* any transfer flags.
*
* Successful submissions return 0; otherwise this routine returns a
* negative error number. If the submission is successful, the complete
* fuction of the urb will be called when the USB host driver is
* finished with the urb (either a successful transmission, or some
* error case.)
*
* Unreserved Bandwidth Transfers:
*
* Bulk or control requests complete only once. When the completion
* function is called, control of the URB is returned to the device
* driver which issued the request. The completion handler may then
* immediately free or reuse that URB.
*
* Bulk URBs will be queued if the USB_QUEUE_BULK transfer flag is set
* in the URB. This can be used to maximize bandwidth utilization by
* letting the USB controller start work on the next URB without any
* delay to report completion (scheduling and processing an interrupt)
* and then submit that next request.
*
* For control endpoints, the synchronous usb_control_msg() call is
* often used (in non-interrupt context) instead of this call.
*
* Reserved Bandwidth Transfers:
*
* Periodic URBs (interrupt or isochronous) are completed repeatedly,
* until the original request is aborted. When the completion callback
* indicates the URB has been unlinked (with a special status code),
* control of that URB returns to the device driver. Otherwise, the
* completion handler does not control the URB, and should not change
* any of its fields.
*
* Note that isochronous URBs should be submitted in a "ring" data
* structure (using urb->next) to ensure that they are resubmitted
* appropriately.
*
* If the USB subsystem can't reserve sufficient bandwidth to perform
* the periodic request, and bandwidth reservation is being done for
* this controller, submitting such a periodic request will fail.
*
* Memory Flags:
*
* General rules for how to decide which mem_flags to use:
*
* Basically the rules are the same as for kmalloc. There are four
* different possible values; GFP_KERNEL, GFP_NOFS, GFP_NOIO and
* GFP_ATOMIC.
*
* GFP_NOFS is not ever used, as it has not been implemented yet.
*
* There are three situations you must use GFP_ATOMIC.
* a) you are inside a completion handler, an interrupt, bottom half,
* tasklet or timer.
* b) you are holding a spinlock or rwlock (does not apply to
* semaphores)
* 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.
*
* All other situations use GFP_KERNEL.
*
* Specfic rules for how to decide which mem_flags to use:
*
* - start_xmit, timeout, and receive methods of network drivers must
* use GFP_ATOMIC (spinlock)
* - queuecommand methods of scsi drivers must use GFP_ATOMIC (spinlock)
* - If you use a kernel thread with a network driver you must use
* GFP_NOIO, unless b) or c) apply
* - After you have done a down() you use GFP_KERNEL, unless b) or c)
* apply or your are in a storage driver's block io path
* - probe and disconnect use GFP_KERNEL unless b) or c) apply
* - Changing firmware on a running storage or net device uses
* GFP_NOIO, unless b) or c) apply
*
*/
int usb_submit_urb(struct urb *urb, int mem_flags)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) {
if (usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)) <= 0) {
err("%s: pipe %x has invalid size (<= 0)", __FUNCTION__, urb->pipe);
return -EMSGSIZE;
}
return urb->dev->bus->op->submit_urb(urb, mem_flags);
}
return -ENODEV;
}
/*-------------------------------------------------------------------*/
/**
* usb_unlink_urb - abort/cancel a transfer request for an endpoint
* @urb: pointer to urb describing a previously submitted request
*
* This routine cancels an in-progress request. The requests's
* completion handler will be called with a status code indicating
* that the request has been canceled, and that control of the URB
* has been returned to that device driver. This is the only way
* to stop an interrupt transfer, so long as the device is connected.
*
* When the USB_ASYNC_UNLINK transfer flag for the URB is clear, this
* request is synchronous. Success is indicated by returning zero,
* at which time the urb will have been unlinked,
* and the completion function will see status -ENOENT. Failure is
* indicated by any other return value. This mode may not be used
* when unlinking an urb from an interrupt context, such as a bottom
* half or a completion handler,
*
* When the USB_ASYNC_UNLINK transfer flag for the URB is set, this
* request is asynchronous. Success is indicated by returning -EINPROGRESS,
* at which time the urb will normally not have been unlinked,
* and the completion function will see status -ECONNRESET. Failure is
* indicated by any other return value.
*/
int usb_unlink_urb(struct urb *urb)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
return urb->dev->bus->op->unlink_urb(urb);
else
return -ENODEV;
}
/*-------------------------------------------------------------------*
* SYNCHRONOUS CALLS *
*-------------------------------------------------------------------*/
struct usb_api_data {
wait_queue_head_t wqh;
int done;
};
static void usb_api_blocking_completion(struct urb *urb)
{
struct usb_api_data *awd = (struct usb_api_data *)urb->context;
awd->done = 1;
wmb();
wake_up(&awd->wqh);
}
// Starts urb and waits for completion or timeout
static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
{
DECLARE_WAITQUEUE(wait, current);
struct usb_api_data awd;
int status;
init_waitqueue_head(&awd.wqh);
awd.done = 0;
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&awd.wqh, &wait);
urb->context = &awd;
status = usb_submit_urb(urb, GFP_KERNEL);
if (status) {
// something went wrong
usb_free_urb(urb);
set_current_state(TASK_RUNNING);
remove_wait_queue(&awd.wqh, &wait);
return status;
}
while (timeout && !awd.done)
{
timeout = schedule_timeout(timeout);
set_current_state(TASK_UNINTERRUPTIBLE);
rmb();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&awd.wqh, &wait);
if (!timeout && !awd.done) {
if (urb->status != -EINPROGRESS) { /* No callback?!! */
printk(KERN_ERR "usb: raced timeout, "
"pipe 0x%x status %d time left %d\n",
urb->pipe, urb->status, timeout);
status = urb->status;
} else {
printk("usb_control/bulk_msg: timeout\n");
usb_unlink_urb(urb); // remove urb safely
status = -ETIMEDOUT;
}
} else
status = urb->status;
if (actual_length)
*actual_length = urb->actual_length;
usb_free_urb(urb);
return status;
}
/*-------------------------------------------------------------------*/
// returns status (negative) or length (positive)
int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
struct usb_ctrlrequest *cmd, void *data, int len, int timeout)
{
struct urb *urb;
int retv;
int length;
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return -ENOMEM;
FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len,
usb_api_blocking_completion, 0);
retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0)
return retv;
else
return length;
}
/**
* 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 jiffies 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()
*/
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_KERNEL);
int ret;
if (!dr)
return -ENOMEM;
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");
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
kfree(dr);
return ret;
}
/**
* 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 jiffies 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()
*/
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout)
{
struct urb *urb;
if (len < 0)
return -EINVAL;
urb=usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return -ENOMEM;
FILL_BULK_URB(urb, usb_dev, pipe, data, len,
usb_api_blocking_completion, 0);
return usb_start_wait_urb(urb,timeout,actual_length);
}
/**
* usb_get_current_frame_number - return current bus frame number
......@@ -1430,390 +1034,6 @@ int usb_get_current_frame_number(struct usb_device *dev)
/*-------------------------------------------------------------------*/
static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size)
{
struct usb_descriptor_header *header;
unsigned char *begin;
int parsed = 0, len, numskipped;
header = (struct usb_descriptor_header *)buffer;
/* Everything should be fine being passed into here, but we sanity */
/* check JIC */
if (header->bLength > size) {
err("ran out of descriptors parsing");
return -1;
}
if (header->bDescriptorType != USB_DT_ENDPOINT) {
warn("unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X",
endpoint->bDescriptorType, USB_DT_ENDPOINT);
return parsed;
}
if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)
memcpy(endpoint, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
else
memcpy(endpoint, buffer, USB_DT_ENDPOINT_SIZE);
le16_to_cpus(&endpoint->wMaxPacketSize);
buffer += header->bLength;
size -= header->bLength;
parsed += header->bLength;
/* Skip over the rest of the Class Specific or Vendor Specific */
/* descriptors */
begin = buffer;
numskipped = 0;
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength < 2) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
dbg("skipping descriptor 0x%X",
header->bDescriptorType);
numskipped++;
buffer += header->bLength;
size -= header->bLength;
parsed += header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for drivers */
/* to later parse */
len = (int)(buffer - begin);
if (!len) {
endpoint->extra = NULL;
endpoint->extralen = 0;
return parsed;
}
endpoint->extra = kmalloc(len, GFP_KERNEL);
if (!endpoint->extra) {
err("couldn't allocate memory for endpoint extra descriptors");
endpoint->extralen = 0;
return parsed;
}
memcpy(endpoint->extra, begin, len);
endpoint->extralen = len;
return parsed;
}
static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size)
{
int i, len, numskipped, retval, parsed = 0;
struct usb_descriptor_header *header;
struct usb_interface_descriptor *ifp;
unsigned char *begin;
interface->act_altsetting = 0;
interface->num_altsetting = 0;
interface->max_altsetting = USB_ALTSETTINGALLOC;
interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
if (!interface->altsetting) {
err("couldn't kmalloc interface->altsetting");
return -1;
}
while (size > 0) {
if (interface->num_altsetting >= interface->max_altsetting) {
void *ptr;
int oldmas;
oldmas = interface->max_altsetting;
interface->max_altsetting += USB_ALTSETTINGALLOC;
if (interface->max_altsetting > USB_MAXALTSETTING) {
warn("too many alternate settings (max %d)",
USB_MAXALTSETTING);
return -1;
}
ptr = interface->altsetting;
interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
if (!interface->altsetting) {
err("couldn't kmalloc interface->altsetting");
interface->altsetting = ptr;
return -1;
}
memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas);
kfree(ptr);
}
ifp = interface->altsetting + interface->num_altsetting;
ifp->endpoint = NULL;
ifp->extra = NULL;
ifp->extralen = 0;
interface->num_altsetting++;
memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
/* Skip over the interface */
buffer += ifp->bLength;
parsed += ifp->bLength;
size -= ifp->bLength;
begin = buffer;
numskipped = 0;
/* Skip over any interface, class or vendor descriptors */
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength < 2) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
numskipped++;
buffer += header->bLength;
parsed += header->bLength;
size -= header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific interface descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for */
/* drivers to later parse */
len = (int)(buffer - begin);
if (len) {
ifp->extra = kmalloc(len, GFP_KERNEL);
if (!ifp->extra) {
err("couldn't allocate memory for interface extra descriptors");
ifp->extralen = 0;
return -1;
}
memcpy(ifp->extra, begin, len);
ifp->extralen = len;
}
/* Did we hit an unexpected descriptor? */
header = (struct usb_descriptor_header *)buffer;
if ((size >= sizeof(struct usb_descriptor_header)) &&
((header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE)))
return parsed;
if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
warn("too many endpoints");
return -1;
}
ifp->endpoint = (struct usb_endpoint_descriptor *)
kmalloc(ifp->bNumEndpoints *
sizeof(struct usb_endpoint_descriptor), GFP_KERNEL);
if (!ifp->endpoint) {
err("out of memory");
return -1;
}
memset(ifp->endpoint, 0, ifp->bNumEndpoints *
sizeof(struct usb_endpoint_descriptor));
for (i = 0; i < ifp->bNumEndpoints; i++) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength > size) {
err("ran out of descriptors parsing");
return -1;
}
retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
if (retval < 0)
return retval;
buffer += retval;
parsed += retval;
size -= retval;
}
/* We check to see if it's an alternate to this one */
ifp = (struct usb_interface_descriptor *)buffer;
if (size < USB_DT_INTERFACE_SIZE ||
ifp->bDescriptorType != USB_DT_INTERFACE ||
!ifp->bAlternateSetting)
return parsed;
}
return parsed;
}
int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer)
{
int i, retval, size;
struct usb_descriptor_header *header;
memcpy(config, buffer, USB_DT_CONFIG_SIZE);
le16_to_cpus(&config->wTotalLength);
size = config->wTotalLength;
if (config->bNumInterfaces > USB_MAXINTERFACES) {
warn("too many interfaces");
return -1;
}
config->interface = (struct usb_interface *)
kmalloc(config->bNumInterfaces *
sizeof(struct usb_interface), GFP_KERNEL);
dbg("kmalloc IF %p, numif %i", config->interface, config->bNumInterfaces);
if (!config->interface) {
err("out of memory");
return -1;
}
memset(config->interface, 0,
config->bNumInterfaces * sizeof(struct usb_interface));
buffer += config->bLength;
size -= config->bLength;
config->extra = NULL;
config->extralen = 0;
for (i = 0; i < config->bNumInterfaces; i++) {
int numskipped, len;
char *begin;
/* Skip over the rest of the Class Specific or Vendor */
/* Specific descriptors */
begin = buffer;
numskipped = 0;
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if ((header->bLength > size) || (header->bLength < 2)) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
dbg("skipping descriptor 0x%X", header->bDescriptorType);
numskipped++;
buffer += header->bLength;
size -= header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for */
/* drivers to later parse */
len = (int)(buffer - begin);
if (len) {
if (config->extralen) {
warn("extra config descriptor");
} else {
config->extra = kmalloc(len, GFP_KERNEL);
if (!config->extra) {
err("couldn't allocate memory for config extra descriptors");
config->extralen = 0;
return -1;
}
memcpy(config->extra, begin, len);
config->extralen = len;
}
}
retval = usb_parse_interface(config->interface + i, buffer, size);
if (retval < 0)
return retval;
buffer += retval;
size -= retval;
}
return size;
}
// 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, j, k;
if (!dev->config)
return;
if (dev->rawdescriptors) {
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
kfree(dev->rawdescriptors[i]);
kfree(dev->rawdescriptors);
}
for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
struct usb_config_descriptor *cf = &dev->config[c];
if (!cf->interface)
break;
for (i = 0; i < cf->bNumInterfaces; i++) {
struct usb_interface *ifp =
&cf->interface[i];
if (!ifp->altsetting)
break;
for (j = 0; j < ifp->num_altsetting; j++) {
struct usb_interface_descriptor *as =
&ifp->altsetting[j];
if(as->extra) {
kfree(as->extra);
}
if (!as->endpoint)
break;
for(k = 0; k < as->bNumEndpoints; k++) {
if(as->endpoint[k].extra) {
kfree(as->endpoint[k].extra);
}
}
kfree(as->endpoint);
}
kfree(ifp->altsetting);
}
kfree(cf->interface);
}
kfree(dev->config);
}
/* for returning string descriptors in UTF-16LE */
static int ascii2utf (char *ascii, __u8 *utf, int utfmax)
......@@ -2013,565 +1233,6 @@ int usb_set_address(struct usb_device *dev)
0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT);
}
/**
* usb_get_descriptor - issues a generic GET_DESCRIPTOR request
* @dev: the device whose descriptor is being retrieved
* @type: the descriptor type (USB_DT_*)
* @index: the number of the descriptor
* @buf: where to put the descriptor
* @size: how big is "buf"?
* Context: !in_interrupt ()
*
* Gets a USB descriptor. Convenience functions exist to simplify
* getting some types of descriptors. Use
* usb_get_device_descriptor() for USB_DT_DEVICE,
* and usb_get_string() or usb_string() for USB_DT_STRING.
* Configuration descriptors (USB_DT_CONFIG) are part of the device
* structure, at least for the current configuration.
* In addition to a number of USB-standard descriptors, some
* devices also use class-specific or vendor-specific descriptors.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* 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 i = 5;
int result;
memset(buf,0,size); // Make sure we parse really received data
while (i--) {
/* retries if the returned length was 0; flakey device */
if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
HZ * USB_CTRL_GET_TIMEOUT)) > 0
|| result == -EPIPE)
break;
}
return result;
}
/**
* usb_get_string - gets a string descriptor
* @dev: the device whose string descriptor is being retrieved
* @langid: code for language chosen (from string descriptor zero)
* @index: the number of the descriptor
* @buf: where to put the string
* @size: how big is "buf"?
* Context: !in_interrupt ()
*
* Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character,
* in little-endian byte order).
* The usb_string() function will often be a convenient way to turn
* these strings into kernel-printable form.
*
* Strings may be referenced in device, configuration, interface, or other
* descriptors, and could also be used in vendor-specific ways.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns the number of bytes received on success, or else the status code
* returned by the underlying usb_control_msg() call.
*/
int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(USB_DT_STRING << 8) + index, langid, buf, size,
HZ * USB_CTRL_GET_TIMEOUT);
}
/**
* usb_get_device_descriptor - (re)reads the device descriptor
* @dev: the device whose device descriptor is being updated
* Context: !in_interrupt ()
*
* Updates the copy of the device descriptor stored in the device structure,
* which dedicates space for this purpose. Note that several fields are
* converted to the host CPU's byte order: the USB version (bcdUSB), and
* vendors product and version fields (idVendor, idProduct, and bcdDevice).
* That lets device drivers compare against non-byteswapped constants.
*
* There's normally no need to use this call, although some devices
* will change their descriptors after events like updating firmware.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns the number of bytes received on success, or else the status code
* returned by the underlying usb_control_msg() call.
*/
int usb_get_device_descriptor(struct usb_device *dev)
{
int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor,
sizeof(dev->descriptor));
if (ret >= 0) {
le16_to_cpus(&dev->descriptor.bcdUSB);
le16_to_cpus(&dev->descriptor.idVendor);
le16_to_cpus(&dev->descriptor.idProduct);
le16_to_cpus(&dev->descriptor.bcdDevice);
}
return ret;
}
/**
* usb_get_status - issues a GET_STATUS call
* @dev: the device whose status is being checked
* @type: USB_RECIP_*; for device, interface, or endpoint
* @target: zero (for device), else interface or endpoint number
* @data: pointer to two bytes of bitmap data
* Context: !in_interrupt ()
*
* Returns device, interface, or endpoint status. Normally only of
* interest to see if the device is self powered, or has enabled the
* remote wakeup facility; or whether a bulk or interrupt endpoint
* is halted ("stalled").
*
* Bits in these status bitmaps are set using the SET_FEATURE request,
* and cleared using the CLEAR_FEATURE request. The usb_clear_halt()
* function should be used to clear halt ("stall") status.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns the number of bytes received on success, or else the status code
* returned by the underlying usb_control_msg() call.
*/
int usb_get_status(struct usb_device *dev, int type, int target, void *data)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2,
HZ * USB_CTRL_GET_TIMEOUT);
}
// hub-only!! ... and only exported for reset/reinit path.
// otherwise used internally, for config/altsetting reconfig.
void usb_set_maxpacket(struct usb_device *dev)
{
int i, b;
for (i=0; i<dev->actconfig->bNumInterfaces; i++) {
struct usb_interface *ifp = dev->actconfig->interface + i;
struct usb_interface_descriptor *as = ifp->altsetting + ifp->act_altsetting;
struct usb_endpoint_descriptor *ep = as->endpoint;
int e;
for (e=0; e<as->bNumEndpoints; e++) {
b = ep[e].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
if ((ep[e].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_CONTROL) { /* Control => bidirectional */
dev->epmaxpacketout[b] = ep[e].wMaxPacketSize;
dev->epmaxpacketin [b] = ep[e].wMaxPacketSize;
}
else if (usb_endpoint_out(ep[e].bEndpointAddress)) {
if (ep[e].wMaxPacketSize > dev->epmaxpacketout[b])
dev->epmaxpacketout[b] = ep[e].wMaxPacketSize;
}
else {
if (ep[e].wMaxPacketSize > dev->epmaxpacketin [b])
dev->epmaxpacketin [b] = ep[e].wMaxPacketSize;
}
}
}
}
/**
* usb_clear_halt - tells device to clear endpoint halt/stall condition
* @dev: device whose endpoint is halted
* @pipe: endpoint "pipe" being cleared
* Context: !in_interrupt ()
*
* This is used to clear halt conditions for bulk and interrupt endpoints,
* as reported by URB completion status. Endpoints that are halted are
* sometimes referred to as being "stalled". Such endpoints are unable
* to transmit or receive data until the halt status is cleared. Any URBs
* queued queued for such an endpoint should normally be unlinked before
* clearing the halt condition.
*
* Note that control and isochronous endpoints don't halt, although control
* endpoints report "protocol stall" (for unsupported requests) using the
* same status code used to report a true stall.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns zero on success, or else the status code returned by the
* underlying usb_control_msg() call.
*/
int usb_clear_halt(struct usb_device *dev, int pipe)
{
int result;
__u16 status;
unsigned char *buffer;
int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
/*
if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp)))
return 0;
*/
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0,
HZ * USB_CTRL_SET_TIMEOUT);
/* don't clear if failed */
if (result < 0)
return result;
buffer = kmalloc(sizeof(status), GFP_KERNEL);
if (!buffer) {
err("unable to allocate memory for configuration descriptors");
return -ENOMEM;
}
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
// FIXME USB_CTRL_GET_TIMEOUT, yes? why not usb_get_status() ?
buffer, sizeof(status), HZ * USB_CTRL_SET_TIMEOUT);
memcpy(&status, buffer, sizeof(status));
kfree(buffer);
if (result < 0)
return result;
if (le16_to_cpu(status) & 1)
return -EPIPE; /* still halted */
usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
/* toggle is reset on clear */
usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
return 0;
}
/**
* usb_set_interface - Makes a particular alternate setting be current
* @dev: the device whose interface is being updated
* @interface: the interface being updated
* @alternate: the setting being chosen.
* Context: !in_interrupt ()
*
* This is used to enable data transfers on interfaces that may not
* be enabled by default. Not all devices support such configurability.
*
* Within any given configuration, each interface may have several
* alternative settings. These are often used to control levels of
* bandwidth consumption. For example, the default setting for a high
* speed interrupt endpoint may not send more than about 4KBytes per
* microframe, and isochronous endpoints may never be part of a an
* interface's default setting. To access such bandwidth, alternate
* interface setting must be made current.
*
* Note that in the Linux USB subsystem, bandwidth associated with
* an endpoint in a given alternate setting is not reserved until an
* is submitted that needs that bandwidth. Some other operating systems
* allocate bandwidth early, when a configuration is chosen.
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns zero on success, or else the status code returned by the
* underlying usb_control_msg() call.
*/
int usb_set_interface(struct usb_device *dev, int interface, int alternate)
{
struct usb_interface *iface;
struct usb_interface_descriptor *iface_as;
int i, ret;
iface = usb_ifnum_to_if(dev, interface);
if (!iface) {
warn("selecting invalid interface %d", interface);
return -EINVAL;
}
/* 9.4.10 says devices don't need this, if the interface
only has one alternate setting */
if (iface->num_altsetting == 1) {
dbg("ignoring set_interface for dev %d, iface %d, alt %d",
dev->devnum, interface, alternate);
return 0;
}
if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,
interface, NULL, 0, HZ * 5)) < 0)
return ret;
iface->act_altsetting = alternate;
/* 9.1.1.5: reset toggles for all endpoints affected by this iface-as
*
* Note:
* Despite EP0 is always present in all interfaces/AS, the list of
* endpoints from the descriptor does not contain EP0. Due to its
* omnipresence one might expect EP0 being considered "affected" by
* any SetInterface request and hence assume toggles need to be reset.
* However, EP0 toggles are re-synced for every individual transfer
* during the SETUP stage - hence EP0 toggles are "don't care" here.
*/
iface_as = &iface->altsetting[alternate];
for (i = 0; i < iface_as->bNumEndpoints; i++) {
u8 ep = iface_as->endpoint[i].bEndpointAddress;
usb_settoggle(dev, ep&USB_ENDPOINT_NUMBER_MASK, usb_endpoint_out(ep), 0);
}
/* usb_set_maxpacket() sets the maxpacket size for all EP in all
* interfaces but it shouldn't do any harm here: we have changed
* the AS for the requested interface only, hence for unaffected
* interfaces it's just re-application of still-valid values.
*/
usb_set_maxpacket(dev);
return 0;
}
/**
* usb_set_configuration - Makes a particular device setting be current
* @dev: the device whose configuration is being updated
* @configuration: the configuration being chosen.
* Context: !in_interrupt ()
*
* This is used to enable non-default device modes. Not all devices
* support this kind of configurability. By default, configuration
* zero is selected after enumeration; many devices only have a single
* configuration.
*
* USB devices may support one or more configurations, which affect
* power consumption and the functionality available. For example,
* the default configuration is limited to using 100mA of bus power,
* so that when certain device functionality requires more power,
* and the device is bus powered, that functionality will be in some
* non-default device configuration. Other device modes may also be
* reflected as configuration options, such as whether two ISDN
* channels are presented as independent 64Kb/s interfaces or as one
* bonded 128Kb/s interface.
*
* Note that USB has an additional level of device configurability,
* associated with interfaces. That configurability is accessed using
* usb_set_interface().
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns zero on success, or else the status code returned by the
* underlying usb_control_msg() call.
*/
int usb_set_configuration(struct usb_device *dev, int configuration)
{
int i, ret;
struct usb_config_descriptor *cp = NULL;
for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
if (dev->config[i].bConfigurationValue == configuration) {
cp = &dev->config[i];
break;
}
}
if (!cp) {
warn("selecting invalid configuration %d", configuration);
return -EINVAL;
}
if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0)
return ret;
dev->actconfig = cp;
dev->toggle[0] = 0;
dev->toggle[1] = 0;
usb_set_maxpacket(dev);
return 0;
}
// hub-only!! ... and only in reset path, or usb_new_device()
// (used by real hubs and virtual root hubs)
int usb_get_configuration(struct usb_device *dev)
{
int result;
unsigned int cfgno, length;
unsigned char *buffer;
unsigned char *bigbuffer;
struct usb_config_descriptor *desc;
if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
warn("too many configurations");
return -EINVAL;
}
if (dev->descriptor.bNumConfigurations < 1) {
warn("not enough configurations");
return -EINVAL;
}
dev->config = (struct usb_config_descriptor *)
kmalloc(dev->descriptor.bNumConfigurations *
sizeof(struct usb_config_descriptor), GFP_KERNEL);
if (!dev->config) {
err("out of memory");
return -ENOMEM;
}
memset(dev->config, 0, dev->descriptor.bNumConfigurations *
sizeof(struct usb_config_descriptor));
dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
dev->descriptor.bNumConfigurations, GFP_KERNEL);
if (!dev->rawdescriptors) {
err("out of memory");
return -ENOMEM;
}
buffer = kmalloc(8, GFP_KERNEL);
if (!buffer) {
err("unable to allocate memory for configuration descriptors");
return -ENOMEM;
}
desc = (struct usb_config_descriptor *)buffer;
for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
/* We grab the first 8 bytes so we know how long the whole */
/* configuration is */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
if (result < 8) {
if (result < 0)
err("unable to get descriptor");
else {
err("config descriptor too short (expected %i, got %i)", 8, result);
result = -EINVAL;
}
goto err;
}
/* Get the full buffer */
length = le16_to_cpu(desc->wTotalLength);
bigbuffer = kmalloc(length, GFP_KERNEL);
if (!bigbuffer) {
err("unable to allocate memory for configuration descriptors");
result = -ENOMEM;
goto err;
}
/* Now that we know the length, get the whole thing */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);
if (result < 0) {
err("couldn't get all of config descriptors");
kfree(bigbuffer);
goto err;
}
if (result < length) {
err("config descriptor too short (expected %i, got %i)", length, result);
result = -EINVAL;
kfree(bigbuffer);
goto err;
}
dev->rawdescriptors[cfgno] = bigbuffer;
result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
if (result > 0)
dbg("descriptor data left");
else if (result < 0) {
result = -EINVAL;
goto err;
}
}
kfree(buffer);
return 0;
err:
kfree(buffer);
dev->descriptor.bNumConfigurations = cfgno;
return result;
}
/**
* usb_string - returns ISO 8859-1 version of a string descriptor
* @dev: the device whose string descriptor is being retrieved
* @index: the number of the descriptor
* @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
* in the chosen descriptor that can't be encoded using ISO-8859-1
* are converted to the question mark ("?") character, and this function
* chooses strings in the first language supported by the device.
*
* The ASCII (or, redundantly, "US-ASCII") character set is the seven-bit
* subset of ISO 8859-1. ISO-8859-1 is the eight-bit subset of Unicode,
* and is appropriate for use many uses of English and several other
* Western European languages. (But it doesn't include the "Euro" symbol.)
*
* This call is synchronous, and may not be used in an interrupt context.
*
* Returns length of the string (>= 0) or usb_control_msg status (< 0).
*/
int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
{
unsigned char *tbuf;
int err;
unsigned int u, idx;
if (size <= 0 || !buf || !index)
return -EINVAL;
buf[0] = 0;
tbuf = kmalloc(256, GFP_KERNEL);
if (!tbuf)
return -ENOMEM;
/* get langid for strings if it's not yet known */
if (!dev->have_langid) {
err = usb_get_string(dev, 0, 0, tbuf, 4);
if (err < 0) {
err("error getting string descriptor 0 (error=%d)", err);
goto errout;
} else if (tbuf[0] < 4) {
err("string descriptor 0 too short");
err = -EINVAL;
goto errout;
} else {
dev->have_langid = -1;
dev->string_langid = tbuf[2] | (tbuf[3]<< 8);
/* always use the first langid listed */
dbg("USB device number %d default language ID 0x%x",
dev->devnum, dev->string_langid);
}
}
/*
* Just ask for a maximum length string and then take the length
* that was returned.
*/
err = usb_get_string(dev, dev->string_langid, index, tbuf, 255);
if (err < 0)
goto errout;
size--; /* leave room for trailing NULL char in output buffer */
for (idx = 0, u = 2; u < err; u += 2) {
if (idx >= size)
break;
if (tbuf[u+1]) /* high byte */
buf[idx++] = '?'; /* non ISO-8859-1 character */
else
buf[idx++] = tbuf[u];
}
buf[idx] = 0;
err = idx;
errout:
kfree(tbuf);
return err;
}
/*
* By the time we get here, the device has gotten a new device ID
......@@ -2828,25 +1489,5 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor);
EXPORT_SYMBOL(usb_get_current_frame_number);
// asynchronous request completion model
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);
// synchronous request completion model
EXPORT_SYMBOL(usb_control_msg);
EXPORT_SYMBOL(usb_bulk_msg);
// synchronous control message convenience routines
EXPORT_SYMBOL(usb_get_descriptor);
EXPORT_SYMBOL(usb_get_device_descriptor);
EXPORT_SYMBOL(usb_get_status);
EXPORT_SYMBOL(usb_get_string);
EXPORT_SYMBOL(usb_string);
EXPORT_SYMBOL(usb_clear_halt);
EXPORT_SYMBOL(usb_set_configuration);
EXPORT_SYMBOL(usb_set_interface);
EXPORT_SYMBOL(usb_devfs_handle);
MODULE_LICENSE("GPL");
......@@ -144,11 +144,13 @@ static inline void qtd_copy_status (struct urb *urb, size_t length, u32 token)
usb_pipeendpoint (pipe),
usb_pipeout (pipe));
if (urb->dev->tt && !usb_pipeint (pipe)) {
#ifdef DEBUG
struct usb_device *tt = urb->dev->tt->hub;
dbg ("clear tt %s-%s p%d buffer, a%d ep%d",
tt->bus->bus_name, tt->devpath,
urb->dev->ttport, urb->dev->devnum,
usb_pipeendpoint (pipe));
#endif /* DEBUG */
usb_hub_tt_clear_buffer (urb->dev, pipe);
}
}
......
/* -*- linux-c -*- */
/*
* Driver for USB Scanners (linux-2.4.12)
* Driver for USB Scanners (linux-2.4.18)
*
* Copyright (C) 1999, 2000, 2001 David E. Nelson
* Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
*
* Portions may be copyright Brad Keryan and Michael Gee.
*
* David E. Nelson (dnelson@jump.net)
* Brian Beattie <beattie@beattie-home.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
......@@ -302,11 +302,24 @@
*
* 05/21/02 Currently maintained by Brian Beattie <beattie@beattie-home.net>
*
* 0.4.8 5/30/2002
* - Added Mustek BearPaw 2400 TA. Thanks to Sergey
* Vlasov <vsu@mivlgu.murom.ru>.
* - Added Mustek 1200UB Plus and Mustek BearPaw 1200 CU ID's. These use
* the Grandtech GT-6801 chip. Thanks to Henning
* Meier-Geinitz <henning@meier-geinitz.de>.
* - Increased Epson timeout to 60 secs as requested from
* Karl Heinz Kremer <khk@khk.net>.
* - Changed maintainership from David E. Nelson to Brian
* Beattie <beattie@beattie-home.net>.
*
* TODO
* - Remove the 2/3 endpoint limitation
* - Performance
* - Select/poll methods
* - More testing
* - Proper registry/assignment for LM9830 ioctl's
* - More general usage ioctl's
*
*
* Thanks to:
......@@ -322,6 +335,8 @@
* - All the folks who chimed in with reports and suggestions.
* - All the developers that are working on USB SANE backends or other
* applications to use USB scanners.
* - Thanks to Greg KH <greg@kroah.com> for setting up Brian Beattie
* to be the new USB Scanner maintainer.
*
* Performance:
*
......@@ -1035,7 +1050,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum,
switch (dev->descriptor.idVendor) { /* Scanner specific read timeout parameters */
case 0x04b8: /* Seiko/Epson */
scn->rd_nak_timeout = HZ * 40;
scn->rd_nak_timeout = HZ * 60;
break;
case 0x055f: /* Mustek */
case 0x0400: /* Another Mustek */
......
/*
* Driver for USB Scanners (linux-2.4.12)
* Driver for USB Scanners (linux-2.4.18)
*
* Copyright (C) 1999, 2000, 2001 David E. Nelson
* Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
*
* David E. Nelson (dnelson@jump.net)
* Brian Beattie <beattie@beattie-home.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
......@@ -51,7 +51,7 @@
static __s32 vendor=-1, product=-1, read_timeout=0;
MODULE_AUTHOR("David E. Nelson, dnelson@jump.net, http://www.jump.net/~dnelson");
MODULE_AUTHOR("Brian Beattie, beattie@beattie-home.net");
MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION);
MODULE_LICENSE("GPL");
......@@ -144,6 +144,8 @@ static struct usb_device_id scanner_device_ids [] = {
{ USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */
{ USB_DEVICE(0x055f, 0x0008) }, /* 1200 CU Plus */
{ USB_DEVICE(0x0ff5, 0x0010) }, /* BearPaw 1200F */
{ USB_DEVICE(0x055f, 0x0218) }, /* BearPaw 2400 TA */
{ USB_DEVICE(0x05d8, 0x4002) }, /* 1200 CU and 1200 UB Plus */
/* Plustek */
{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12 */
{ USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro UT24 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment