# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.612 -> 1.613 # drivers/usb/core/usb.c 1.61 -> 1.62 # drivers/usb/core/Makefile 1.5 -> 1.6 # (new) -> 1.2 drivers/usb/core/message.c # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/05/30 mochel@osdl.org 1.613 # USB: Move synchronous message passing code from usb.c to message.c # -------------------------------------------- # diff -Nru a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile --- a/drivers/usb/core/Makefile Fri May 31 16:47:05 2002 +++ b/drivers/usb/core/Makefile Fri May 31 16:47:05 2002 @@ -2,9 +2,9 @@ # Makefile for USB Core files and filesystem # -export-objs := usb.o hcd.o urb.o +export-objs := usb.o hcd.o urb.o message.o -usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o +usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o message.o ifeq ($(CONFIG_USB_DEVICEFS),y) usbcore-objs += devio.o inode.o drivers.o devices.o diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/usb/core/message.c Fri May 31 16:47:05 2002 @@ -0,0 +1,661 @@ +/* + * message.c - synchronous message handling + */ + +#include +#include +#include +#include +#include + +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; iactconfig->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; ebNumEndpoints; 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; idescriptor.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); + diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Fri May 31 16:47:05 2002 +++ b/drivers/usb/core/usb.c Fri May 31 16:47:05 2002 @@ -1015,189 +1015,6 @@ } -/*-------------------------------------------------------------------* - * 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 * @dev: the device whose bus is being queried @@ -1801,382 +1618,6 @@ 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; iactconfig->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; ebNumEndpoints; 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; idescriptor.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) @@ -2280,87 +1721,6 @@ 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 * and is in the default state. We need to identify the thing and @@ -2615,19 +1975,6 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor); EXPORT_SYMBOL(usb_get_current_frame_number); - -// 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");