162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * message.c - synchronous message handling 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Released under the GPLv2 only. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/acpi.h> 962306a36Sopenharmony_ci#include <linux/pci.h> /* for scatterlist macros */ 1062306a36Sopenharmony_ci#include <linux/usb.h> 1162306a36Sopenharmony_ci#include <linux/module.h> 1262306a36Sopenharmony_ci#include <linux/of.h> 1362306a36Sopenharmony_ci#include <linux/slab.h> 1462306a36Sopenharmony_ci#include <linux/mm.h> 1562306a36Sopenharmony_ci#include <linux/timer.h> 1662306a36Sopenharmony_ci#include <linux/ctype.h> 1762306a36Sopenharmony_ci#include <linux/nls.h> 1862306a36Sopenharmony_ci#include <linux/device.h> 1962306a36Sopenharmony_ci#include <linux/scatterlist.h> 2062306a36Sopenharmony_ci#include <linux/usb/cdc.h> 2162306a36Sopenharmony_ci#include <linux/usb/quirks.h> 2262306a36Sopenharmony_ci#include <linux/usb/hcd.h> /* for usbcore internals */ 2362306a36Sopenharmony_ci#include <linux/usb/of.h> 2462306a36Sopenharmony_ci#include <asm/byteorder.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include "usb.h" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic void cancel_async_set_config(struct usb_device *udev); 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistruct api_context { 3162306a36Sopenharmony_ci struct completion done; 3262306a36Sopenharmony_ci int status; 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic void usb_api_blocking_completion(struct urb *urb) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci struct api_context *ctx = urb->context; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci ctx->status = urb->status; 4062306a36Sopenharmony_ci complete(&ctx->done); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* 4562306a36Sopenharmony_ci * Starts urb and waits for completion or timeout. Note that this call 4662306a36Sopenharmony_ci * is NOT interruptible. Many device driver i/o requests should be 4762306a36Sopenharmony_ci * interruptible and therefore these drivers should implement their 4862306a36Sopenharmony_ci * own interruptible routines. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_cistatic int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci struct api_context ctx; 5362306a36Sopenharmony_ci unsigned long expire; 5462306a36Sopenharmony_ci int retval; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci init_completion(&ctx.done); 5762306a36Sopenharmony_ci urb->context = &ctx; 5862306a36Sopenharmony_ci urb->actual_length = 0; 5962306a36Sopenharmony_ci retval = usb_submit_urb(urb, GFP_NOIO); 6062306a36Sopenharmony_ci if (unlikely(retval)) 6162306a36Sopenharmony_ci goto out; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; 6462306a36Sopenharmony_ci if (!wait_for_completion_timeout(&ctx.done, expire)) { 6562306a36Sopenharmony_ci usb_kill_urb(urb); 6662306a36Sopenharmony_ci retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci dev_dbg(&urb->dev->dev, 6962306a36Sopenharmony_ci "%s timed out on ep%d%s len=%u/%u\n", 7062306a36Sopenharmony_ci current->comm, 7162306a36Sopenharmony_ci usb_endpoint_num(&urb->ep->desc), 7262306a36Sopenharmony_ci usb_urb_dir_in(urb) ? "in" : "out", 7362306a36Sopenharmony_ci urb->actual_length, 7462306a36Sopenharmony_ci urb->transfer_buffer_length); 7562306a36Sopenharmony_ci } else 7662306a36Sopenharmony_ci retval = ctx.status; 7762306a36Sopenharmony_ciout: 7862306a36Sopenharmony_ci if (actual_length) 7962306a36Sopenharmony_ci *actual_length = urb->actual_length; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci usb_free_urb(urb); 8262306a36Sopenharmony_ci return retval; 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/*-------------------------------------------------------------------*/ 8662306a36Sopenharmony_ci/* returns status (negative) or length (positive) */ 8762306a36Sopenharmony_cistatic int usb_internal_control_msg(struct usb_device *usb_dev, 8862306a36Sopenharmony_ci unsigned int pipe, 8962306a36Sopenharmony_ci struct usb_ctrlrequest *cmd, 9062306a36Sopenharmony_ci void *data, int len, int timeout) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci struct urb *urb; 9362306a36Sopenharmony_ci int retv; 9462306a36Sopenharmony_ci int length; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci urb = usb_alloc_urb(0, GFP_NOIO); 9762306a36Sopenharmony_ci if (!urb) 9862306a36Sopenharmony_ci return -ENOMEM; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, 10162306a36Sopenharmony_ci len, usb_api_blocking_completion, NULL); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci retv = usb_start_wait_urb(urb, timeout, &length); 10462306a36Sopenharmony_ci if (retv < 0) 10562306a36Sopenharmony_ci return retv; 10662306a36Sopenharmony_ci else 10762306a36Sopenharmony_ci return length; 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/** 11162306a36Sopenharmony_ci * usb_control_msg - Builds a control urb, sends it off and waits for completion 11262306a36Sopenharmony_ci * @dev: pointer to the usb device to send the message to 11362306a36Sopenharmony_ci * @pipe: endpoint "pipe" to send the message to 11462306a36Sopenharmony_ci * @request: USB message request value 11562306a36Sopenharmony_ci * @requesttype: USB message request type value 11662306a36Sopenharmony_ci * @value: USB message value 11762306a36Sopenharmony_ci * @index: USB message index value 11862306a36Sopenharmony_ci * @data: pointer to the data to send 11962306a36Sopenharmony_ci * @size: length in bytes of the data to send 12062306a36Sopenharmony_ci * @timeout: time in msecs to wait for the message to complete before timing 12162306a36Sopenharmony_ci * out (if 0 the wait is forever) 12262306a36Sopenharmony_ci * 12362306a36Sopenharmony_ci * Context: task context, might sleep. 12462306a36Sopenharmony_ci * 12562306a36Sopenharmony_ci * This function sends a simple control message to a specified endpoint and 12662306a36Sopenharmony_ci * waits for the message to complete, or timeout. 12762306a36Sopenharmony_ci * 12862306a36Sopenharmony_ci * Don't use this function from within an interrupt context. If you need 12962306a36Sopenharmony_ci * an asynchronous message, or need to send a message from within interrupt 13062306a36Sopenharmony_ci * context, use usb_submit_urb(). If a thread in your driver uses this call, 13162306a36Sopenharmony_ci * make sure your disconnect() method can wait for it to complete. Since you 13262306a36Sopenharmony_ci * don't have a handle on the URB used, you can't cancel the request. 13362306a36Sopenharmony_ci * 13462306a36Sopenharmony_ci * Return: If successful, the number of bytes transferred. Otherwise, a negative 13562306a36Sopenharmony_ci * error number. 13662306a36Sopenharmony_ci */ 13762306a36Sopenharmony_ciint usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, 13862306a36Sopenharmony_ci __u8 requesttype, __u16 value, __u16 index, void *data, 13962306a36Sopenharmony_ci __u16 size, int timeout) 14062306a36Sopenharmony_ci{ 14162306a36Sopenharmony_ci struct usb_ctrlrequest *dr; 14262306a36Sopenharmony_ci int ret; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); 14562306a36Sopenharmony_ci if (!dr) 14662306a36Sopenharmony_ci return -ENOMEM; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci dr->bRequestType = requesttype; 14962306a36Sopenharmony_ci dr->bRequest = request; 15062306a36Sopenharmony_ci dr->wValue = cpu_to_le16(value); 15162306a36Sopenharmony_ci dr->wIndex = cpu_to_le16(index); 15262306a36Sopenharmony_ci dr->wLength = cpu_to_le16(size); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci /* Linger a bit, prior to the next control message. */ 15762306a36Sopenharmony_ci if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) 15862306a36Sopenharmony_ci msleep(200); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci kfree(dr); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci return ret; 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_control_msg); 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci/** 16762306a36Sopenharmony_ci * usb_control_msg_send - Builds a control "send" message, sends it off and waits for completion 16862306a36Sopenharmony_ci * @dev: pointer to the usb device to send the message to 16962306a36Sopenharmony_ci * @endpoint: endpoint to send the message to 17062306a36Sopenharmony_ci * @request: USB message request value 17162306a36Sopenharmony_ci * @requesttype: USB message request type value 17262306a36Sopenharmony_ci * @value: USB message value 17362306a36Sopenharmony_ci * @index: USB message index value 17462306a36Sopenharmony_ci * @driver_data: pointer to the data to send 17562306a36Sopenharmony_ci * @size: length in bytes of the data to send 17662306a36Sopenharmony_ci * @timeout: time in msecs to wait for the message to complete before timing 17762306a36Sopenharmony_ci * out (if 0 the wait is forever) 17862306a36Sopenharmony_ci * @memflags: the flags for memory allocation for buffers 17962306a36Sopenharmony_ci * 18062306a36Sopenharmony_ci * Context: !in_interrupt () 18162306a36Sopenharmony_ci * 18262306a36Sopenharmony_ci * This function sends a control message to a specified endpoint that is not 18362306a36Sopenharmony_ci * expected to fill in a response (i.e. a "send message") and waits for the 18462306a36Sopenharmony_ci * message to complete, or timeout. 18562306a36Sopenharmony_ci * 18662306a36Sopenharmony_ci * Do not use this function from within an interrupt context. If you need 18762306a36Sopenharmony_ci * an asynchronous message, or need to send a message from within interrupt 18862306a36Sopenharmony_ci * context, use usb_submit_urb(). If a thread in your driver uses this call, 18962306a36Sopenharmony_ci * make sure your disconnect() method can wait for it to complete. Since you 19062306a36Sopenharmony_ci * don't have a handle on the URB used, you can't cancel the request. 19162306a36Sopenharmony_ci * 19262306a36Sopenharmony_ci * The data pointer can be made to a reference on the stack, or anywhere else, 19362306a36Sopenharmony_ci * as it will not be modified at all. This does not have the restriction that 19462306a36Sopenharmony_ci * usb_control_msg() has where the data pointer must be to dynamically allocated 19562306a36Sopenharmony_ci * memory (i.e. memory that can be successfully DMAed to a device). 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * Return: If successful, 0 is returned, Otherwise, a negative error number. 19862306a36Sopenharmony_ci */ 19962306a36Sopenharmony_ciint usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request, 20062306a36Sopenharmony_ci __u8 requesttype, __u16 value, __u16 index, 20162306a36Sopenharmony_ci const void *driver_data, __u16 size, int timeout, 20262306a36Sopenharmony_ci gfp_t memflags) 20362306a36Sopenharmony_ci{ 20462306a36Sopenharmony_ci unsigned int pipe = usb_sndctrlpipe(dev, endpoint); 20562306a36Sopenharmony_ci int ret; 20662306a36Sopenharmony_ci u8 *data = NULL; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci if (size) { 20962306a36Sopenharmony_ci data = kmemdup(driver_data, size, memflags); 21062306a36Sopenharmony_ci if (!data) 21162306a36Sopenharmony_ci return -ENOMEM; 21262306a36Sopenharmony_ci } 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci ret = usb_control_msg(dev, pipe, request, requesttype, value, index, 21562306a36Sopenharmony_ci data, size, timeout); 21662306a36Sopenharmony_ci kfree(data); 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci if (ret < 0) 21962306a36Sopenharmony_ci return ret; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci return 0; 22262306a36Sopenharmony_ci} 22362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_control_msg_send); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci/** 22662306a36Sopenharmony_ci * usb_control_msg_recv - Builds a control "receive" message, sends it off and waits for completion 22762306a36Sopenharmony_ci * @dev: pointer to the usb device to send the message to 22862306a36Sopenharmony_ci * @endpoint: endpoint to send the message to 22962306a36Sopenharmony_ci * @request: USB message request value 23062306a36Sopenharmony_ci * @requesttype: USB message request type value 23162306a36Sopenharmony_ci * @value: USB message value 23262306a36Sopenharmony_ci * @index: USB message index value 23362306a36Sopenharmony_ci * @driver_data: pointer to the data to be filled in by the message 23462306a36Sopenharmony_ci * @size: length in bytes of the data to be received 23562306a36Sopenharmony_ci * @timeout: time in msecs to wait for the message to complete before timing 23662306a36Sopenharmony_ci * out (if 0 the wait is forever) 23762306a36Sopenharmony_ci * @memflags: the flags for memory allocation for buffers 23862306a36Sopenharmony_ci * 23962306a36Sopenharmony_ci * Context: !in_interrupt () 24062306a36Sopenharmony_ci * 24162306a36Sopenharmony_ci * This function sends a control message to a specified endpoint that is 24262306a36Sopenharmony_ci * expected to fill in a response (i.e. a "receive message") and waits for the 24362306a36Sopenharmony_ci * message to complete, or timeout. 24462306a36Sopenharmony_ci * 24562306a36Sopenharmony_ci * Do not use this function from within an interrupt context. If you need 24662306a36Sopenharmony_ci * an asynchronous message, or need to send a message from within interrupt 24762306a36Sopenharmony_ci * context, use usb_submit_urb(). If a thread in your driver uses this call, 24862306a36Sopenharmony_ci * make sure your disconnect() method can wait for it to complete. Since you 24962306a36Sopenharmony_ci * don't have a handle on the URB used, you can't cancel the request. 25062306a36Sopenharmony_ci * 25162306a36Sopenharmony_ci * The data pointer can be made to a reference on the stack, or anywhere else 25262306a36Sopenharmony_ci * that can be successfully written to. This function does not have the 25362306a36Sopenharmony_ci * restriction that usb_control_msg() has where the data pointer must be to 25462306a36Sopenharmony_ci * dynamically allocated memory (i.e. memory that can be successfully DMAed to a 25562306a36Sopenharmony_ci * device). 25662306a36Sopenharmony_ci * 25762306a36Sopenharmony_ci * The "whole" message must be properly received from the device in order for 25862306a36Sopenharmony_ci * this function to be successful. If a device returns less than the expected 25962306a36Sopenharmony_ci * amount of data, then the function will fail. Do not use this for messages 26062306a36Sopenharmony_ci * where a variable amount of data might be returned. 26162306a36Sopenharmony_ci * 26262306a36Sopenharmony_ci * Return: If successful, 0 is returned, Otherwise, a negative error number. 26362306a36Sopenharmony_ci */ 26462306a36Sopenharmony_ciint usb_control_msg_recv(struct usb_device *dev, __u8 endpoint, __u8 request, 26562306a36Sopenharmony_ci __u8 requesttype, __u16 value, __u16 index, 26662306a36Sopenharmony_ci void *driver_data, __u16 size, int timeout, 26762306a36Sopenharmony_ci gfp_t memflags) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci unsigned int pipe = usb_rcvctrlpipe(dev, endpoint); 27062306a36Sopenharmony_ci int ret; 27162306a36Sopenharmony_ci u8 *data; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci if (!size || !driver_data) 27462306a36Sopenharmony_ci return -EINVAL; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci data = kmalloc(size, memflags); 27762306a36Sopenharmony_ci if (!data) 27862306a36Sopenharmony_ci return -ENOMEM; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci ret = usb_control_msg(dev, pipe, request, requesttype, value, index, 28162306a36Sopenharmony_ci data, size, timeout); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci if (ret < 0) 28462306a36Sopenharmony_ci goto exit; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci if (ret == size) { 28762306a36Sopenharmony_ci memcpy(driver_data, data, size); 28862306a36Sopenharmony_ci ret = 0; 28962306a36Sopenharmony_ci } else { 29062306a36Sopenharmony_ci ret = -EREMOTEIO; 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ciexit: 29462306a36Sopenharmony_ci kfree(data); 29562306a36Sopenharmony_ci return ret; 29662306a36Sopenharmony_ci} 29762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_control_msg_recv); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci/** 30062306a36Sopenharmony_ci * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion 30162306a36Sopenharmony_ci * @usb_dev: pointer to the usb device to send the message to 30262306a36Sopenharmony_ci * @pipe: endpoint "pipe" to send the message to 30362306a36Sopenharmony_ci * @data: pointer to the data to send 30462306a36Sopenharmony_ci * @len: length in bytes of the data to send 30562306a36Sopenharmony_ci * @actual_length: pointer to a location to put the actual length transferred 30662306a36Sopenharmony_ci * in bytes 30762306a36Sopenharmony_ci * @timeout: time in msecs to wait for the message to complete before 30862306a36Sopenharmony_ci * timing out (if 0 the wait is forever) 30962306a36Sopenharmony_ci * 31062306a36Sopenharmony_ci * Context: task context, might sleep. 31162306a36Sopenharmony_ci * 31262306a36Sopenharmony_ci * This function sends a simple interrupt message to a specified endpoint and 31362306a36Sopenharmony_ci * waits for the message to complete, or timeout. 31462306a36Sopenharmony_ci * 31562306a36Sopenharmony_ci * Don't use this function from within an interrupt context. If you need 31662306a36Sopenharmony_ci * an asynchronous message, or need to send a message from within interrupt 31762306a36Sopenharmony_ci * context, use usb_submit_urb() If a thread in your driver uses this call, 31862306a36Sopenharmony_ci * make sure your disconnect() method can wait for it to complete. Since you 31962306a36Sopenharmony_ci * don't have a handle on the URB used, you can't cancel the request. 32062306a36Sopenharmony_ci * 32162306a36Sopenharmony_ci * Return: 32262306a36Sopenharmony_ci * If successful, 0. Otherwise a negative error number. The number of actual 32362306a36Sopenharmony_ci * bytes transferred will be stored in the @actual_length parameter. 32462306a36Sopenharmony_ci */ 32562306a36Sopenharmony_ciint usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe, 32662306a36Sopenharmony_ci void *data, int len, int *actual_length, int timeout) 32762306a36Sopenharmony_ci{ 32862306a36Sopenharmony_ci return usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout); 32962306a36Sopenharmony_ci} 33062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_interrupt_msg); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci/** 33362306a36Sopenharmony_ci * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion 33462306a36Sopenharmony_ci * @usb_dev: pointer to the usb device to send the message to 33562306a36Sopenharmony_ci * @pipe: endpoint "pipe" to send the message to 33662306a36Sopenharmony_ci * @data: pointer to the data to send 33762306a36Sopenharmony_ci * @len: length in bytes of the data to send 33862306a36Sopenharmony_ci * @actual_length: pointer to a location to put the actual length transferred 33962306a36Sopenharmony_ci * in bytes 34062306a36Sopenharmony_ci * @timeout: time in msecs to wait for the message to complete before 34162306a36Sopenharmony_ci * timing out (if 0 the wait is forever) 34262306a36Sopenharmony_ci * 34362306a36Sopenharmony_ci * Context: task context, might sleep. 34462306a36Sopenharmony_ci * 34562306a36Sopenharmony_ci * This function sends a simple bulk message to a specified endpoint 34662306a36Sopenharmony_ci * and waits for the message to complete, or timeout. 34762306a36Sopenharmony_ci * 34862306a36Sopenharmony_ci * Don't use this function from within an interrupt context. If you need 34962306a36Sopenharmony_ci * an asynchronous message, or need to send a message from within interrupt 35062306a36Sopenharmony_ci * context, use usb_submit_urb() If a thread in your driver uses this call, 35162306a36Sopenharmony_ci * make sure your disconnect() method can wait for it to complete. Since you 35262306a36Sopenharmony_ci * don't have a handle on the URB used, you can't cancel the request. 35362306a36Sopenharmony_ci * 35462306a36Sopenharmony_ci * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT ioctl, 35562306a36Sopenharmony_ci * users are forced to abuse this routine by using it to submit URBs for 35662306a36Sopenharmony_ci * interrupt endpoints. We will take the liberty of creating an interrupt URB 35762306a36Sopenharmony_ci * (with the default interval) if the target is an interrupt endpoint. 35862306a36Sopenharmony_ci * 35962306a36Sopenharmony_ci * Return: 36062306a36Sopenharmony_ci * If successful, 0. Otherwise a negative error number. The number of actual 36162306a36Sopenharmony_ci * bytes transferred will be stored in the @actual_length parameter. 36262306a36Sopenharmony_ci * 36362306a36Sopenharmony_ci */ 36462306a36Sopenharmony_ciint usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, 36562306a36Sopenharmony_ci void *data, int len, int *actual_length, int timeout) 36662306a36Sopenharmony_ci{ 36762306a36Sopenharmony_ci struct urb *urb; 36862306a36Sopenharmony_ci struct usb_host_endpoint *ep; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci ep = usb_pipe_endpoint(usb_dev, pipe); 37162306a36Sopenharmony_ci if (!ep || len < 0) 37262306a36Sopenharmony_ci return -EINVAL; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci urb = usb_alloc_urb(0, GFP_KERNEL); 37562306a36Sopenharmony_ci if (!urb) 37662306a36Sopenharmony_ci return -ENOMEM; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 37962306a36Sopenharmony_ci USB_ENDPOINT_XFER_INT) { 38062306a36Sopenharmony_ci pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); 38162306a36Sopenharmony_ci usb_fill_int_urb(urb, usb_dev, pipe, data, len, 38262306a36Sopenharmony_ci usb_api_blocking_completion, NULL, 38362306a36Sopenharmony_ci ep->desc.bInterval); 38462306a36Sopenharmony_ci } else 38562306a36Sopenharmony_ci usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, 38662306a36Sopenharmony_ci usb_api_blocking_completion, NULL); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci return usb_start_wait_urb(urb, timeout, actual_length); 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_bulk_msg); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci/*-------------------------------------------------------------------*/ 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_cistatic void sg_clean(struct usb_sg_request *io) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci if (io->urbs) { 39762306a36Sopenharmony_ci while (io->entries--) 39862306a36Sopenharmony_ci usb_free_urb(io->urbs[io->entries]); 39962306a36Sopenharmony_ci kfree(io->urbs); 40062306a36Sopenharmony_ci io->urbs = NULL; 40162306a36Sopenharmony_ci } 40262306a36Sopenharmony_ci io->dev = NULL; 40362306a36Sopenharmony_ci} 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_cistatic void sg_complete(struct urb *urb) 40662306a36Sopenharmony_ci{ 40762306a36Sopenharmony_ci unsigned long flags; 40862306a36Sopenharmony_ci struct usb_sg_request *io = urb->context; 40962306a36Sopenharmony_ci int status = urb->status; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci spin_lock_irqsave(&io->lock, flags); 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci /* In 2.5 we require hcds' endpoint queues not to progress after fault 41462306a36Sopenharmony_ci * reports, until the completion callback (this!) returns. That lets 41562306a36Sopenharmony_ci * device driver code (like this routine) unlink queued urbs first, 41662306a36Sopenharmony_ci * if it needs to, since the HC won't work on them at all. So it's 41762306a36Sopenharmony_ci * not possible for page N+1 to overwrite page N, and so on. 41862306a36Sopenharmony_ci * 41962306a36Sopenharmony_ci * That's only for "hard" faults; "soft" faults (unlinks) sometimes 42062306a36Sopenharmony_ci * complete before the HCD can get requests away from hardware, 42162306a36Sopenharmony_ci * though never during cleanup after a hard fault. 42262306a36Sopenharmony_ci */ 42362306a36Sopenharmony_ci if (io->status 42462306a36Sopenharmony_ci && (io->status != -ECONNRESET 42562306a36Sopenharmony_ci || status != -ECONNRESET) 42662306a36Sopenharmony_ci && urb->actual_length) { 42762306a36Sopenharmony_ci dev_err(io->dev->bus->controller, 42862306a36Sopenharmony_ci "dev %s ep%d%s scatterlist error %d/%d\n", 42962306a36Sopenharmony_ci io->dev->devpath, 43062306a36Sopenharmony_ci usb_endpoint_num(&urb->ep->desc), 43162306a36Sopenharmony_ci usb_urb_dir_in(urb) ? "in" : "out", 43262306a36Sopenharmony_ci status, io->status); 43362306a36Sopenharmony_ci /* BUG (); */ 43462306a36Sopenharmony_ci } 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci if (io->status == 0 && status && status != -ECONNRESET) { 43762306a36Sopenharmony_ci int i, found, retval; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci io->status = status; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci /* the previous urbs, and this one, completed already. 44262306a36Sopenharmony_ci * unlink pending urbs so they won't rx/tx bad data. 44362306a36Sopenharmony_ci * careful: unlink can sometimes be synchronous... 44462306a36Sopenharmony_ci */ 44562306a36Sopenharmony_ci spin_unlock_irqrestore(&io->lock, flags); 44662306a36Sopenharmony_ci for (i = 0, found = 0; i < io->entries; i++) { 44762306a36Sopenharmony_ci if (!io->urbs[i]) 44862306a36Sopenharmony_ci continue; 44962306a36Sopenharmony_ci if (found) { 45062306a36Sopenharmony_ci usb_block_urb(io->urbs[i]); 45162306a36Sopenharmony_ci retval = usb_unlink_urb(io->urbs[i]); 45262306a36Sopenharmony_ci if (retval != -EINPROGRESS && 45362306a36Sopenharmony_ci retval != -ENODEV && 45462306a36Sopenharmony_ci retval != -EBUSY && 45562306a36Sopenharmony_ci retval != -EIDRM) 45662306a36Sopenharmony_ci dev_err(&io->dev->dev, 45762306a36Sopenharmony_ci "%s, unlink --> %d\n", 45862306a36Sopenharmony_ci __func__, retval); 45962306a36Sopenharmony_ci } else if (urb == io->urbs[i]) 46062306a36Sopenharmony_ci found = 1; 46162306a36Sopenharmony_ci } 46262306a36Sopenharmony_ci spin_lock_irqsave(&io->lock, flags); 46362306a36Sopenharmony_ci } 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci /* on the last completion, signal usb_sg_wait() */ 46662306a36Sopenharmony_ci io->bytes += urb->actual_length; 46762306a36Sopenharmony_ci io->count--; 46862306a36Sopenharmony_ci if (!io->count) 46962306a36Sopenharmony_ci complete(&io->complete); 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci spin_unlock_irqrestore(&io->lock, flags); 47262306a36Sopenharmony_ci} 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci/** 47662306a36Sopenharmony_ci * usb_sg_init - initializes scatterlist-based bulk/interrupt I/O request 47762306a36Sopenharmony_ci * @io: request block being initialized. until usb_sg_wait() returns, 47862306a36Sopenharmony_ci * treat this as a pointer to an opaque block of memory, 47962306a36Sopenharmony_ci * @dev: the usb device that will send or receive the data 48062306a36Sopenharmony_ci * @pipe: endpoint "pipe" used to transfer the data 48162306a36Sopenharmony_ci * @period: polling rate for interrupt endpoints, in frames or 48262306a36Sopenharmony_ci * (for high speed endpoints) microframes; ignored for bulk 48362306a36Sopenharmony_ci * @sg: scatterlist entries 48462306a36Sopenharmony_ci * @nents: how many entries in the scatterlist 48562306a36Sopenharmony_ci * @length: how many bytes to send from the scatterlist, or zero to 48662306a36Sopenharmony_ci * send every byte identified in the list. 48762306a36Sopenharmony_ci * @mem_flags: SLAB_* flags affecting memory allocations in this call 48862306a36Sopenharmony_ci * 48962306a36Sopenharmony_ci * This initializes a scatter/gather request, allocating resources such as 49062306a36Sopenharmony_ci * I/O mappings and urb memory (except maybe memory used by USB controller 49162306a36Sopenharmony_ci * drivers). 49262306a36Sopenharmony_ci * 49362306a36Sopenharmony_ci * The request must be issued using usb_sg_wait(), which waits for the I/O to 49462306a36Sopenharmony_ci * complete (or to be canceled) and then cleans up all resources allocated by 49562306a36Sopenharmony_ci * usb_sg_init(). 49662306a36Sopenharmony_ci * 49762306a36Sopenharmony_ci * The request may be canceled with usb_sg_cancel(), either before or after 49862306a36Sopenharmony_ci * usb_sg_wait() is called. 49962306a36Sopenharmony_ci * 50062306a36Sopenharmony_ci * Return: Zero for success, else a negative errno value. 50162306a36Sopenharmony_ci */ 50262306a36Sopenharmony_ciint usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, 50362306a36Sopenharmony_ci unsigned pipe, unsigned period, struct scatterlist *sg, 50462306a36Sopenharmony_ci int nents, size_t length, gfp_t mem_flags) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci int i; 50762306a36Sopenharmony_ci int urb_flags; 50862306a36Sopenharmony_ci int use_sg; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci if (!io || !dev || !sg 51162306a36Sopenharmony_ci || usb_pipecontrol(pipe) 51262306a36Sopenharmony_ci || usb_pipeisoc(pipe) 51362306a36Sopenharmony_ci || nents <= 0) 51462306a36Sopenharmony_ci return -EINVAL; 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci spin_lock_init(&io->lock); 51762306a36Sopenharmony_ci io->dev = dev; 51862306a36Sopenharmony_ci io->pipe = pipe; 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci if (dev->bus->sg_tablesize > 0) { 52162306a36Sopenharmony_ci use_sg = true; 52262306a36Sopenharmony_ci io->entries = 1; 52362306a36Sopenharmony_ci } else { 52462306a36Sopenharmony_ci use_sg = false; 52562306a36Sopenharmony_ci io->entries = nents; 52662306a36Sopenharmony_ci } 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci /* initialize all the urbs we'll use */ 52962306a36Sopenharmony_ci io->urbs = kmalloc_array(io->entries, sizeof(*io->urbs), mem_flags); 53062306a36Sopenharmony_ci if (!io->urbs) 53162306a36Sopenharmony_ci goto nomem; 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci urb_flags = URB_NO_INTERRUPT; 53462306a36Sopenharmony_ci if (usb_pipein(pipe)) 53562306a36Sopenharmony_ci urb_flags |= URB_SHORT_NOT_OK; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci for_each_sg(sg, sg, io->entries, i) { 53862306a36Sopenharmony_ci struct urb *urb; 53962306a36Sopenharmony_ci unsigned len; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci urb = usb_alloc_urb(0, mem_flags); 54262306a36Sopenharmony_ci if (!urb) { 54362306a36Sopenharmony_ci io->entries = i; 54462306a36Sopenharmony_ci goto nomem; 54562306a36Sopenharmony_ci } 54662306a36Sopenharmony_ci io->urbs[i] = urb; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci urb->dev = NULL; 54962306a36Sopenharmony_ci urb->pipe = pipe; 55062306a36Sopenharmony_ci urb->interval = period; 55162306a36Sopenharmony_ci urb->transfer_flags = urb_flags; 55262306a36Sopenharmony_ci urb->complete = sg_complete; 55362306a36Sopenharmony_ci urb->context = io; 55462306a36Sopenharmony_ci urb->sg = sg; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci if (use_sg) { 55762306a36Sopenharmony_ci /* There is no single transfer buffer */ 55862306a36Sopenharmony_ci urb->transfer_buffer = NULL; 55962306a36Sopenharmony_ci urb->num_sgs = nents; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci /* A length of zero means transfer the whole sg list */ 56262306a36Sopenharmony_ci len = length; 56362306a36Sopenharmony_ci if (len == 0) { 56462306a36Sopenharmony_ci struct scatterlist *sg2; 56562306a36Sopenharmony_ci int j; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci for_each_sg(sg, sg2, nents, j) 56862306a36Sopenharmony_ci len += sg2->length; 56962306a36Sopenharmony_ci } 57062306a36Sopenharmony_ci } else { 57162306a36Sopenharmony_ci /* 57262306a36Sopenharmony_ci * Some systems can't use DMA; they use PIO instead. 57362306a36Sopenharmony_ci * For their sakes, transfer_buffer is set whenever 57462306a36Sopenharmony_ci * possible. 57562306a36Sopenharmony_ci */ 57662306a36Sopenharmony_ci if (!PageHighMem(sg_page(sg))) 57762306a36Sopenharmony_ci urb->transfer_buffer = sg_virt(sg); 57862306a36Sopenharmony_ci else 57962306a36Sopenharmony_ci urb->transfer_buffer = NULL; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci len = sg->length; 58262306a36Sopenharmony_ci if (length) { 58362306a36Sopenharmony_ci len = min_t(size_t, len, length); 58462306a36Sopenharmony_ci length -= len; 58562306a36Sopenharmony_ci if (length == 0) 58662306a36Sopenharmony_ci io->entries = i + 1; 58762306a36Sopenharmony_ci } 58862306a36Sopenharmony_ci } 58962306a36Sopenharmony_ci urb->transfer_buffer_length = len; 59062306a36Sopenharmony_ci } 59162306a36Sopenharmony_ci io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci /* transaction state */ 59462306a36Sopenharmony_ci io->count = io->entries; 59562306a36Sopenharmony_ci io->status = 0; 59662306a36Sopenharmony_ci io->bytes = 0; 59762306a36Sopenharmony_ci init_completion(&io->complete); 59862306a36Sopenharmony_ci return 0; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_cinomem: 60162306a36Sopenharmony_ci sg_clean(io); 60262306a36Sopenharmony_ci return -ENOMEM; 60362306a36Sopenharmony_ci} 60462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_sg_init); 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ci/** 60762306a36Sopenharmony_ci * usb_sg_wait - synchronously execute scatter/gather request 60862306a36Sopenharmony_ci * @io: request block handle, as initialized with usb_sg_init(). 60962306a36Sopenharmony_ci * some fields become accessible when this call returns. 61062306a36Sopenharmony_ci * 61162306a36Sopenharmony_ci * Context: task context, might sleep. 61262306a36Sopenharmony_ci * 61362306a36Sopenharmony_ci * This function blocks until the specified I/O operation completes. It 61462306a36Sopenharmony_ci * leverages the grouping of the related I/O requests to get good transfer 61562306a36Sopenharmony_ci * rates, by queueing the requests. At higher speeds, such queuing can 61662306a36Sopenharmony_ci * significantly improve USB throughput. 61762306a36Sopenharmony_ci * 61862306a36Sopenharmony_ci * There are three kinds of completion for this function. 61962306a36Sopenharmony_ci * 62062306a36Sopenharmony_ci * (1) success, where io->status is zero. The number of io->bytes 62162306a36Sopenharmony_ci * transferred is as requested. 62262306a36Sopenharmony_ci * (2) error, where io->status is a negative errno value. The number 62362306a36Sopenharmony_ci * of io->bytes transferred before the error is usually less 62462306a36Sopenharmony_ci * than requested, and can be nonzero. 62562306a36Sopenharmony_ci * (3) cancellation, a type of error with status -ECONNRESET that 62662306a36Sopenharmony_ci * is initiated by usb_sg_cancel(). 62762306a36Sopenharmony_ci * 62862306a36Sopenharmony_ci * When this function returns, all memory allocated through usb_sg_init() or 62962306a36Sopenharmony_ci * this call will have been freed. The request block parameter may still be 63062306a36Sopenharmony_ci * passed to usb_sg_cancel(), or it may be freed. It could also be 63162306a36Sopenharmony_ci * reinitialized and then reused. 63262306a36Sopenharmony_ci * 63362306a36Sopenharmony_ci * Data Transfer Rates: 63462306a36Sopenharmony_ci * 63562306a36Sopenharmony_ci * Bulk transfers are valid for full or high speed endpoints. 63662306a36Sopenharmony_ci * The best full speed data rate is 19 packets of 64 bytes each 63762306a36Sopenharmony_ci * per frame, or 1216 bytes per millisecond. 63862306a36Sopenharmony_ci * The best high speed data rate is 13 packets of 512 bytes each 63962306a36Sopenharmony_ci * per microframe, or 52 KBytes per millisecond. 64062306a36Sopenharmony_ci * 64162306a36Sopenharmony_ci * The reason to use interrupt transfers through this API would most likely 64262306a36Sopenharmony_ci * be to reserve high speed bandwidth, where up to 24 KBytes per millisecond 64362306a36Sopenharmony_ci * could be transferred. That capability is less useful for low or full 64462306a36Sopenharmony_ci * speed interrupt endpoints, which allow at most one packet per millisecond, 64562306a36Sopenharmony_ci * of at most 8 or 64 bytes (respectively). 64662306a36Sopenharmony_ci * 64762306a36Sopenharmony_ci * It is not necessary to call this function to reserve bandwidth for devices 64862306a36Sopenharmony_ci * under an xHCI host controller, as the bandwidth is reserved when the 64962306a36Sopenharmony_ci * configuration or interface alt setting is selected. 65062306a36Sopenharmony_ci */ 65162306a36Sopenharmony_civoid usb_sg_wait(struct usb_sg_request *io) 65262306a36Sopenharmony_ci{ 65362306a36Sopenharmony_ci int i; 65462306a36Sopenharmony_ci int entries = io->entries; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci /* queue the urbs. */ 65762306a36Sopenharmony_ci spin_lock_irq(&io->lock); 65862306a36Sopenharmony_ci i = 0; 65962306a36Sopenharmony_ci while (i < entries && !io->status) { 66062306a36Sopenharmony_ci int retval; 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci io->urbs[i]->dev = io->dev; 66362306a36Sopenharmony_ci spin_unlock_irq(&io->lock); 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci retval = usb_submit_urb(io->urbs[i], GFP_NOIO); 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_ci switch (retval) { 66862306a36Sopenharmony_ci /* maybe we retrying will recover */ 66962306a36Sopenharmony_ci case -ENXIO: /* hc didn't queue this one */ 67062306a36Sopenharmony_ci case -EAGAIN: 67162306a36Sopenharmony_ci case -ENOMEM: 67262306a36Sopenharmony_ci retval = 0; 67362306a36Sopenharmony_ci yield(); 67462306a36Sopenharmony_ci break; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci /* no error? continue immediately. 67762306a36Sopenharmony_ci * 67862306a36Sopenharmony_ci * NOTE: to work better with UHCI (4K I/O buffer may 67962306a36Sopenharmony_ci * need 3K of TDs) it may be good to limit how many 68062306a36Sopenharmony_ci * URBs are queued at once; N milliseconds? 68162306a36Sopenharmony_ci */ 68262306a36Sopenharmony_ci case 0: 68362306a36Sopenharmony_ci ++i; 68462306a36Sopenharmony_ci cpu_relax(); 68562306a36Sopenharmony_ci break; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci /* fail any uncompleted urbs */ 68862306a36Sopenharmony_ci default: 68962306a36Sopenharmony_ci io->urbs[i]->status = retval; 69062306a36Sopenharmony_ci dev_dbg(&io->dev->dev, "%s, submit --> %d\n", 69162306a36Sopenharmony_ci __func__, retval); 69262306a36Sopenharmony_ci usb_sg_cancel(io); 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci spin_lock_irq(&io->lock); 69562306a36Sopenharmony_ci if (retval && (io->status == 0 || io->status == -ECONNRESET)) 69662306a36Sopenharmony_ci io->status = retval; 69762306a36Sopenharmony_ci } 69862306a36Sopenharmony_ci io->count -= entries - i; 69962306a36Sopenharmony_ci if (io->count == 0) 70062306a36Sopenharmony_ci complete(&io->complete); 70162306a36Sopenharmony_ci spin_unlock_irq(&io->lock); 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci /* OK, yes, this could be packaged as non-blocking. 70462306a36Sopenharmony_ci * So could the submit loop above ... but it's easier to 70562306a36Sopenharmony_ci * solve neither problem than to solve both! 70662306a36Sopenharmony_ci */ 70762306a36Sopenharmony_ci wait_for_completion(&io->complete); 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci sg_clean(io); 71062306a36Sopenharmony_ci} 71162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_sg_wait); 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci/** 71462306a36Sopenharmony_ci * usb_sg_cancel - stop scatter/gather i/o issued by usb_sg_wait() 71562306a36Sopenharmony_ci * @io: request block, initialized with usb_sg_init() 71662306a36Sopenharmony_ci * 71762306a36Sopenharmony_ci * This stops a request after it has been started by usb_sg_wait(). 71862306a36Sopenharmony_ci * It can also prevents one initialized by usb_sg_init() from starting, 71962306a36Sopenharmony_ci * so that call just frees resources allocated to the request. 72062306a36Sopenharmony_ci */ 72162306a36Sopenharmony_civoid usb_sg_cancel(struct usb_sg_request *io) 72262306a36Sopenharmony_ci{ 72362306a36Sopenharmony_ci unsigned long flags; 72462306a36Sopenharmony_ci int i, retval; 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci spin_lock_irqsave(&io->lock, flags); 72762306a36Sopenharmony_ci if (io->status || io->count == 0) { 72862306a36Sopenharmony_ci spin_unlock_irqrestore(&io->lock, flags); 72962306a36Sopenharmony_ci return; 73062306a36Sopenharmony_ci } 73162306a36Sopenharmony_ci /* shut everything down */ 73262306a36Sopenharmony_ci io->status = -ECONNRESET; 73362306a36Sopenharmony_ci io->count++; /* Keep the request alive until we're done */ 73462306a36Sopenharmony_ci spin_unlock_irqrestore(&io->lock, flags); 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci for (i = io->entries - 1; i >= 0; --i) { 73762306a36Sopenharmony_ci usb_block_urb(io->urbs[i]); 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci retval = usb_unlink_urb(io->urbs[i]); 74062306a36Sopenharmony_ci if (retval != -EINPROGRESS 74162306a36Sopenharmony_ci && retval != -ENODEV 74262306a36Sopenharmony_ci && retval != -EBUSY 74362306a36Sopenharmony_ci && retval != -EIDRM) 74462306a36Sopenharmony_ci dev_warn(&io->dev->dev, "%s, unlink --> %d\n", 74562306a36Sopenharmony_ci __func__, retval); 74662306a36Sopenharmony_ci } 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci spin_lock_irqsave(&io->lock, flags); 74962306a36Sopenharmony_ci io->count--; 75062306a36Sopenharmony_ci if (!io->count) 75162306a36Sopenharmony_ci complete(&io->complete); 75262306a36Sopenharmony_ci spin_unlock_irqrestore(&io->lock, flags); 75362306a36Sopenharmony_ci} 75462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_sg_cancel); 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci/*-------------------------------------------------------------------*/ 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci/** 75962306a36Sopenharmony_ci * usb_get_descriptor - issues a generic GET_DESCRIPTOR request 76062306a36Sopenharmony_ci * @dev: the device whose descriptor is being retrieved 76162306a36Sopenharmony_ci * @type: the descriptor type (USB_DT_*) 76262306a36Sopenharmony_ci * @index: the number of the descriptor 76362306a36Sopenharmony_ci * @buf: where to put the descriptor 76462306a36Sopenharmony_ci * @size: how big is "buf"? 76562306a36Sopenharmony_ci * 76662306a36Sopenharmony_ci * Context: task context, might sleep. 76762306a36Sopenharmony_ci * 76862306a36Sopenharmony_ci * Gets a USB descriptor. Convenience functions exist to simplify 76962306a36Sopenharmony_ci * getting some types of descriptors. Use 77062306a36Sopenharmony_ci * usb_get_string() or usb_string() for USB_DT_STRING. 77162306a36Sopenharmony_ci * Device (USB_DT_DEVICE) and configuration descriptors (USB_DT_CONFIG) 77262306a36Sopenharmony_ci * are part of the device structure. 77362306a36Sopenharmony_ci * In addition to a number of USB-standard descriptors, some 77462306a36Sopenharmony_ci * devices also use class-specific or vendor-specific descriptors. 77562306a36Sopenharmony_ci * 77662306a36Sopenharmony_ci * This call is synchronous, and may not be used in an interrupt context. 77762306a36Sopenharmony_ci * 77862306a36Sopenharmony_ci * Return: The number of bytes received on success, or else the status code 77962306a36Sopenharmony_ci * returned by the underlying usb_control_msg() call. 78062306a36Sopenharmony_ci */ 78162306a36Sopenharmony_ciint usb_get_descriptor(struct usb_device *dev, unsigned char type, 78262306a36Sopenharmony_ci unsigned char index, void *buf, int size) 78362306a36Sopenharmony_ci{ 78462306a36Sopenharmony_ci int i; 78562306a36Sopenharmony_ci int result; 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci if (size <= 0) /* No point in asking for no data */ 78862306a36Sopenharmony_ci return -EINVAL; 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci memset(buf, 0, size); /* Make sure we parse really received data */ 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci for (i = 0; i < 3; ++i) { 79362306a36Sopenharmony_ci /* retry on length 0 or error; some devices are flakey */ 79462306a36Sopenharmony_ci result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 79562306a36Sopenharmony_ci USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 79662306a36Sopenharmony_ci (type << 8) + index, 0, buf, size, 79762306a36Sopenharmony_ci USB_CTRL_GET_TIMEOUT); 79862306a36Sopenharmony_ci if (result <= 0 && result != -ETIMEDOUT) 79962306a36Sopenharmony_ci continue; 80062306a36Sopenharmony_ci if (result > 1 && ((u8 *)buf)[1] != type) { 80162306a36Sopenharmony_ci result = -ENODATA; 80262306a36Sopenharmony_ci continue; 80362306a36Sopenharmony_ci } 80462306a36Sopenharmony_ci break; 80562306a36Sopenharmony_ci } 80662306a36Sopenharmony_ci return result; 80762306a36Sopenharmony_ci} 80862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_get_descriptor); 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ci/** 81162306a36Sopenharmony_ci * usb_get_string - gets a string descriptor 81262306a36Sopenharmony_ci * @dev: the device whose string descriptor is being retrieved 81362306a36Sopenharmony_ci * @langid: code for language chosen (from string descriptor zero) 81462306a36Sopenharmony_ci * @index: the number of the descriptor 81562306a36Sopenharmony_ci * @buf: where to put the string 81662306a36Sopenharmony_ci * @size: how big is "buf"? 81762306a36Sopenharmony_ci * 81862306a36Sopenharmony_ci * Context: task context, might sleep. 81962306a36Sopenharmony_ci * 82062306a36Sopenharmony_ci * Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character, 82162306a36Sopenharmony_ci * in little-endian byte order). 82262306a36Sopenharmony_ci * The usb_string() function will often be a convenient way to turn 82362306a36Sopenharmony_ci * these strings into kernel-printable form. 82462306a36Sopenharmony_ci * 82562306a36Sopenharmony_ci * Strings may be referenced in device, configuration, interface, or other 82662306a36Sopenharmony_ci * descriptors, and could also be used in vendor-specific ways. 82762306a36Sopenharmony_ci * 82862306a36Sopenharmony_ci * This call is synchronous, and may not be used in an interrupt context. 82962306a36Sopenharmony_ci * 83062306a36Sopenharmony_ci * Return: The number of bytes received on success, or else the status code 83162306a36Sopenharmony_ci * returned by the underlying usb_control_msg() call. 83262306a36Sopenharmony_ci */ 83362306a36Sopenharmony_cistatic int usb_get_string(struct usb_device *dev, unsigned short langid, 83462306a36Sopenharmony_ci unsigned char index, void *buf, int size) 83562306a36Sopenharmony_ci{ 83662306a36Sopenharmony_ci int i; 83762306a36Sopenharmony_ci int result; 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci if (size <= 0) /* No point in asking for no data */ 84062306a36Sopenharmony_ci return -EINVAL; 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci for (i = 0; i < 3; ++i) { 84362306a36Sopenharmony_ci /* retry on length 0 or stall; some devices are flakey */ 84462306a36Sopenharmony_ci result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 84562306a36Sopenharmony_ci USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 84662306a36Sopenharmony_ci (USB_DT_STRING << 8) + index, langid, buf, size, 84762306a36Sopenharmony_ci USB_CTRL_GET_TIMEOUT); 84862306a36Sopenharmony_ci if (result == 0 || result == -EPIPE) 84962306a36Sopenharmony_ci continue; 85062306a36Sopenharmony_ci if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) { 85162306a36Sopenharmony_ci result = -ENODATA; 85262306a36Sopenharmony_ci continue; 85362306a36Sopenharmony_ci } 85462306a36Sopenharmony_ci break; 85562306a36Sopenharmony_ci } 85662306a36Sopenharmony_ci return result; 85762306a36Sopenharmony_ci} 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_cistatic void usb_try_string_workarounds(unsigned char *buf, int *length) 86062306a36Sopenharmony_ci{ 86162306a36Sopenharmony_ci int newlength, oldlength = *length; 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci for (newlength = 2; newlength + 1 < oldlength; newlength += 2) 86462306a36Sopenharmony_ci if (!isprint(buf[newlength]) || buf[newlength + 1]) 86562306a36Sopenharmony_ci break; 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci if (newlength > 2) { 86862306a36Sopenharmony_ci buf[0] = newlength; 86962306a36Sopenharmony_ci *length = newlength; 87062306a36Sopenharmony_ci } 87162306a36Sopenharmony_ci} 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_cistatic int usb_string_sub(struct usb_device *dev, unsigned int langid, 87462306a36Sopenharmony_ci unsigned int index, unsigned char *buf) 87562306a36Sopenharmony_ci{ 87662306a36Sopenharmony_ci int rc; 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci /* Try to read the string descriptor by asking for the maximum 87962306a36Sopenharmony_ci * possible number of bytes */ 88062306a36Sopenharmony_ci if (dev->quirks & USB_QUIRK_STRING_FETCH_255) 88162306a36Sopenharmony_ci rc = -EIO; 88262306a36Sopenharmony_ci else 88362306a36Sopenharmony_ci rc = usb_get_string(dev, langid, index, buf, 255); 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci /* If that failed try to read the descriptor length, then 88662306a36Sopenharmony_ci * ask for just that many bytes */ 88762306a36Sopenharmony_ci if (rc < 2) { 88862306a36Sopenharmony_ci rc = usb_get_string(dev, langid, index, buf, 2); 88962306a36Sopenharmony_ci if (rc == 2) 89062306a36Sopenharmony_ci rc = usb_get_string(dev, langid, index, buf, buf[0]); 89162306a36Sopenharmony_ci } 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_ci if (rc >= 2) { 89462306a36Sopenharmony_ci if (!buf[0] && !buf[1]) 89562306a36Sopenharmony_ci usb_try_string_workarounds(buf, &rc); 89662306a36Sopenharmony_ci 89762306a36Sopenharmony_ci /* There might be extra junk at the end of the descriptor */ 89862306a36Sopenharmony_ci if (buf[0] < rc) 89962306a36Sopenharmony_ci rc = buf[0]; 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_ci rc = rc - (rc & 1); /* force a multiple of two */ 90262306a36Sopenharmony_ci } 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci if (rc < 2) 90562306a36Sopenharmony_ci rc = (rc < 0 ? rc : -EINVAL); 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_ci return rc; 90862306a36Sopenharmony_ci} 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_cistatic int usb_get_langid(struct usb_device *dev, unsigned char *tbuf) 91162306a36Sopenharmony_ci{ 91262306a36Sopenharmony_ci int err; 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci if (dev->have_langid) 91562306a36Sopenharmony_ci return 0; 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ci if (dev->string_langid < 0) 91862306a36Sopenharmony_ci return -EPIPE; 91962306a36Sopenharmony_ci 92062306a36Sopenharmony_ci err = usb_string_sub(dev, 0, 0, tbuf); 92162306a36Sopenharmony_ci 92262306a36Sopenharmony_ci /* If the string was reported but is malformed, default to english 92362306a36Sopenharmony_ci * (0x0409) */ 92462306a36Sopenharmony_ci if (err == -ENODATA || (err > 0 && err < 4)) { 92562306a36Sopenharmony_ci dev->string_langid = 0x0409; 92662306a36Sopenharmony_ci dev->have_langid = 1; 92762306a36Sopenharmony_ci dev_err(&dev->dev, 92862306a36Sopenharmony_ci "language id specifier not provided by device, defaulting to English\n"); 92962306a36Sopenharmony_ci return 0; 93062306a36Sopenharmony_ci } 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ci /* In case of all other errors, we assume the device is not able to 93362306a36Sopenharmony_ci * deal with strings at all. Set string_langid to -1 in order to 93462306a36Sopenharmony_ci * prevent any string to be retrieved from the device */ 93562306a36Sopenharmony_ci if (err < 0) { 93662306a36Sopenharmony_ci dev_info(&dev->dev, "string descriptor 0 read error: %d\n", 93762306a36Sopenharmony_ci err); 93862306a36Sopenharmony_ci dev->string_langid = -1; 93962306a36Sopenharmony_ci return -EPIPE; 94062306a36Sopenharmony_ci } 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_ci /* always use the first langid listed */ 94362306a36Sopenharmony_ci dev->string_langid = tbuf[2] | (tbuf[3] << 8); 94462306a36Sopenharmony_ci dev->have_langid = 1; 94562306a36Sopenharmony_ci dev_dbg(&dev->dev, "default language 0x%04x\n", 94662306a36Sopenharmony_ci dev->string_langid); 94762306a36Sopenharmony_ci return 0; 94862306a36Sopenharmony_ci} 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci/** 95162306a36Sopenharmony_ci * usb_string - returns UTF-8 version of a string descriptor 95262306a36Sopenharmony_ci * @dev: the device whose string descriptor is being retrieved 95362306a36Sopenharmony_ci * @index: the number of the descriptor 95462306a36Sopenharmony_ci * @buf: where to put the string 95562306a36Sopenharmony_ci * @size: how big is "buf"? 95662306a36Sopenharmony_ci * 95762306a36Sopenharmony_ci * Context: task context, might sleep. 95862306a36Sopenharmony_ci * 95962306a36Sopenharmony_ci * This converts the UTF-16LE encoded strings returned by devices, from 96062306a36Sopenharmony_ci * usb_get_string_descriptor(), to null-terminated UTF-8 encoded ones 96162306a36Sopenharmony_ci * that are more usable in most kernel contexts. Note that this function 96262306a36Sopenharmony_ci * chooses strings in the first language supported by the device. 96362306a36Sopenharmony_ci * 96462306a36Sopenharmony_ci * This call is synchronous, and may not be used in an interrupt context. 96562306a36Sopenharmony_ci * 96662306a36Sopenharmony_ci * Return: length of the string (>= 0) or usb_control_msg status (< 0). 96762306a36Sopenharmony_ci */ 96862306a36Sopenharmony_ciint usb_string(struct usb_device *dev, int index, char *buf, size_t size) 96962306a36Sopenharmony_ci{ 97062306a36Sopenharmony_ci unsigned char *tbuf; 97162306a36Sopenharmony_ci int err; 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci if (dev->state == USB_STATE_SUSPENDED) 97462306a36Sopenharmony_ci return -EHOSTUNREACH; 97562306a36Sopenharmony_ci if (size <= 0 || !buf) 97662306a36Sopenharmony_ci return -EINVAL; 97762306a36Sopenharmony_ci buf[0] = 0; 97862306a36Sopenharmony_ci if (index <= 0 || index >= 256) 97962306a36Sopenharmony_ci return -EINVAL; 98062306a36Sopenharmony_ci tbuf = kmalloc(256, GFP_NOIO); 98162306a36Sopenharmony_ci if (!tbuf) 98262306a36Sopenharmony_ci return -ENOMEM; 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ci err = usb_get_langid(dev, tbuf); 98562306a36Sopenharmony_ci if (err < 0) 98662306a36Sopenharmony_ci goto errout; 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci err = usb_string_sub(dev, dev->string_langid, index, tbuf); 98962306a36Sopenharmony_ci if (err < 0) 99062306a36Sopenharmony_ci goto errout; 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci size--; /* leave room for trailing NULL char in output buffer */ 99362306a36Sopenharmony_ci err = utf16s_to_utf8s((wchar_t *) &tbuf[2], (err - 2) / 2, 99462306a36Sopenharmony_ci UTF16_LITTLE_ENDIAN, buf, size); 99562306a36Sopenharmony_ci buf[err] = 0; 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_ci if (tbuf[1] != USB_DT_STRING) 99862306a36Sopenharmony_ci dev_dbg(&dev->dev, 99962306a36Sopenharmony_ci "wrong descriptor type %02x for string %d (\"%s\")\n", 100062306a36Sopenharmony_ci tbuf[1], index, buf); 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci errout: 100362306a36Sopenharmony_ci kfree(tbuf); 100462306a36Sopenharmony_ci return err; 100562306a36Sopenharmony_ci} 100662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_string); 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci/* one UTF-8-encoded 16-bit character has at most three bytes */ 100962306a36Sopenharmony_ci#define MAX_USB_STRING_SIZE (127 * 3 + 1) 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci/** 101262306a36Sopenharmony_ci * usb_cache_string - read a string descriptor and cache it for later use 101362306a36Sopenharmony_ci * @udev: the device whose string descriptor is being read 101462306a36Sopenharmony_ci * @index: the descriptor index 101562306a36Sopenharmony_ci * 101662306a36Sopenharmony_ci * Return: A pointer to a kmalloc'ed buffer containing the descriptor string, 101762306a36Sopenharmony_ci * or %NULL if the index is 0 or the string could not be read. 101862306a36Sopenharmony_ci */ 101962306a36Sopenharmony_cichar *usb_cache_string(struct usb_device *udev, int index) 102062306a36Sopenharmony_ci{ 102162306a36Sopenharmony_ci char *buf; 102262306a36Sopenharmony_ci char *smallbuf = NULL; 102362306a36Sopenharmony_ci int len; 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci if (index <= 0) 102662306a36Sopenharmony_ci return NULL; 102762306a36Sopenharmony_ci 102862306a36Sopenharmony_ci buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO); 102962306a36Sopenharmony_ci if (buf) { 103062306a36Sopenharmony_ci len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE); 103162306a36Sopenharmony_ci if (len > 0) { 103262306a36Sopenharmony_ci smallbuf = kmalloc(++len, GFP_NOIO); 103362306a36Sopenharmony_ci if (!smallbuf) 103462306a36Sopenharmony_ci return buf; 103562306a36Sopenharmony_ci memcpy(smallbuf, buf, len); 103662306a36Sopenharmony_ci } 103762306a36Sopenharmony_ci kfree(buf); 103862306a36Sopenharmony_ci } 103962306a36Sopenharmony_ci return smallbuf; 104062306a36Sopenharmony_ci} 104162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_cache_string); 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci/* 104462306a36Sopenharmony_ci * usb_get_device_descriptor - read the device descriptor 104562306a36Sopenharmony_ci * @udev: the device whose device descriptor should be read 104662306a36Sopenharmony_ci * 104762306a36Sopenharmony_ci * Context: task context, might sleep. 104862306a36Sopenharmony_ci * 104962306a36Sopenharmony_ci * Not exported, only for use by the core. If drivers really want to read 105062306a36Sopenharmony_ci * the device descriptor directly, they can call usb_get_descriptor() with 105162306a36Sopenharmony_ci * type = USB_DT_DEVICE and index = 0. 105262306a36Sopenharmony_ci * 105362306a36Sopenharmony_ci * Returns: a pointer to a dynamically allocated usb_device_descriptor 105462306a36Sopenharmony_ci * structure (which the caller must deallocate), or an ERR_PTR value. 105562306a36Sopenharmony_ci */ 105662306a36Sopenharmony_cistruct usb_device_descriptor *usb_get_device_descriptor(struct usb_device *udev) 105762306a36Sopenharmony_ci{ 105862306a36Sopenharmony_ci struct usb_device_descriptor *desc; 105962306a36Sopenharmony_ci int ret; 106062306a36Sopenharmony_ci 106162306a36Sopenharmony_ci desc = kmalloc(sizeof(*desc), GFP_NOIO); 106262306a36Sopenharmony_ci if (!desc) 106362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_ci ret = usb_get_descriptor(udev, USB_DT_DEVICE, 0, desc, sizeof(*desc)); 106662306a36Sopenharmony_ci if (ret == sizeof(*desc)) 106762306a36Sopenharmony_ci return desc; 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_ci if (ret >= 0) 107062306a36Sopenharmony_ci ret = -EMSGSIZE; 107162306a36Sopenharmony_ci kfree(desc); 107262306a36Sopenharmony_ci return ERR_PTR(ret); 107362306a36Sopenharmony_ci} 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci/* 107662306a36Sopenharmony_ci * usb_set_isoch_delay - informs the device of the packet transmit delay 107762306a36Sopenharmony_ci * @dev: the device whose delay is to be informed 107862306a36Sopenharmony_ci * Context: task context, might sleep 107962306a36Sopenharmony_ci * 108062306a36Sopenharmony_ci * Since this is an optional request, we don't bother if it fails. 108162306a36Sopenharmony_ci */ 108262306a36Sopenharmony_ciint usb_set_isoch_delay(struct usb_device *dev) 108362306a36Sopenharmony_ci{ 108462306a36Sopenharmony_ci /* skip hub devices */ 108562306a36Sopenharmony_ci if (dev->descriptor.bDeviceClass == USB_CLASS_HUB) 108662306a36Sopenharmony_ci return 0; 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci /* skip non-SS/non-SSP devices */ 108962306a36Sopenharmony_ci if (dev->speed < USB_SPEED_SUPER) 109062306a36Sopenharmony_ci return 0; 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_ci return usb_control_msg_send(dev, 0, 109362306a36Sopenharmony_ci USB_REQ_SET_ISOCH_DELAY, 109462306a36Sopenharmony_ci USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, 109562306a36Sopenharmony_ci dev->hub_delay, 0, NULL, 0, 109662306a36Sopenharmony_ci USB_CTRL_SET_TIMEOUT, 109762306a36Sopenharmony_ci GFP_NOIO); 109862306a36Sopenharmony_ci} 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci/** 110162306a36Sopenharmony_ci * usb_get_status - issues a GET_STATUS call 110262306a36Sopenharmony_ci * @dev: the device whose status is being checked 110362306a36Sopenharmony_ci * @recip: USB_RECIP_*; for device, interface, or endpoint 110462306a36Sopenharmony_ci * @type: USB_STATUS_TYPE_*; for standard or PTM status types 110562306a36Sopenharmony_ci * @target: zero (for device), else interface or endpoint number 110662306a36Sopenharmony_ci * @data: pointer to two bytes of bitmap data 110762306a36Sopenharmony_ci * 110862306a36Sopenharmony_ci * Context: task context, might sleep. 110962306a36Sopenharmony_ci * 111062306a36Sopenharmony_ci * Returns device, interface, or endpoint status. Normally only of 111162306a36Sopenharmony_ci * interest to see if the device is self powered, or has enabled the 111262306a36Sopenharmony_ci * remote wakeup facility; or whether a bulk or interrupt endpoint 111362306a36Sopenharmony_ci * is halted ("stalled"). 111462306a36Sopenharmony_ci * 111562306a36Sopenharmony_ci * Bits in these status bitmaps are set using the SET_FEATURE request, 111662306a36Sopenharmony_ci * and cleared using the CLEAR_FEATURE request. The usb_clear_halt() 111762306a36Sopenharmony_ci * function should be used to clear halt ("stall") status. 111862306a36Sopenharmony_ci * 111962306a36Sopenharmony_ci * This call is synchronous, and may not be used in an interrupt context. 112062306a36Sopenharmony_ci * 112162306a36Sopenharmony_ci * Returns 0 and the status value in *@data (in host byte order) on success, 112262306a36Sopenharmony_ci * or else the status code from the underlying usb_control_msg() call. 112362306a36Sopenharmony_ci */ 112462306a36Sopenharmony_ciint usb_get_status(struct usb_device *dev, int recip, int type, int target, 112562306a36Sopenharmony_ci void *data) 112662306a36Sopenharmony_ci{ 112762306a36Sopenharmony_ci int ret; 112862306a36Sopenharmony_ci void *status; 112962306a36Sopenharmony_ci int length; 113062306a36Sopenharmony_ci 113162306a36Sopenharmony_ci switch (type) { 113262306a36Sopenharmony_ci case USB_STATUS_TYPE_STANDARD: 113362306a36Sopenharmony_ci length = 2; 113462306a36Sopenharmony_ci break; 113562306a36Sopenharmony_ci case USB_STATUS_TYPE_PTM: 113662306a36Sopenharmony_ci if (recip != USB_RECIP_DEVICE) 113762306a36Sopenharmony_ci return -EINVAL; 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci length = 4; 114062306a36Sopenharmony_ci break; 114162306a36Sopenharmony_ci default: 114262306a36Sopenharmony_ci return -EINVAL; 114362306a36Sopenharmony_ci } 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ci status = kmalloc(length, GFP_KERNEL); 114662306a36Sopenharmony_ci if (!status) 114762306a36Sopenharmony_ci return -ENOMEM; 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_ci ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 115062306a36Sopenharmony_ci USB_REQ_GET_STATUS, USB_DIR_IN | recip, USB_STATUS_TYPE_STANDARD, 115162306a36Sopenharmony_ci target, status, length, USB_CTRL_GET_TIMEOUT); 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_ci switch (ret) { 115462306a36Sopenharmony_ci case 4: 115562306a36Sopenharmony_ci if (type != USB_STATUS_TYPE_PTM) { 115662306a36Sopenharmony_ci ret = -EIO; 115762306a36Sopenharmony_ci break; 115862306a36Sopenharmony_ci } 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ci *(u32 *) data = le32_to_cpu(*(__le32 *) status); 116162306a36Sopenharmony_ci ret = 0; 116262306a36Sopenharmony_ci break; 116362306a36Sopenharmony_ci case 2: 116462306a36Sopenharmony_ci if (type != USB_STATUS_TYPE_STANDARD) { 116562306a36Sopenharmony_ci ret = -EIO; 116662306a36Sopenharmony_ci break; 116762306a36Sopenharmony_ci } 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_ci *(u16 *) data = le16_to_cpu(*(__le16 *) status); 117062306a36Sopenharmony_ci ret = 0; 117162306a36Sopenharmony_ci break; 117262306a36Sopenharmony_ci default: 117362306a36Sopenharmony_ci ret = -EIO; 117462306a36Sopenharmony_ci } 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_ci kfree(status); 117762306a36Sopenharmony_ci return ret; 117862306a36Sopenharmony_ci} 117962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_get_status); 118062306a36Sopenharmony_ci 118162306a36Sopenharmony_ci/** 118262306a36Sopenharmony_ci * usb_clear_halt - tells device to clear endpoint halt/stall condition 118362306a36Sopenharmony_ci * @dev: device whose endpoint is halted 118462306a36Sopenharmony_ci * @pipe: endpoint "pipe" being cleared 118562306a36Sopenharmony_ci * 118662306a36Sopenharmony_ci * Context: task context, might sleep. 118762306a36Sopenharmony_ci * 118862306a36Sopenharmony_ci * This is used to clear halt conditions for bulk and interrupt endpoints, 118962306a36Sopenharmony_ci * as reported by URB completion status. Endpoints that are halted are 119062306a36Sopenharmony_ci * sometimes referred to as being "stalled". Such endpoints are unable 119162306a36Sopenharmony_ci * to transmit or receive data until the halt status is cleared. Any URBs 119262306a36Sopenharmony_ci * queued for such an endpoint should normally be unlinked by the driver 119362306a36Sopenharmony_ci * before clearing the halt condition, as described in sections 5.7.5 119462306a36Sopenharmony_ci * and 5.8.5 of the USB 2.0 spec. 119562306a36Sopenharmony_ci * 119662306a36Sopenharmony_ci * Note that control and isochronous endpoints don't halt, although control 119762306a36Sopenharmony_ci * endpoints report "protocol stall" (for unsupported requests) using the 119862306a36Sopenharmony_ci * same status code used to report a true stall. 119962306a36Sopenharmony_ci * 120062306a36Sopenharmony_ci * This call is synchronous, and may not be used in an interrupt context. 120162306a36Sopenharmony_ci * 120262306a36Sopenharmony_ci * Return: Zero on success, or else the status code returned by the 120362306a36Sopenharmony_ci * underlying usb_control_msg() call. 120462306a36Sopenharmony_ci */ 120562306a36Sopenharmony_ciint usb_clear_halt(struct usb_device *dev, int pipe) 120662306a36Sopenharmony_ci{ 120762306a36Sopenharmony_ci int result; 120862306a36Sopenharmony_ci int endp = usb_pipeendpoint(pipe); 120962306a36Sopenharmony_ci 121062306a36Sopenharmony_ci if (usb_pipein(pipe)) 121162306a36Sopenharmony_ci endp |= USB_DIR_IN; 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_ci /* we don't care if it wasn't halted first. in fact some devices 121462306a36Sopenharmony_ci * (like some ibmcam model 1 units) seem to expect hosts to make 121562306a36Sopenharmony_ci * this request for iso endpoints, which can't halt! 121662306a36Sopenharmony_ci */ 121762306a36Sopenharmony_ci result = usb_control_msg_send(dev, 0, 121862306a36Sopenharmony_ci USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 121962306a36Sopenharmony_ci USB_ENDPOINT_HALT, endp, NULL, 0, 122062306a36Sopenharmony_ci USB_CTRL_SET_TIMEOUT, GFP_NOIO); 122162306a36Sopenharmony_ci 122262306a36Sopenharmony_ci /* don't un-halt or force to DATA0 except on success */ 122362306a36Sopenharmony_ci if (result) 122462306a36Sopenharmony_ci return result; 122562306a36Sopenharmony_ci 122662306a36Sopenharmony_ci /* NOTE: seems like Microsoft and Apple don't bother verifying 122762306a36Sopenharmony_ci * the clear "took", so some devices could lock up if you check... 122862306a36Sopenharmony_ci * such as the Hagiwara FlashGate DUAL. So we won't bother. 122962306a36Sopenharmony_ci * 123062306a36Sopenharmony_ci * NOTE: make sure the logic here doesn't diverge much from 123162306a36Sopenharmony_ci * the copy in usb-storage, for as long as we need two copies. 123262306a36Sopenharmony_ci */ 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci usb_reset_endpoint(dev, endp); 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci return 0; 123762306a36Sopenharmony_ci} 123862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_clear_halt); 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_cistatic int create_intf_ep_devs(struct usb_interface *intf) 124162306a36Sopenharmony_ci{ 124262306a36Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(intf); 124362306a36Sopenharmony_ci struct usb_host_interface *alt = intf->cur_altsetting; 124462306a36Sopenharmony_ci int i; 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_ci if (intf->ep_devs_created || intf->unregistering) 124762306a36Sopenharmony_ci return 0; 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci for (i = 0; i < alt->desc.bNumEndpoints; ++i) 125062306a36Sopenharmony_ci (void) usb_create_ep_devs(&intf->dev, &alt->endpoint[i], udev); 125162306a36Sopenharmony_ci intf->ep_devs_created = 1; 125262306a36Sopenharmony_ci return 0; 125362306a36Sopenharmony_ci} 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_cistatic void remove_intf_ep_devs(struct usb_interface *intf) 125662306a36Sopenharmony_ci{ 125762306a36Sopenharmony_ci struct usb_host_interface *alt = intf->cur_altsetting; 125862306a36Sopenharmony_ci int i; 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci if (!intf->ep_devs_created) 126162306a36Sopenharmony_ci return; 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_ci for (i = 0; i < alt->desc.bNumEndpoints; ++i) 126462306a36Sopenharmony_ci usb_remove_ep_devs(&alt->endpoint[i]); 126562306a36Sopenharmony_ci intf->ep_devs_created = 0; 126662306a36Sopenharmony_ci} 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci/** 126962306a36Sopenharmony_ci * usb_disable_endpoint -- Disable an endpoint by address 127062306a36Sopenharmony_ci * @dev: the device whose endpoint is being disabled 127162306a36Sopenharmony_ci * @epaddr: the endpoint's address. Endpoint number for output, 127262306a36Sopenharmony_ci * endpoint number + USB_DIR_IN for input 127362306a36Sopenharmony_ci * @reset_hardware: flag to erase any endpoint state stored in the 127462306a36Sopenharmony_ci * controller hardware 127562306a36Sopenharmony_ci * 127662306a36Sopenharmony_ci * Disables the endpoint for URB submission and nukes all pending URBs. 127762306a36Sopenharmony_ci * If @reset_hardware is set then also deallocates hcd/hardware state 127862306a36Sopenharmony_ci * for the endpoint. 127962306a36Sopenharmony_ci */ 128062306a36Sopenharmony_civoid usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, 128162306a36Sopenharmony_ci bool reset_hardware) 128262306a36Sopenharmony_ci{ 128362306a36Sopenharmony_ci unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; 128462306a36Sopenharmony_ci struct usb_host_endpoint *ep; 128562306a36Sopenharmony_ci 128662306a36Sopenharmony_ci if (!dev) 128762306a36Sopenharmony_ci return; 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci if (usb_endpoint_out(epaddr)) { 129062306a36Sopenharmony_ci ep = dev->ep_out[epnum]; 129162306a36Sopenharmony_ci if (reset_hardware && epnum != 0) 129262306a36Sopenharmony_ci dev->ep_out[epnum] = NULL; 129362306a36Sopenharmony_ci } else { 129462306a36Sopenharmony_ci ep = dev->ep_in[epnum]; 129562306a36Sopenharmony_ci if (reset_hardware && epnum != 0) 129662306a36Sopenharmony_ci dev->ep_in[epnum] = NULL; 129762306a36Sopenharmony_ci } 129862306a36Sopenharmony_ci if (ep) { 129962306a36Sopenharmony_ci ep->enabled = 0; 130062306a36Sopenharmony_ci usb_hcd_flush_endpoint(dev, ep); 130162306a36Sopenharmony_ci if (reset_hardware) 130262306a36Sopenharmony_ci usb_hcd_disable_endpoint(dev, ep); 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci} 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci/** 130762306a36Sopenharmony_ci * usb_reset_endpoint - Reset an endpoint's state. 130862306a36Sopenharmony_ci * @dev: the device whose endpoint is to be reset 130962306a36Sopenharmony_ci * @epaddr: the endpoint's address. Endpoint number for output, 131062306a36Sopenharmony_ci * endpoint number + USB_DIR_IN for input 131162306a36Sopenharmony_ci * 131262306a36Sopenharmony_ci * Resets any host-side endpoint state such as the toggle bit, 131362306a36Sopenharmony_ci * sequence number or current window. 131462306a36Sopenharmony_ci */ 131562306a36Sopenharmony_civoid usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr) 131662306a36Sopenharmony_ci{ 131762306a36Sopenharmony_ci unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; 131862306a36Sopenharmony_ci struct usb_host_endpoint *ep; 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_ci if (usb_endpoint_out(epaddr)) 132162306a36Sopenharmony_ci ep = dev->ep_out[epnum]; 132262306a36Sopenharmony_ci else 132362306a36Sopenharmony_ci ep = dev->ep_in[epnum]; 132462306a36Sopenharmony_ci if (ep) 132562306a36Sopenharmony_ci usb_hcd_reset_endpoint(dev, ep); 132662306a36Sopenharmony_ci} 132762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_reset_endpoint); 132862306a36Sopenharmony_ci 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci/** 133162306a36Sopenharmony_ci * usb_disable_interface -- Disable all endpoints for an interface 133262306a36Sopenharmony_ci * @dev: the device whose interface is being disabled 133362306a36Sopenharmony_ci * @intf: pointer to the interface descriptor 133462306a36Sopenharmony_ci * @reset_hardware: flag to erase any endpoint state stored in the 133562306a36Sopenharmony_ci * controller hardware 133662306a36Sopenharmony_ci * 133762306a36Sopenharmony_ci * Disables all the endpoints for the interface's current altsetting. 133862306a36Sopenharmony_ci */ 133962306a36Sopenharmony_civoid usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, 134062306a36Sopenharmony_ci bool reset_hardware) 134162306a36Sopenharmony_ci{ 134262306a36Sopenharmony_ci struct usb_host_interface *alt = intf->cur_altsetting; 134362306a36Sopenharmony_ci int i; 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_ci for (i = 0; i < alt->desc.bNumEndpoints; ++i) { 134662306a36Sopenharmony_ci usb_disable_endpoint(dev, 134762306a36Sopenharmony_ci alt->endpoint[i].desc.bEndpointAddress, 134862306a36Sopenharmony_ci reset_hardware); 134962306a36Sopenharmony_ci } 135062306a36Sopenharmony_ci} 135162306a36Sopenharmony_ci 135262306a36Sopenharmony_ci/* 135362306a36Sopenharmony_ci * usb_disable_device_endpoints -- Disable all endpoints for a device 135462306a36Sopenharmony_ci * @dev: the device whose endpoints are being disabled 135562306a36Sopenharmony_ci * @skip_ep0: 0 to disable endpoint 0, 1 to skip it. 135662306a36Sopenharmony_ci */ 135762306a36Sopenharmony_cistatic void usb_disable_device_endpoints(struct usb_device *dev, int skip_ep0) 135862306a36Sopenharmony_ci{ 135962306a36Sopenharmony_ci struct usb_hcd *hcd = bus_to_hcd(dev->bus); 136062306a36Sopenharmony_ci int i; 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci if (hcd->driver->check_bandwidth) { 136362306a36Sopenharmony_ci /* First pass: Cancel URBs, leave endpoint pointers intact. */ 136462306a36Sopenharmony_ci for (i = skip_ep0; i < 16; ++i) { 136562306a36Sopenharmony_ci usb_disable_endpoint(dev, i, false); 136662306a36Sopenharmony_ci usb_disable_endpoint(dev, i + USB_DIR_IN, false); 136762306a36Sopenharmony_ci } 136862306a36Sopenharmony_ci /* Remove endpoints from the host controller internal state */ 136962306a36Sopenharmony_ci mutex_lock(hcd->bandwidth_mutex); 137062306a36Sopenharmony_ci usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); 137162306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 137262306a36Sopenharmony_ci } 137362306a36Sopenharmony_ci /* Second pass: remove endpoint pointers */ 137462306a36Sopenharmony_ci for (i = skip_ep0; i < 16; ++i) { 137562306a36Sopenharmony_ci usb_disable_endpoint(dev, i, true); 137662306a36Sopenharmony_ci usb_disable_endpoint(dev, i + USB_DIR_IN, true); 137762306a36Sopenharmony_ci } 137862306a36Sopenharmony_ci} 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_ci/** 138162306a36Sopenharmony_ci * usb_disable_device - Disable all the endpoints for a USB device 138262306a36Sopenharmony_ci * @dev: the device whose endpoints are being disabled 138362306a36Sopenharmony_ci * @skip_ep0: 0 to disable endpoint 0, 1 to skip it. 138462306a36Sopenharmony_ci * 138562306a36Sopenharmony_ci * Disables all the device's endpoints, potentially including endpoint 0. 138662306a36Sopenharmony_ci * Deallocates hcd/hardware state for the endpoints (nuking all or most 138762306a36Sopenharmony_ci * pending urbs) and usbcore state for the interfaces, so that usbcore 138862306a36Sopenharmony_ci * must usb_set_configuration() before any interfaces could be used. 138962306a36Sopenharmony_ci */ 139062306a36Sopenharmony_civoid usb_disable_device(struct usb_device *dev, int skip_ep0) 139162306a36Sopenharmony_ci{ 139262306a36Sopenharmony_ci int i; 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci /* getting rid of interfaces will disconnect 139562306a36Sopenharmony_ci * any drivers bound to them (a key side effect) 139662306a36Sopenharmony_ci */ 139762306a36Sopenharmony_ci if (dev->actconfig) { 139862306a36Sopenharmony_ci /* 139962306a36Sopenharmony_ci * FIXME: In order to avoid self-deadlock involving the 140062306a36Sopenharmony_ci * bandwidth_mutex, we have to mark all the interfaces 140162306a36Sopenharmony_ci * before unregistering any of them. 140262306a36Sopenharmony_ci */ 140362306a36Sopenharmony_ci for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) 140462306a36Sopenharmony_ci dev->actconfig->interface[i]->unregistering = 1; 140562306a36Sopenharmony_ci 140662306a36Sopenharmony_ci for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { 140762306a36Sopenharmony_ci struct usb_interface *interface; 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ci /* remove this interface if it has been registered */ 141062306a36Sopenharmony_ci interface = dev->actconfig->interface[i]; 141162306a36Sopenharmony_ci if (!device_is_registered(&interface->dev)) 141262306a36Sopenharmony_ci continue; 141362306a36Sopenharmony_ci dev_dbg(&dev->dev, "unregistering interface %s\n", 141462306a36Sopenharmony_ci dev_name(&interface->dev)); 141562306a36Sopenharmony_ci remove_intf_ep_devs(interface); 141662306a36Sopenharmony_ci device_del(&interface->dev); 141762306a36Sopenharmony_ci } 141862306a36Sopenharmony_ci 141962306a36Sopenharmony_ci /* Now that the interfaces are unbound, nobody should 142062306a36Sopenharmony_ci * try to access them. 142162306a36Sopenharmony_ci */ 142262306a36Sopenharmony_ci for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { 142362306a36Sopenharmony_ci put_device(&dev->actconfig->interface[i]->dev); 142462306a36Sopenharmony_ci dev->actconfig->interface[i] = NULL; 142562306a36Sopenharmony_ci } 142662306a36Sopenharmony_ci 142762306a36Sopenharmony_ci usb_disable_usb2_hardware_lpm(dev); 142862306a36Sopenharmony_ci usb_unlocked_disable_lpm(dev); 142962306a36Sopenharmony_ci usb_disable_ltm(dev); 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_ci dev->actconfig = NULL; 143262306a36Sopenharmony_ci if (dev->state == USB_STATE_CONFIGURED) 143362306a36Sopenharmony_ci usb_set_device_state(dev, USB_STATE_ADDRESS); 143462306a36Sopenharmony_ci } 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_ci dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, 143762306a36Sopenharmony_ci skip_ep0 ? "non-ep0" : "all"); 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci usb_disable_device_endpoints(dev, skip_ep0); 144062306a36Sopenharmony_ci} 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ci/** 144362306a36Sopenharmony_ci * usb_enable_endpoint - Enable an endpoint for USB communications 144462306a36Sopenharmony_ci * @dev: the device whose interface is being enabled 144562306a36Sopenharmony_ci * @ep: the endpoint 144662306a36Sopenharmony_ci * @reset_ep: flag to reset the endpoint state 144762306a36Sopenharmony_ci * 144862306a36Sopenharmony_ci * Resets the endpoint state if asked, and sets dev->ep_{in,out} pointers. 144962306a36Sopenharmony_ci * For control endpoints, both the input and output sides are handled. 145062306a36Sopenharmony_ci */ 145162306a36Sopenharmony_civoid usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, 145262306a36Sopenharmony_ci bool reset_ep) 145362306a36Sopenharmony_ci{ 145462306a36Sopenharmony_ci int epnum = usb_endpoint_num(&ep->desc); 145562306a36Sopenharmony_ci int is_out = usb_endpoint_dir_out(&ep->desc); 145662306a36Sopenharmony_ci int is_control = usb_endpoint_xfer_control(&ep->desc); 145762306a36Sopenharmony_ci 145862306a36Sopenharmony_ci if (reset_ep) 145962306a36Sopenharmony_ci usb_hcd_reset_endpoint(dev, ep); 146062306a36Sopenharmony_ci if (is_out || is_control) 146162306a36Sopenharmony_ci dev->ep_out[epnum] = ep; 146262306a36Sopenharmony_ci if (!is_out || is_control) 146362306a36Sopenharmony_ci dev->ep_in[epnum] = ep; 146462306a36Sopenharmony_ci ep->enabled = 1; 146562306a36Sopenharmony_ci} 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_ci/** 146862306a36Sopenharmony_ci * usb_enable_interface - Enable all the endpoints for an interface 146962306a36Sopenharmony_ci * @dev: the device whose interface is being enabled 147062306a36Sopenharmony_ci * @intf: pointer to the interface descriptor 147162306a36Sopenharmony_ci * @reset_eps: flag to reset the endpoints' state 147262306a36Sopenharmony_ci * 147362306a36Sopenharmony_ci * Enables all the endpoints for the interface's current altsetting. 147462306a36Sopenharmony_ci */ 147562306a36Sopenharmony_civoid usb_enable_interface(struct usb_device *dev, 147662306a36Sopenharmony_ci struct usb_interface *intf, bool reset_eps) 147762306a36Sopenharmony_ci{ 147862306a36Sopenharmony_ci struct usb_host_interface *alt = intf->cur_altsetting; 147962306a36Sopenharmony_ci int i; 148062306a36Sopenharmony_ci 148162306a36Sopenharmony_ci for (i = 0; i < alt->desc.bNumEndpoints; ++i) 148262306a36Sopenharmony_ci usb_enable_endpoint(dev, &alt->endpoint[i], reset_eps); 148362306a36Sopenharmony_ci} 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci/** 148662306a36Sopenharmony_ci * usb_set_interface - Makes a particular alternate setting be current 148762306a36Sopenharmony_ci * @dev: the device whose interface is being updated 148862306a36Sopenharmony_ci * @interface: the interface being updated 148962306a36Sopenharmony_ci * @alternate: the setting being chosen. 149062306a36Sopenharmony_ci * 149162306a36Sopenharmony_ci * Context: task context, might sleep. 149262306a36Sopenharmony_ci * 149362306a36Sopenharmony_ci * This is used to enable data transfers on interfaces that may not 149462306a36Sopenharmony_ci * be enabled by default. Not all devices support such configurability. 149562306a36Sopenharmony_ci * Only the driver bound to an interface may change its setting. 149662306a36Sopenharmony_ci * 149762306a36Sopenharmony_ci * Within any given configuration, each interface may have several 149862306a36Sopenharmony_ci * alternative settings. These are often used to control levels of 149962306a36Sopenharmony_ci * bandwidth consumption. For example, the default setting for a high 150062306a36Sopenharmony_ci * speed interrupt endpoint may not send more than 64 bytes per microframe, 150162306a36Sopenharmony_ci * while interrupt transfers of up to 3KBytes per microframe are legal. 150262306a36Sopenharmony_ci * Also, isochronous endpoints may never be part of an 150362306a36Sopenharmony_ci * interface's default setting. To access such bandwidth, alternate 150462306a36Sopenharmony_ci * interface settings must be made current. 150562306a36Sopenharmony_ci * 150662306a36Sopenharmony_ci * Note that in the Linux USB subsystem, bandwidth associated with 150762306a36Sopenharmony_ci * an endpoint in a given alternate setting is not reserved until an URB 150862306a36Sopenharmony_ci * is submitted that needs that bandwidth. Some other operating systems 150962306a36Sopenharmony_ci * allocate bandwidth early, when a configuration is chosen. 151062306a36Sopenharmony_ci * 151162306a36Sopenharmony_ci * xHCI reserves bandwidth and configures the alternate setting in 151262306a36Sopenharmony_ci * usb_hcd_alloc_bandwidth(). If it fails the original interface altsetting 151362306a36Sopenharmony_ci * may be disabled. Drivers cannot rely on any particular alternate 151462306a36Sopenharmony_ci * setting being in effect after a failure. 151562306a36Sopenharmony_ci * 151662306a36Sopenharmony_ci * This call is synchronous, and may not be used in an interrupt context. 151762306a36Sopenharmony_ci * Also, drivers must not change altsettings while urbs are scheduled for 151862306a36Sopenharmony_ci * endpoints in that interface; all such urbs must first be completed 151962306a36Sopenharmony_ci * (perhaps forced by unlinking). 152062306a36Sopenharmony_ci * 152162306a36Sopenharmony_ci * Return: Zero on success, or else the status code returned by the 152262306a36Sopenharmony_ci * underlying usb_control_msg() call. 152362306a36Sopenharmony_ci */ 152462306a36Sopenharmony_ciint usb_set_interface(struct usb_device *dev, int interface, int alternate) 152562306a36Sopenharmony_ci{ 152662306a36Sopenharmony_ci struct usb_interface *iface; 152762306a36Sopenharmony_ci struct usb_host_interface *alt; 152862306a36Sopenharmony_ci struct usb_hcd *hcd = bus_to_hcd(dev->bus); 152962306a36Sopenharmony_ci int i, ret, manual = 0; 153062306a36Sopenharmony_ci unsigned int epaddr; 153162306a36Sopenharmony_ci unsigned int pipe; 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_ci if (dev->state == USB_STATE_SUSPENDED) 153462306a36Sopenharmony_ci return -EHOSTUNREACH; 153562306a36Sopenharmony_ci 153662306a36Sopenharmony_ci iface = usb_ifnum_to_if(dev, interface); 153762306a36Sopenharmony_ci if (!iface) { 153862306a36Sopenharmony_ci dev_dbg(&dev->dev, "selecting invalid interface %d\n", 153962306a36Sopenharmony_ci interface); 154062306a36Sopenharmony_ci return -EINVAL; 154162306a36Sopenharmony_ci } 154262306a36Sopenharmony_ci if (iface->unregistering) 154362306a36Sopenharmony_ci return -ENODEV; 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci alt = usb_altnum_to_altsetting(iface, alternate); 154662306a36Sopenharmony_ci if (!alt) { 154762306a36Sopenharmony_ci dev_warn(&dev->dev, "selecting invalid altsetting %d\n", 154862306a36Sopenharmony_ci alternate); 154962306a36Sopenharmony_ci return -EINVAL; 155062306a36Sopenharmony_ci } 155162306a36Sopenharmony_ci /* 155262306a36Sopenharmony_ci * usb3 hosts configure the interface in usb_hcd_alloc_bandwidth, 155362306a36Sopenharmony_ci * including freeing dropped endpoint ring buffers. 155462306a36Sopenharmony_ci * Make sure the interface endpoints are flushed before that 155562306a36Sopenharmony_ci */ 155662306a36Sopenharmony_ci usb_disable_interface(dev, iface, false); 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_ci /* Make sure we have enough bandwidth for this alternate interface. 155962306a36Sopenharmony_ci * Remove the current alt setting and add the new alt setting. 156062306a36Sopenharmony_ci */ 156162306a36Sopenharmony_ci mutex_lock(hcd->bandwidth_mutex); 156262306a36Sopenharmony_ci /* Disable LPM, and re-enable it once the new alt setting is installed, 156362306a36Sopenharmony_ci * so that the xHCI driver can recalculate the U1/U2 timeouts. 156462306a36Sopenharmony_ci */ 156562306a36Sopenharmony_ci if (usb_disable_lpm(dev)) { 156662306a36Sopenharmony_ci dev_err(&iface->dev, "%s Failed to disable LPM\n", __func__); 156762306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 156862306a36Sopenharmony_ci return -ENOMEM; 156962306a36Sopenharmony_ci } 157062306a36Sopenharmony_ci /* Changing alt-setting also frees any allocated streams */ 157162306a36Sopenharmony_ci for (i = 0; i < iface->cur_altsetting->desc.bNumEndpoints; i++) 157262306a36Sopenharmony_ci iface->cur_altsetting->endpoint[i].streams = 0; 157362306a36Sopenharmony_ci 157462306a36Sopenharmony_ci ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt); 157562306a36Sopenharmony_ci if (ret < 0) { 157662306a36Sopenharmony_ci dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n", 157762306a36Sopenharmony_ci alternate); 157862306a36Sopenharmony_ci usb_enable_lpm(dev); 157962306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 158062306a36Sopenharmony_ci return ret; 158162306a36Sopenharmony_ci } 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_ci if (dev->quirks & USB_QUIRK_NO_SET_INTF) 158462306a36Sopenharmony_ci ret = -EPIPE; 158562306a36Sopenharmony_ci else 158662306a36Sopenharmony_ci ret = usb_control_msg_send(dev, 0, 158762306a36Sopenharmony_ci USB_REQ_SET_INTERFACE, 158862306a36Sopenharmony_ci USB_RECIP_INTERFACE, alternate, 158962306a36Sopenharmony_ci interface, NULL, 0, 5000, 159062306a36Sopenharmony_ci GFP_NOIO); 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_ci /* 9.4.10 says devices don't need this and are free to STALL the 159362306a36Sopenharmony_ci * request if the interface only has one alternate setting. 159462306a36Sopenharmony_ci */ 159562306a36Sopenharmony_ci if (ret == -EPIPE && iface->num_altsetting == 1) { 159662306a36Sopenharmony_ci dev_dbg(&dev->dev, 159762306a36Sopenharmony_ci "manual set_interface for iface %d, alt %d\n", 159862306a36Sopenharmony_ci interface, alternate); 159962306a36Sopenharmony_ci manual = 1; 160062306a36Sopenharmony_ci } else if (ret) { 160162306a36Sopenharmony_ci /* Re-instate the old alt setting */ 160262306a36Sopenharmony_ci usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting); 160362306a36Sopenharmony_ci usb_enable_lpm(dev); 160462306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 160562306a36Sopenharmony_ci return ret; 160662306a36Sopenharmony_ci } 160762306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 160862306a36Sopenharmony_ci 160962306a36Sopenharmony_ci /* FIXME drivers shouldn't need to replicate/bugfix the logic here 161062306a36Sopenharmony_ci * when they implement async or easily-killable versions of this or 161162306a36Sopenharmony_ci * other "should-be-internal" functions (like clear_halt). 161262306a36Sopenharmony_ci * should hcd+usbcore postprocess control requests? 161362306a36Sopenharmony_ci */ 161462306a36Sopenharmony_ci 161562306a36Sopenharmony_ci /* prevent submissions using previous endpoint settings */ 161662306a36Sopenharmony_ci if (iface->cur_altsetting != alt) { 161762306a36Sopenharmony_ci remove_intf_ep_devs(iface); 161862306a36Sopenharmony_ci usb_remove_sysfs_intf_files(iface); 161962306a36Sopenharmony_ci } 162062306a36Sopenharmony_ci usb_disable_interface(dev, iface, true); 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci iface->cur_altsetting = alt; 162362306a36Sopenharmony_ci 162462306a36Sopenharmony_ci /* Now that the interface is installed, re-enable LPM. */ 162562306a36Sopenharmony_ci usb_unlocked_enable_lpm(dev); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci /* If the interface only has one altsetting and the device didn't 162862306a36Sopenharmony_ci * accept the request, we attempt to carry out the equivalent action 162962306a36Sopenharmony_ci * by manually clearing the HALT feature for each endpoint in the 163062306a36Sopenharmony_ci * new altsetting. 163162306a36Sopenharmony_ci */ 163262306a36Sopenharmony_ci if (manual) { 163362306a36Sopenharmony_ci for (i = 0; i < alt->desc.bNumEndpoints; i++) { 163462306a36Sopenharmony_ci epaddr = alt->endpoint[i].desc.bEndpointAddress; 163562306a36Sopenharmony_ci pipe = __create_pipe(dev, 163662306a36Sopenharmony_ci USB_ENDPOINT_NUMBER_MASK & epaddr) | 163762306a36Sopenharmony_ci (usb_endpoint_out(epaddr) ? 163862306a36Sopenharmony_ci USB_DIR_OUT : USB_DIR_IN); 163962306a36Sopenharmony_ci 164062306a36Sopenharmony_ci usb_clear_halt(dev, pipe); 164162306a36Sopenharmony_ci } 164262306a36Sopenharmony_ci } 164362306a36Sopenharmony_ci 164462306a36Sopenharmony_ci /* 9.1.1.5: reset toggles for all endpoints in the new altsetting 164562306a36Sopenharmony_ci * 164662306a36Sopenharmony_ci * Note: 164762306a36Sopenharmony_ci * Despite EP0 is always present in all interfaces/AS, the list of 164862306a36Sopenharmony_ci * endpoints from the descriptor does not contain EP0. Due to its 164962306a36Sopenharmony_ci * omnipresence one might expect EP0 being considered "affected" by 165062306a36Sopenharmony_ci * any SetInterface request and hence assume toggles need to be reset. 165162306a36Sopenharmony_ci * However, EP0 toggles are re-synced for every individual transfer 165262306a36Sopenharmony_ci * during the SETUP stage - hence EP0 toggles are "don't care" here. 165362306a36Sopenharmony_ci * (Likewise, EP0 never "halts" on well designed devices.) 165462306a36Sopenharmony_ci */ 165562306a36Sopenharmony_ci usb_enable_interface(dev, iface, true); 165662306a36Sopenharmony_ci if (device_is_registered(&iface->dev)) { 165762306a36Sopenharmony_ci usb_create_sysfs_intf_files(iface); 165862306a36Sopenharmony_ci create_intf_ep_devs(iface); 165962306a36Sopenharmony_ci } 166062306a36Sopenharmony_ci return 0; 166162306a36Sopenharmony_ci} 166262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_set_interface); 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci/** 166562306a36Sopenharmony_ci * usb_reset_configuration - lightweight device reset 166662306a36Sopenharmony_ci * @dev: the device whose configuration is being reset 166762306a36Sopenharmony_ci * 166862306a36Sopenharmony_ci * This issues a standard SET_CONFIGURATION request to the device using 166962306a36Sopenharmony_ci * the current configuration. The effect is to reset most USB-related 167062306a36Sopenharmony_ci * state in the device, including interface altsettings (reset to zero), 167162306a36Sopenharmony_ci * endpoint halts (cleared), and endpoint state (only for bulk and interrupt 167262306a36Sopenharmony_ci * endpoints). Other usbcore state is unchanged, including bindings of 167362306a36Sopenharmony_ci * usb device drivers to interfaces. 167462306a36Sopenharmony_ci * 167562306a36Sopenharmony_ci * Because this affects multiple interfaces, avoid using this with composite 167662306a36Sopenharmony_ci * (multi-interface) devices. Instead, the driver for each interface may 167762306a36Sopenharmony_ci * use usb_set_interface() on the interfaces it claims. Be careful though; 167862306a36Sopenharmony_ci * some devices don't support the SET_INTERFACE request, and others won't 167962306a36Sopenharmony_ci * reset all the interface state (notably endpoint state). Resetting the whole 168062306a36Sopenharmony_ci * configuration would affect other drivers' interfaces. 168162306a36Sopenharmony_ci * 168262306a36Sopenharmony_ci * The caller must own the device lock. 168362306a36Sopenharmony_ci * 168462306a36Sopenharmony_ci * Return: Zero on success, else a negative error code. 168562306a36Sopenharmony_ci * 168662306a36Sopenharmony_ci * If this routine fails the device will probably be in an unusable state 168762306a36Sopenharmony_ci * with endpoints disabled, and interfaces only partially enabled. 168862306a36Sopenharmony_ci */ 168962306a36Sopenharmony_ciint usb_reset_configuration(struct usb_device *dev) 169062306a36Sopenharmony_ci{ 169162306a36Sopenharmony_ci int i, retval; 169262306a36Sopenharmony_ci struct usb_host_config *config; 169362306a36Sopenharmony_ci struct usb_hcd *hcd = bus_to_hcd(dev->bus); 169462306a36Sopenharmony_ci 169562306a36Sopenharmony_ci if (dev->state == USB_STATE_SUSPENDED) 169662306a36Sopenharmony_ci return -EHOSTUNREACH; 169762306a36Sopenharmony_ci 169862306a36Sopenharmony_ci /* caller must have locked the device and must own 169962306a36Sopenharmony_ci * the usb bus readlock (so driver bindings are stable); 170062306a36Sopenharmony_ci * calls during probe() are fine 170162306a36Sopenharmony_ci */ 170262306a36Sopenharmony_ci 170362306a36Sopenharmony_ci usb_disable_device_endpoints(dev, 1); /* skip ep0*/ 170462306a36Sopenharmony_ci 170562306a36Sopenharmony_ci config = dev->actconfig; 170662306a36Sopenharmony_ci retval = 0; 170762306a36Sopenharmony_ci mutex_lock(hcd->bandwidth_mutex); 170862306a36Sopenharmony_ci /* Disable LPM, and re-enable it once the configuration is reset, so 170962306a36Sopenharmony_ci * that the xHCI driver can recalculate the U1/U2 timeouts. 171062306a36Sopenharmony_ci */ 171162306a36Sopenharmony_ci if (usb_disable_lpm(dev)) { 171262306a36Sopenharmony_ci dev_err(&dev->dev, "%s Failed to disable LPM\n", __func__); 171362306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 171462306a36Sopenharmony_ci return -ENOMEM; 171562306a36Sopenharmony_ci } 171662306a36Sopenharmony_ci 171762306a36Sopenharmony_ci /* xHCI adds all endpoints in usb_hcd_alloc_bandwidth */ 171862306a36Sopenharmony_ci retval = usb_hcd_alloc_bandwidth(dev, config, NULL, NULL); 171962306a36Sopenharmony_ci if (retval < 0) { 172062306a36Sopenharmony_ci usb_enable_lpm(dev); 172162306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 172262306a36Sopenharmony_ci return retval; 172362306a36Sopenharmony_ci } 172462306a36Sopenharmony_ci retval = usb_control_msg_send(dev, 0, USB_REQ_SET_CONFIGURATION, 0, 172562306a36Sopenharmony_ci config->desc.bConfigurationValue, 0, 172662306a36Sopenharmony_ci NULL, 0, USB_CTRL_SET_TIMEOUT, 172762306a36Sopenharmony_ci GFP_NOIO); 172862306a36Sopenharmony_ci if (retval) { 172962306a36Sopenharmony_ci usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); 173062306a36Sopenharmony_ci usb_enable_lpm(dev); 173162306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 173262306a36Sopenharmony_ci return retval; 173362306a36Sopenharmony_ci } 173462306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci /* re-init hc/hcd interface/endpoint state */ 173762306a36Sopenharmony_ci for (i = 0; i < config->desc.bNumInterfaces; i++) { 173862306a36Sopenharmony_ci struct usb_interface *intf = config->interface[i]; 173962306a36Sopenharmony_ci struct usb_host_interface *alt; 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci alt = usb_altnum_to_altsetting(intf, 0); 174262306a36Sopenharmony_ci 174362306a36Sopenharmony_ci /* No altsetting 0? We'll assume the first altsetting. 174462306a36Sopenharmony_ci * We could use a GetInterface call, but if a device is 174562306a36Sopenharmony_ci * so non-compliant that it doesn't have altsetting 0 174662306a36Sopenharmony_ci * then I wouldn't trust its reply anyway. 174762306a36Sopenharmony_ci */ 174862306a36Sopenharmony_ci if (!alt) 174962306a36Sopenharmony_ci alt = &intf->altsetting[0]; 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci if (alt != intf->cur_altsetting) { 175262306a36Sopenharmony_ci remove_intf_ep_devs(intf); 175362306a36Sopenharmony_ci usb_remove_sysfs_intf_files(intf); 175462306a36Sopenharmony_ci } 175562306a36Sopenharmony_ci intf->cur_altsetting = alt; 175662306a36Sopenharmony_ci usb_enable_interface(dev, intf, true); 175762306a36Sopenharmony_ci if (device_is_registered(&intf->dev)) { 175862306a36Sopenharmony_ci usb_create_sysfs_intf_files(intf); 175962306a36Sopenharmony_ci create_intf_ep_devs(intf); 176062306a36Sopenharmony_ci } 176162306a36Sopenharmony_ci } 176262306a36Sopenharmony_ci /* Now that the interfaces are installed, re-enable LPM. */ 176362306a36Sopenharmony_ci usb_unlocked_enable_lpm(dev); 176462306a36Sopenharmony_ci return 0; 176562306a36Sopenharmony_ci} 176662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_reset_configuration); 176762306a36Sopenharmony_ci 176862306a36Sopenharmony_cistatic void usb_release_interface(struct device *dev) 176962306a36Sopenharmony_ci{ 177062306a36Sopenharmony_ci struct usb_interface *intf = to_usb_interface(dev); 177162306a36Sopenharmony_ci struct usb_interface_cache *intfc = 177262306a36Sopenharmony_ci altsetting_to_usb_interface_cache(intf->altsetting); 177362306a36Sopenharmony_ci 177462306a36Sopenharmony_ci kref_put(&intfc->ref, usb_release_interface_cache); 177562306a36Sopenharmony_ci usb_put_dev(interface_to_usbdev(intf)); 177662306a36Sopenharmony_ci of_node_put(dev->of_node); 177762306a36Sopenharmony_ci kfree(intf); 177862306a36Sopenharmony_ci} 177962306a36Sopenharmony_ci 178062306a36Sopenharmony_ci/* 178162306a36Sopenharmony_ci * usb_deauthorize_interface - deauthorize an USB interface 178262306a36Sopenharmony_ci * 178362306a36Sopenharmony_ci * @intf: USB interface structure 178462306a36Sopenharmony_ci */ 178562306a36Sopenharmony_civoid usb_deauthorize_interface(struct usb_interface *intf) 178662306a36Sopenharmony_ci{ 178762306a36Sopenharmony_ci struct device *dev = &intf->dev; 178862306a36Sopenharmony_ci 178962306a36Sopenharmony_ci device_lock(dev->parent); 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci if (intf->authorized) { 179262306a36Sopenharmony_ci device_lock(dev); 179362306a36Sopenharmony_ci intf->authorized = 0; 179462306a36Sopenharmony_ci device_unlock(dev); 179562306a36Sopenharmony_ci 179662306a36Sopenharmony_ci usb_forced_unbind_intf(intf); 179762306a36Sopenharmony_ci } 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci device_unlock(dev->parent); 180062306a36Sopenharmony_ci} 180162306a36Sopenharmony_ci 180262306a36Sopenharmony_ci/* 180362306a36Sopenharmony_ci * usb_authorize_interface - authorize an USB interface 180462306a36Sopenharmony_ci * 180562306a36Sopenharmony_ci * @intf: USB interface structure 180662306a36Sopenharmony_ci */ 180762306a36Sopenharmony_civoid usb_authorize_interface(struct usb_interface *intf) 180862306a36Sopenharmony_ci{ 180962306a36Sopenharmony_ci struct device *dev = &intf->dev; 181062306a36Sopenharmony_ci 181162306a36Sopenharmony_ci if (!intf->authorized) { 181262306a36Sopenharmony_ci device_lock(dev); 181362306a36Sopenharmony_ci intf->authorized = 1; /* authorize interface */ 181462306a36Sopenharmony_ci device_unlock(dev); 181562306a36Sopenharmony_ci } 181662306a36Sopenharmony_ci} 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_cistatic int usb_if_uevent(const struct device *dev, struct kobj_uevent_env *env) 181962306a36Sopenharmony_ci{ 182062306a36Sopenharmony_ci const struct usb_device *usb_dev; 182162306a36Sopenharmony_ci const struct usb_interface *intf; 182262306a36Sopenharmony_ci const struct usb_host_interface *alt; 182362306a36Sopenharmony_ci 182462306a36Sopenharmony_ci intf = to_usb_interface(dev); 182562306a36Sopenharmony_ci usb_dev = interface_to_usbdev(intf); 182662306a36Sopenharmony_ci alt = intf->cur_altsetting; 182762306a36Sopenharmony_ci 182862306a36Sopenharmony_ci if (add_uevent_var(env, "INTERFACE=%d/%d/%d", 182962306a36Sopenharmony_ci alt->desc.bInterfaceClass, 183062306a36Sopenharmony_ci alt->desc.bInterfaceSubClass, 183162306a36Sopenharmony_ci alt->desc.bInterfaceProtocol)) 183262306a36Sopenharmony_ci return -ENOMEM; 183362306a36Sopenharmony_ci 183462306a36Sopenharmony_ci if (add_uevent_var(env, 183562306a36Sopenharmony_ci "MODALIAS=usb:" 183662306a36Sopenharmony_ci "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X", 183762306a36Sopenharmony_ci le16_to_cpu(usb_dev->descriptor.idVendor), 183862306a36Sopenharmony_ci le16_to_cpu(usb_dev->descriptor.idProduct), 183962306a36Sopenharmony_ci le16_to_cpu(usb_dev->descriptor.bcdDevice), 184062306a36Sopenharmony_ci usb_dev->descriptor.bDeviceClass, 184162306a36Sopenharmony_ci usb_dev->descriptor.bDeviceSubClass, 184262306a36Sopenharmony_ci usb_dev->descriptor.bDeviceProtocol, 184362306a36Sopenharmony_ci alt->desc.bInterfaceClass, 184462306a36Sopenharmony_ci alt->desc.bInterfaceSubClass, 184562306a36Sopenharmony_ci alt->desc.bInterfaceProtocol, 184662306a36Sopenharmony_ci alt->desc.bInterfaceNumber)) 184762306a36Sopenharmony_ci return -ENOMEM; 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_ci return 0; 185062306a36Sopenharmony_ci} 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_cistruct device_type usb_if_device_type = { 185362306a36Sopenharmony_ci .name = "usb_interface", 185462306a36Sopenharmony_ci .release = usb_release_interface, 185562306a36Sopenharmony_ci .uevent = usb_if_uevent, 185662306a36Sopenharmony_ci}; 185762306a36Sopenharmony_ci 185862306a36Sopenharmony_cistatic struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, 185962306a36Sopenharmony_ci struct usb_host_config *config, 186062306a36Sopenharmony_ci u8 inum) 186162306a36Sopenharmony_ci{ 186262306a36Sopenharmony_ci struct usb_interface_assoc_descriptor *retval = NULL; 186362306a36Sopenharmony_ci struct usb_interface_assoc_descriptor *intf_assoc; 186462306a36Sopenharmony_ci int first_intf; 186562306a36Sopenharmony_ci int last_intf; 186662306a36Sopenharmony_ci int i; 186762306a36Sopenharmony_ci 186862306a36Sopenharmony_ci for (i = 0; (i < USB_MAXIADS && config->intf_assoc[i]); i++) { 186962306a36Sopenharmony_ci intf_assoc = config->intf_assoc[i]; 187062306a36Sopenharmony_ci if (intf_assoc->bInterfaceCount == 0) 187162306a36Sopenharmony_ci continue; 187262306a36Sopenharmony_ci 187362306a36Sopenharmony_ci first_intf = intf_assoc->bFirstInterface; 187462306a36Sopenharmony_ci last_intf = first_intf + (intf_assoc->bInterfaceCount - 1); 187562306a36Sopenharmony_ci if (inum >= first_intf && inum <= last_intf) { 187662306a36Sopenharmony_ci if (!retval) 187762306a36Sopenharmony_ci retval = intf_assoc; 187862306a36Sopenharmony_ci else 187962306a36Sopenharmony_ci dev_err(&dev->dev, "Interface #%d referenced" 188062306a36Sopenharmony_ci " by multiple IADs\n", inum); 188162306a36Sopenharmony_ci } 188262306a36Sopenharmony_ci } 188362306a36Sopenharmony_ci 188462306a36Sopenharmony_ci return retval; 188562306a36Sopenharmony_ci} 188662306a36Sopenharmony_ci 188762306a36Sopenharmony_ci 188862306a36Sopenharmony_ci/* 188962306a36Sopenharmony_ci * Internal function to queue a device reset 189062306a36Sopenharmony_ci * See usb_queue_reset_device() for more details 189162306a36Sopenharmony_ci */ 189262306a36Sopenharmony_cistatic void __usb_queue_reset_device(struct work_struct *ws) 189362306a36Sopenharmony_ci{ 189462306a36Sopenharmony_ci int rc; 189562306a36Sopenharmony_ci struct usb_interface *iface = 189662306a36Sopenharmony_ci container_of(ws, struct usb_interface, reset_ws); 189762306a36Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(iface); 189862306a36Sopenharmony_ci 189962306a36Sopenharmony_ci rc = usb_lock_device_for_reset(udev, iface); 190062306a36Sopenharmony_ci if (rc >= 0) { 190162306a36Sopenharmony_ci usb_reset_device(udev); 190262306a36Sopenharmony_ci usb_unlock_device(udev); 190362306a36Sopenharmony_ci } 190462306a36Sopenharmony_ci usb_put_intf(iface); /* Undo _get_ in usb_queue_reset_device() */ 190562306a36Sopenharmony_ci} 190662306a36Sopenharmony_ci 190762306a36Sopenharmony_ci/* 190862306a36Sopenharmony_ci * Internal function to set the wireless_status sysfs attribute 190962306a36Sopenharmony_ci * See usb_set_wireless_status() for more details 191062306a36Sopenharmony_ci */ 191162306a36Sopenharmony_cistatic void __usb_wireless_status_intf(struct work_struct *ws) 191262306a36Sopenharmony_ci{ 191362306a36Sopenharmony_ci struct usb_interface *iface = 191462306a36Sopenharmony_ci container_of(ws, struct usb_interface, wireless_status_work); 191562306a36Sopenharmony_ci 191662306a36Sopenharmony_ci device_lock(iface->dev.parent); 191762306a36Sopenharmony_ci if (iface->sysfs_files_created) 191862306a36Sopenharmony_ci usb_update_wireless_status_attr(iface); 191962306a36Sopenharmony_ci device_unlock(iface->dev.parent); 192062306a36Sopenharmony_ci usb_put_intf(iface); /* Undo _get_ in usb_set_wireless_status() */ 192162306a36Sopenharmony_ci} 192262306a36Sopenharmony_ci 192362306a36Sopenharmony_ci/** 192462306a36Sopenharmony_ci * usb_set_wireless_status - sets the wireless_status struct member 192562306a36Sopenharmony_ci * @iface: the interface to modify 192662306a36Sopenharmony_ci * @status: the new wireless status 192762306a36Sopenharmony_ci * 192862306a36Sopenharmony_ci * Set the wireless_status struct member to the new value, and emit 192962306a36Sopenharmony_ci * sysfs changes as necessary. 193062306a36Sopenharmony_ci * 193162306a36Sopenharmony_ci * Returns: 0 on success, -EALREADY if already set. 193262306a36Sopenharmony_ci */ 193362306a36Sopenharmony_ciint usb_set_wireless_status(struct usb_interface *iface, 193462306a36Sopenharmony_ci enum usb_wireless_status status) 193562306a36Sopenharmony_ci{ 193662306a36Sopenharmony_ci if (iface->wireless_status == status) 193762306a36Sopenharmony_ci return -EALREADY; 193862306a36Sopenharmony_ci 193962306a36Sopenharmony_ci usb_get_intf(iface); 194062306a36Sopenharmony_ci iface->wireless_status = status; 194162306a36Sopenharmony_ci schedule_work(&iface->wireless_status_work); 194262306a36Sopenharmony_ci 194362306a36Sopenharmony_ci return 0; 194462306a36Sopenharmony_ci} 194562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_set_wireless_status); 194662306a36Sopenharmony_ci 194762306a36Sopenharmony_ci/* 194862306a36Sopenharmony_ci * usb_set_configuration - Makes a particular device setting be current 194962306a36Sopenharmony_ci * @dev: the device whose configuration is being updated 195062306a36Sopenharmony_ci * @configuration: the configuration being chosen. 195162306a36Sopenharmony_ci * 195262306a36Sopenharmony_ci * Context: task context, might sleep. Caller holds device lock. 195362306a36Sopenharmony_ci * 195462306a36Sopenharmony_ci * This is used to enable non-default device modes. Not all devices 195562306a36Sopenharmony_ci * use this kind of configurability; many devices only have one 195662306a36Sopenharmony_ci * configuration. 195762306a36Sopenharmony_ci * 195862306a36Sopenharmony_ci * @configuration is the value of the configuration to be installed. 195962306a36Sopenharmony_ci * According to the USB spec (e.g. section 9.1.1.5), configuration values 196062306a36Sopenharmony_ci * must be non-zero; a value of zero indicates that the device in 196162306a36Sopenharmony_ci * unconfigured. However some devices erroneously use 0 as one of their 196262306a36Sopenharmony_ci * configuration values. To help manage such devices, this routine will 196362306a36Sopenharmony_ci * accept @configuration = -1 as indicating the device should be put in 196462306a36Sopenharmony_ci * an unconfigured state. 196562306a36Sopenharmony_ci * 196662306a36Sopenharmony_ci * USB device configurations may affect Linux interoperability, 196762306a36Sopenharmony_ci * power consumption and the functionality available. For example, 196862306a36Sopenharmony_ci * the default configuration is limited to using 100mA of bus power, 196962306a36Sopenharmony_ci * so that when certain device functionality requires more power, 197062306a36Sopenharmony_ci * and the device is bus powered, that functionality should be in some 197162306a36Sopenharmony_ci * non-default device configuration. Other device modes may also be 197262306a36Sopenharmony_ci * reflected as configuration options, such as whether two ISDN 197362306a36Sopenharmony_ci * channels are available independently; and choosing between open 197462306a36Sopenharmony_ci * standard device protocols (like CDC) or proprietary ones. 197562306a36Sopenharmony_ci * 197662306a36Sopenharmony_ci * Note that a non-authorized device (dev->authorized == 0) will only 197762306a36Sopenharmony_ci * be put in unconfigured mode. 197862306a36Sopenharmony_ci * 197962306a36Sopenharmony_ci * Note that USB has an additional level of device configurability, 198062306a36Sopenharmony_ci * associated with interfaces. That configurability is accessed using 198162306a36Sopenharmony_ci * usb_set_interface(). 198262306a36Sopenharmony_ci * 198362306a36Sopenharmony_ci * This call is synchronous. The calling context must be able to sleep, 198462306a36Sopenharmony_ci * must own the device lock, and must not hold the driver model's USB 198562306a36Sopenharmony_ci * bus mutex; usb interface driver probe() methods cannot use this routine. 198662306a36Sopenharmony_ci * 198762306a36Sopenharmony_ci * Returns zero on success, or else the status code returned by the 198862306a36Sopenharmony_ci * underlying call that failed. On successful completion, each interface 198962306a36Sopenharmony_ci * in the original device configuration has been destroyed, and each one 199062306a36Sopenharmony_ci * in the new configuration has been probed by all relevant usb device 199162306a36Sopenharmony_ci * drivers currently known to the kernel. 199262306a36Sopenharmony_ci */ 199362306a36Sopenharmony_ciint usb_set_configuration(struct usb_device *dev, int configuration) 199462306a36Sopenharmony_ci{ 199562306a36Sopenharmony_ci int i, ret; 199662306a36Sopenharmony_ci struct usb_host_config *cp = NULL; 199762306a36Sopenharmony_ci struct usb_interface **new_interfaces = NULL; 199862306a36Sopenharmony_ci struct usb_hcd *hcd = bus_to_hcd(dev->bus); 199962306a36Sopenharmony_ci int n, nintf; 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_ci if (dev->authorized == 0 || configuration == -1) 200262306a36Sopenharmony_ci configuration = 0; 200362306a36Sopenharmony_ci else { 200462306a36Sopenharmony_ci for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { 200562306a36Sopenharmony_ci if (dev->config[i].desc.bConfigurationValue == 200662306a36Sopenharmony_ci configuration) { 200762306a36Sopenharmony_ci cp = &dev->config[i]; 200862306a36Sopenharmony_ci break; 200962306a36Sopenharmony_ci } 201062306a36Sopenharmony_ci } 201162306a36Sopenharmony_ci } 201262306a36Sopenharmony_ci if ((!cp && configuration != 0)) 201362306a36Sopenharmony_ci return -EINVAL; 201462306a36Sopenharmony_ci 201562306a36Sopenharmony_ci /* The USB spec says configuration 0 means unconfigured. 201662306a36Sopenharmony_ci * But if a device includes a configuration numbered 0, 201762306a36Sopenharmony_ci * we will accept it as a correctly configured state. 201862306a36Sopenharmony_ci * Use -1 if you really want to unconfigure the device. 201962306a36Sopenharmony_ci */ 202062306a36Sopenharmony_ci if (cp && configuration == 0) 202162306a36Sopenharmony_ci dev_warn(&dev->dev, "config 0 descriptor??\n"); 202262306a36Sopenharmony_ci 202362306a36Sopenharmony_ci /* Allocate memory for new interfaces before doing anything else, 202462306a36Sopenharmony_ci * so that if we run out then nothing will have changed. */ 202562306a36Sopenharmony_ci n = nintf = 0; 202662306a36Sopenharmony_ci if (cp) { 202762306a36Sopenharmony_ci nintf = cp->desc.bNumInterfaces; 202862306a36Sopenharmony_ci new_interfaces = kmalloc_array(nintf, sizeof(*new_interfaces), 202962306a36Sopenharmony_ci GFP_NOIO); 203062306a36Sopenharmony_ci if (!new_interfaces) 203162306a36Sopenharmony_ci return -ENOMEM; 203262306a36Sopenharmony_ci 203362306a36Sopenharmony_ci for (; n < nintf; ++n) { 203462306a36Sopenharmony_ci new_interfaces[n] = kzalloc( 203562306a36Sopenharmony_ci sizeof(struct usb_interface), 203662306a36Sopenharmony_ci GFP_NOIO); 203762306a36Sopenharmony_ci if (!new_interfaces[n]) { 203862306a36Sopenharmony_ci ret = -ENOMEM; 203962306a36Sopenharmony_cifree_interfaces: 204062306a36Sopenharmony_ci while (--n >= 0) 204162306a36Sopenharmony_ci kfree(new_interfaces[n]); 204262306a36Sopenharmony_ci kfree(new_interfaces); 204362306a36Sopenharmony_ci return ret; 204462306a36Sopenharmony_ci } 204562306a36Sopenharmony_ci } 204662306a36Sopenharmony_ci 204762306a36Sopenharmony_ci i = dev->bus_mA - usb_get_max_power(dev, cp); 204862306a36Sopenharmony_ci if (i < 0) 204962306a36Sopenharmony_ci dev_warn(&dev->dev, "new config #%d exceeds power " 205062306a36Sopenharmony_ci "limit by %dmA\n", 205162306a36Sopenharmony_ci configuration, -i); 205262306a36Sopenharmony_ci } 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_ci /* Wake up the device so we can send it the Set-Config request */ 205562306a36Sopenharmony_ci ret = usb_autoresume_device(dev); 205662306a36Sopenharmony_ci if (ret) 205762306a36Sopenharmony_ci goto free_interfaces; 205862306a36Sopenharmony_ci 205962306a36Sopenharmony_ci /* if it's already configured, clear out old state first. 206062306a36Sopenharmony_ci * getting rid of old interfaces means unbinding their drivers. 206162306a36Sopenharmony_ci */ 206262306a36Sopenharmony_ci if (dev->state != USB_STATE_ADDRESS) 206362306a36Sopenharmony_ci usb_disable_device(dev, 1); /* Skip ep0 */ 206462306a36Sopenharmony_ci 206562306a36Sopenharmony_ci /* Get rid of pending async Set-Config requests for this device */ 206662306a36Sopenharmony_ci cancel_async_set_config(dev); 206762306a36Sopenharmony_ci 206862306a36Sopenharmony_ci /* Make sure we have bandwidth (and available HCD resources) for this 206962306a36Sopenharmony_ci * configuration. Remove endpoints from the schedule if we're dropping 207062306a36Sopenharmony_ci * this configuration to set configuration 0. After this point, the 207162306a36Sopenharmony_ci * host controller will not allow submissions to dropped endpoints. If 207262306a36Sopenharmony_ci * this call fails, the device state is unchanged. 207362306a36Sopenharmony_ci */ 207462306a36Sopenharmony_ci mutex_lock(hcd->bandwidth_mutex); 207562306a36Sopenharmony_ci /* Disable LPM, and re-enable it once the new configuration is 207662306a36Sopenharmony_ci * installed, so that the xHCI driver can recalculate the U1/U2 207762306a36Sopenharmony_ci * timeouts. 207862306a36Sopenharmony_ci */ 207962306a36Sopenharmony_ci if (dev->actconfig && usb_disable_lpm(dev)) { 208062306a36Sopenharmony_ci dev_err(&dev->dev, "%s Failed to disable LPM\n", __func__); 208162306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 208262306a36Sopenharmony_ci ret = -ENOMEM; 208362306a36Sopenharmony_ci goto free_interfaces; 208462306a36Sopenharmony_ci } 208562306a36Sopenharmony_ci ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); 208662306a36Sopenharmony_ci if (ret < 0) { 208762306a36Sopenharmony_ci if (dev->actconfig) 208862306a36Sopenharmony_ci usb_enable_lpm(dev); 208962306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 209062306a36Sopenharmony_ci usb_autosuspend_device(dev); 209162306a36Sopenharmony_ci goto free_interfaces; 209262306a36Sopenharmony_ci } 209362306a36Sopenharmony_ci 209462306a36Sopenharmony_ci /* 209562306a36Sopenharmony_ci * Initialize the new interface structures and the 209662306a36Sopenharmony_ci * hc/hcd/usbcore interface/endpoint state. 209762306a36Sopenharmony_ci */ 209862306a36Sopenharmony_ci for (i = 0; i < nintf; ++i) { 209962306a36Sopenharmony_ci struct usb_interface_cache *intfc; 210062306a36Sopenharmony_ci struct usb_interface *intf; 210162306a36Sopenharmony_ci struct usb_host_interface *alt; 210262306a36Sopenharmony_ci u8 ifnum; 210362306a36Sopenharmony_ci 210462306a36Sopenharmony_ci cp->interface[i] = intf = new_interfaces[i]; 210562306a36Sopenharmony_ci intfc = cp->intf_cache[i]; 210662306a36Sopenharmony_ci intf->altsetting = intfc->altsetting; 210762306a36Sopenharmony_ci intf->num_altsetting = intfc->num_altsetting; 210862306a36Sopenharmony_ci intf->authorized = !!HCD_INTF_AUTHORIZED(hcd); 210962306a36Sopenharmony_ci kref_get(&intfc->ref); 211062306a36Sopenharmony_ci 211162306a36Sopenharmony_ci alt = usb_altnum_to_altsetting(intf, 0); 211262306a36Sopenharmony_ci 211362306a36Sopenharmony_ci /* No altsetting 0? We'll assume the first altsetting. 211462306a36Sopenharmony_ci * We could use a GetInterface call, but if a device is 211562306a36Sopenharmony_ci * so non-compliant that it doesn't have altsetting 0 211662306a36Sopenharmony_ci * then I wouldn't trust its reply anyway. 211762306a36Sopenharmony_ci */ 211862306a36Sopenharmony_ci if (!alt) 211962306a36Sopenharmony_ci alt = &intf->altsetting[0]; 212062306a36Sopenharmony_ci 212162306a36Sopenharmony_ci ifnum = alt->desc.bInterfaceNumber; 212262306a36Sopenharmony_ci intf->intf_assoc = find_iad(dev, cp, ifnum); 212362306a36Sopenharmony_ci intf->cur_altsetting = alt; 212462306a36Sopenharmony_ci usb_enable_interface(dev, intf, true); 212562306a36Sopenharmony_ci intf->dev.parent = &dev->dev; 212662306a36Sopenharmony_ci if (usb_of_has_combined_node(dev)) { 212762306a36Sopenharmony_ci device_set_of_node_from_dev(&intf->dev, &dev->dev); 212862306a36Sopenharmony_ci } else { 212962306a36Sopenharmony_ci intf->dev.of_node = usb_of_get_interface_node(dev, 213062306a36Sopenharmony_ci configuration, ifnum); 213162306a36Sopenharmony_ci } 213262306a36Sopenharmony_ci ACPI_COMPANION_SET(&intf->dev, ACPI_COMPANION(&dev->dev)); 213362306a36Sopenharmony_ci intf->dev.driver = NULL; 213462306a36Sopenharmony_ci intf->dev.bus = &usb_bus_type; 213562306a36Sopenharmony_ci intf->dev.type = &usb_if_device_type; 213662306a36Sopenharmony_ci intf->dev.groups = usb_interface_groups; 213762306a36Sopenharmony_ci INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); 213862306a36Sopenharmony_ci INIT_WORK(&intf->wireless_status_work, __usb_wireless_status_intf); 213962306a36Sopenharmony_ci intf->minor = -1; 214062306a36Sopenharmony_ci device_initialize(&intf->dev); 214162306a36Sopenharmony_ci pm_runtime_no_callbacks(&intf->dev); 214262306a36Sopenharmony_ci dev_set_name(&intf->dev, "%d-%s:%d.%d", dev->bus->busnum, 214362306a36Sopenharmony_ci dev->devpath, configuration, ifnum); 214462306a36Sopenharmony_ci usb_get_dev(dev); 214562306a36Sopenharmony_ci } 214662306a36Sopenharmony_ci kfree(new_interfaces); 214762306a36Sopenharmony_ci 214862306a36Sopenharmony_ci ret = usb_control_msg_send(dev, 0, USB_REQ_SET_CONFIGURATION, 0, 214962306a36Sopenharmony_ci configuration, 0, NULL, 0, 215062306a36Sopenharmony_ci USB_CTRL_SET_TIMEOUT, GFP_NOIO); 215162306a36Sopenharmony_ci if (ret && cp) { 215262306a36Sopenharmony_ci /* 215362306a36Sopenharmony_ci * All the old state is gone, so what else can we do? 215462306a36Sopenharmony_ci * The device is probably useless now anyway. 215562306a36Sopenharmony_ci */ 215662306a36Sopenharmony_ci usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); 215762306a36Sopenharmony_ci for (i = 0; i < nintf; ++i) { 215862306a36Sopenharmony_ci usb_disable_interface(dev, cp->interface[i], true); 215962306a36Sopenharmony_ci put_device(&cp->interface[i]->dev); 216062306a36Sopenharmony_ci cp->interface[i] = NULL; 216162306a36Sopenharmony_ci } 216262306a36Sopenharmony_ci cp = NULL; 216362306a36Sopenharmony_ci } 216462306a36Sopenharmony_ci 216562306a36Sopenharmony_ci dev->actconfig = cp; 216662306a36Sopenharmony_ci mutex_unlock(hcd->bandwidth_mutex); 216762306a36Sopenharmony_ci 216862306a36Sopenharmony_ci if (!cp) { 216962306a36Sopenharmony_ci usb_set_device_state(dev, USB_STATE_ADDRESS); 217062306a36Sopenharmony_ci 217162306a36Sopenharmony_ci /* Leave LPM disabled while the device is unconfigured. */ 217262306a36Sopenharmony_ci usb_autosuspend_device(dev); 217362306a36Sopenharmony_ci return ret; 217462306a36Sopenharmony_ci } 217562306a36Sopenharmony_ci usb_set_device_state(dev, USB_STATE_CONFIGURED); 217662306a36Sopenharmony_ci 217762306a36Sopenharmony_ci if (cp->string == NULL && 217862306a36Sopenharmony_ci !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) 217962306a36Sopenharmony_ci cp->string = usb_cache_string(dev, cp->desc.iConfiguration); 218062306a36Sopenharmony_ci 218162306a36Sopenharmony_ci /* Now that the interfaces are installed, re-enable LPM. */ 218262306a36Sopenharmony_ci usb_unlocked_enable_lpm(dev); 218362306a36Sopenharmony_ci /* Enable LTM if it was turned off by usb_disable_device. */ 218462306a36Sopenharmony_ci usb_enable_ltm(dev); 218562306a36Sopenharmony_ci 218662306a36Sopenharmony_ci /* Now that all the interfaces are set up, register them 218762306a36Sopenharmony_ci * to trigger binding of drivers to interfaces. probe() 218862306a36Sopenharmony_ci * routines may install different altsettings and may 218962306a36Sopenharmony_ci * claim() any interfaces not yet bound. Many class drivers 219062306a36Sopenharmony_ci * need that: CDC, audio, video, etc. 219162306a36Sopenharmony_ci */ 219262306a36Sopenharmony_ci for (i = 0; i < nintf; ++i) { 219362306a36Sopenharmony_ci struct usb_interface *intf = cp->interface[i]; 219462306a36Sopenharmony_ci 219562306a36Sopenharmony_ci if (intf->dev.of_node && 219662306a36Sopenharmony_ci !of_device_is_available(intf->dev.of_node)) { 219762306a36Sopenharmony_ci dev_info(&dev->dev, "skipping disabled interface %d\n", 219862306a36Sopenharmony_ci intf->cur_altsetting->desc.bInterfaceNumber); 219962306a36Sopenharmony_ci continue; 220062306a36Sopenharmony_ci } 220162306a36Sopenharmony_ci 220262306a36Sopenharmony_ci dev_dbg(&dev->dev, 220362306a36Sopenharmony_ci "adding %s (config #%d, interface %d)\n", 220462306a36Sopenharmony_ci dev_name(&intf->dev), configuration, 220562306a36Sopenharmony_ci intf->cur_altsetting->desc.bInterfaceNumber); 220662306a36Sopenharmony_ci device_enable_async_suspend(&intf->dev); 220762306a36Sopenharmony_ci ret = device_add(&intf->dev); 220862306a36Sopenharmony_ci if (ret != 0) { 220962306a36Sopenharmony_ci dev_err(&dev->dev, "device_add(%s) --> %d\n", 221062306a36Sopenharmony_ci dev_name(&intf->dev), ret); 221162306a36Sopenharmony_ci continue; 221262306a36Sopenharmony_ci } 221362306a36Sopenharmony_ci create_intf_ep_devs(intf); 221462306a36Sopenharmony_ci } 221562306a36Sopenharmony_ci 221662306a36Sopenharmony_ci usb_autosuspend_device(dev); 221762306a36Sopenharmony_ci return 0; 221862306a36Sopenharmony_ci} 221962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_set_configuration); 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_cistatic LIST_HEAD(set_config_list); 222262306a36Sopenharmony_cistatic DEFINE_SPINLOCK(set_config_lock); 222362306a36Sopenharmony_ci 222462306a36Sopenharmony_cistruct set_config_request { 222562306a36Sopenharmony_ci struct usb_device *udev; 222662306a36Sopenharmony_ci int config; 222762306a36Sopenharmony_ci struct work_struct work; 222862306a36Sopenharmony_ci struct list_head node; 222962306a36Sopenharmony_ci}; 223062306a36Sopenharmony_ci 223162306a36Sopenharmony_ci/* Worker routine for usb_driver_set_configuration() */ 223262306a36Sopenharmony_cistatic void driver_set_config_work(struct work_struct *work) 223362306a36Sopenharmony_ci{ 223462306a36Sopenharmony_ci struct set_config_request *req = 223562306a36Sopenharmony_ci container_of(work, struct set_config_request, work); 223662306a36Sopenharmony_ci struct usb_device *udev = req->udev; 223762306a36Sopenharmony_ci 223862306a36Sopenharmony_ci usb_lock_device(udev); 223962306a36Sopenharmony_ci spin_lock(&set_config_lock); 224062306a36Sopenharmony_ci list_del(&req->node); 224162306a36Sopenharmony_ci spin_unlock(&set_config_lock); 224262306a36Sopenharmony_ci 224362306a36Sopenharmony_ci if (req->config >= -1) /* Is req still valid? */ 224462306a36Sopenharmony_ci usb_set_configuration(udev, req->config); 224562306a36Sopenharmony_ci usb_unlock_device(udev); 224662306a36Sopenharmony_ci usb_put_dev(udev); 224762306a36Sopenharmony_ci kfree(req); 224862306a36Sopenharmony_ci} 224962306a36Sopenharmony_ci 225062306a36Sopenharmony_ci/* Cancel pending Set-Config requests for a device whose configuration 225162306a36Sopenharmony_ci * was just changed 225262306a36Sopenharmony_ci */ 225362306a36Sopenharmony_cistatic void cancel_async_set_config(struct usb_device *udev) 225462306a36Sopenharmony_ci{ 225562306a36Sopenharmony_ci struct set_config_request *req; 225662306a36Sopenharmony_ci 225762306a36Sopenharmony_ci spin_lock(&set_config_lock); 225862306a36Sopenharmony_ci list_for_each_entry(req, &set_config_list, node) { 225962306a36Sopenharmony_ci if (req->udev == udev) 226062306a36Sopenharmony_ci req->config = -999; /* Mark as cancelled */ 226162306a36Sopenharmony_ci } 226262306a36Sopenharmony_ci spin_unlock(&set_config_lock); 226362306a36Sopenharmony_ci} 226462306a36Sopenharmony_ci 226562306a36Sopenharmony_ci/** 226662306a36Sopenharmony_ci * usb_driver_set_configuration - Provide a way for drivers to change device configurations 226762306a36Sopenharmony_ci * @udev: the device whose configuration is being updated 226862306a36Sopenharmony_ci * @config: the configuration being chosen. 226962306a36Sopenharmony_ci * Context: In process context, must be able to sleep 227062306a36Sopenharmony_ci * 227162306a36Sopenharmony_ci * Device interface drivers are not allowed to change device configurations. 227262306a36Sopenharmony_ci * This is because changing configurations will destroy the interface the 227362306a36Sopenharmony_ci * driver is bound to and create new ones; it would be like a floppy-disk 227462306a36Sopenharmony_ci * driver telling the computer to replace the floppy-disk drive with a 227562306a36Sopenharmony_ci * tape drive! 227662306a36Sopenharmony_ci * 227762306a36Sopenharmony_ci * Still, in certain specialized circumstances the need may arise. This 227862306a36Sopenharmony_ci * routine gets around the normal restrictions by using a work thread to 227962306a36Sopenharmony_ci * submit the change-config request. 228062306a36Sopenharmony_ci * 228162306a36Sopenharmony_ci * Return: 0 if the request was successfully queued, error code otherwise. 228262306a36Sopenharmony_ci * The caller has no way to know whether the queued request will eventually 228362306a36Sopenharmony_ci * succeed. 228462306a36Sopenharmony_ci */ 228562306a36Sopenharmony_ciint usb_driver_set_configuration(struct usb_device *udev, int config) 228662306a36Sopenharmony_ci{ 228762306a36Sopenharmony_ci struct set_config_request *req; 228862306a36Sopenharmony_ci 228962306a36Sopenharmony_ci req = kmalloc(sizeof(*req), GFP_KERNEL); 229062306a36Sopenharmony_ci if (!req) 229162306a36Sopenharmony_ci return -ENOMEM; 229262306a36Sopenharmony_ci req->udev = udev; 229362306a36Sopenharmony_ci req->config = config; 229462306a36Sopenharmony_ci INIT_WORK(&req->work, driver_set_config_work); 229562306a36Sopenharmony_ci 229662306a36Sopenharmony_ci spin_lock(&set_config_lock); 229762306a36Sopenharmony_ci list_add(&req->node, &set_config_list); 229862306a36Sopenharmony_ci spin_unlock(&set_config_lock); 229962306a36Sopenharmony_ci 230062306a36Sopenharmony_ci usb_get_dev(udev); 230162306a36Sopenharmony_ci schedule_work(&req->work); 230262306a36Sopenharmony_ci return 0; 230362306a36Sopenharmony_ci} 230462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_driver_set_configuration); 230562306a36Sopenharmony_ci 230662306a36Sopenharmony_ci/** 230762306a36Sopenharmony_ci * cdc_parse_cdc_header - parse the extra headers present in CDC devices 230862306a36Sopenharmony_ci * @hdr: the place to put the results of the parsing 230962306a36Sopenharmony_ci * @intf: the interface for which parsing is requested 231062306a36Sopenharmony_ci * @buffer: pointer to the extra headers to be parsed 231162306a36Sopenharmony_ci * @buflen: length of the extra headers 231262306a36Sopenharmony_ci * 231362306a36Sopenharmony_ci * This evaluates the extra headers present in CDC devices which 231462306a36Sopenharmony_ci * bind the interfaces for data and control and provide details 231562306a36Sopenharmony_ci * about the capabilities of the device. 231662306a36Sopenharmony_ci * 231762306a36Sopenharmony_ci * Return: number of descriptors parsed or -EINVAL 231862306a36Sopenharmony_ci * if the header is contradictory beyond salvage 231962306a36Sopenharmony_ci */ 232062306a36Sopenharmony_ci 232162306a36Sopenharmony_ciint cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, 232262306a36Sopenharmony_ci struct usb_interface *intf, 232362306a36Sopenharmony_ci u8 *buffer, 232462306a36Sopenharmony_ci int buflen) 232562306a36Sopenharmony_ci{ 232662306a36Sopenharmony_ci /* duplicates are ignored */ 232762306a36Sopenharmony_ci struct usb_cdc_union_desc *union_header = NULL; 232862306a36Sopenharmony_ci 232962306a36Sopenharmony_ci /* duplicates are not tolerated */ 233062306a36Sopenharmony_ci struct usb_cdc_header_desc *header = NULL; 233162306a36Sopenharmony_ci struct usb_cdc_ether_desc *ether = NULL; 233262306a36Sopenharmony_ci struct usb_cdc_mdlm_detail_desc *detail = NULL; 233362306a36Sopenharmony_ci struct usb_cdc_mdlm_desc *desc = NULL; 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci unsigned int elength; 233662306a36Sopenharmony_ci int cnt = 0; 233762306a36Sopenharmony_ci 233862306a36Sopenharmony_ci memset(hdr, 0x00, sizeof(struct usb_cdc_parsed_header)); 233962306a36Sopenharmony_ci hdr->phonet_magic_present = false; 234062306a36Sopenharmony_ci while (buflen > 0) { 234162306a36Sopenharmony_ci elength = buffer[0]; 234262306a36Sopenharmony_ci if (!elength) { 234362306a36Sopenharmony_ci dev_err(&intf->dev, "skipping garbage byte\n"); 234462306a36Sopenharmony_ci elength = 1; 234562306a36Sopenharmony_ci goto next_desc; 234662306a36Sopenharmony_ci } 234762306a36Sopenharmony_ci if ((buflen < elength) || (elength < 3)) { 234862306a36Sopenharmony_ci dev_err(&intf->dev, "invalid descriptor buffer length\n"); 234962306a36Sopenharmony_ci break; 235062306a36Sopenharmony_ci } 235162306a36Sopenharmony_ci if (buffer[1] != USB_DT_CS_INTERFACE) { 235262306a36Sopenharmony_ci dev_err(&intf->dev, "skipping garbage\n"); 235362306a36Sopenharmony_ci goto next_desc; 235462306a36Sopenharmony_ci } 235562306a36Sopenharmony_ci 235662306a36Sopenharmony_ci switch (buffer[2]) { 235762306a36Sopenharmony_ci case USB_CDC_UNION_TYPE: /* we've found it */ 235862306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_union_desc)) 235962306a36Sopenharmony_ci goto next_desc; 236062306a36Sopenharmony_ci if (union_header) { 236162306a36Sopenharmony_ci dev_err(&intf->dev, "More than one union descriptor, skipping ...\n"); 236262306a36Sopenharmony_ci goto next_desc; 236362306a36Sopenharmony_ci } 236462306a36Sopenharmony_ci union_header = (struct usb_cdc_union_desc *)buffer; 236562306a36Sopenharmony_ci break; 236662306a36Sopenharmony_ci case USB_CDC_COUNTRY_TYPE: 236762306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_country_functional_desc)) 236862306a36Sopenharmony_ci goto next_desc; 236962306a36Sopenharmony_ci hdr->usb_cdc_country_functional_desc = 237062306a36Sopenharmony_ci (struct usb_cdc_country_functional_desc *)buffer; 237162306a36Sopenharmony_ci break; 237262306a36Sopenharmony_ci case USB_CDC_HEADER_TYPE: 237362306a36Sopenharmony_ci if (elength != sizeof(struct usb_cdc_header_desc)) 237462306a36Sopenharmony_ci goto next_desc; 237562306a36Sopenharmony_ci if (header) 237662306a36Sopenharmony_ci return -EINVAL; 237762306a36Sopenharmony_ci header = (struct usb_cdc_header_desc *)buffer; 237862306a36Sopenharmony_ci break; 237962306a36Sopenharmony_ci case USB_CDC_ACM_TYPE: 238062306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_acm_descriptor)) 238162306a36Sopenharmony_ci goto next_desc; 238262306a36Sopenharmony_ci hdr->usb_cdc_acm_descriptor = 238362306a36Sopenharmony_ci (struct usb_cdc_acm_descriptor *)buffer; 238462306a36Sopenharmony_ci break; 238562306a36Sopenharmony_ci case USB_CDC_ETHERNET_TYPE: 238662306a36Sopenharmony_ci if (elength != sizeof(struct usb_cdc_ether_desc)) 238762306a36Sopenharmony_ci goto next_desc; 238862306a36Sopenharmony_ci if (ether) 238962306a36Sopenharmony_ci return -EINVAL; 239062306a36Sopenharmony_ci ether = (struct usb_cdc_ether_desc *)buffer; 239162306a36Sopenharmony_ci break; 239262306a36Sopenharmony_ci case USB_CDC_CALL_MANAGEMENT_TYPE: 239362306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_call_mgmt_descriptor)) 239462306a36Sopenharmony_ci goto next_desc; 239562306a36Sopenharmony_ci hdr->usb_cdc_call_mgmt_descriptor = 239662306a36Sopenharmony_ci (struct usb_cdc_call_mgmt_descriptor *)buffer; 239762306a36Sopenharmony_ci break; 239862306a36Sopenharmony_ci case USB_CDC_DMM_TYPE: 239962306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_dmm_desc)) 240062306a36Sopenharmony_ci goto next_desc; 240162306a36Sopenharmony_ci hdr->usb_cdc_dmm_desc = 240262306a36Sopenharmony_ci (struct usb_cdc_dmm_desc *)buffer; 240362306a36Sopenharmony_ci break; 240462306a36Sopenharmony_ci case USB_CDC_MDLM_TYPE: 240562306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_mdlm_desc)) 240662306a36Sopenharmony_ci goto next_desc; 240762306a36Sopenharmony_ci if (desc) 240862306a36Sopenharmony_ci return -EINVAL; 240962306a36Sopenharmony_ci desc = (struct usb_cdc_mdlm_desc *)buffer; 241062306a36Sopenharmony_ci break; 241162306a36Sopenharmony_ci case USB_CDC_MDLM_DETAIL_TYPE: 241262306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_mdlm_detail_desc)) 241362306a36Sopenharmony_ci goto next_desc; 241462306a36Sopenharmony_ci if (detail) 241562306a36Sopenharmony_ci return -EINVAL; 241662306a36Sopenharmony_ci detail = (struct usb_cdc_mdlm_detail_desc *)buffer; 241762306a36Sopenharmony_ci break; 241862306a36Sopenharmony_ci case USB_CDC_NCM_TYPE: 241962306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_ncm_desc)) 242062306a36Sopenharmony_ci goto next_desc; 242162306a36Sopenharmony_ci hdr->usb_cdc_ncm_desc = (struct usb_cdc_ncm_desc *)buffer; 242262306a36Sopenharmony_ci break; 242362306a36Sopenharmony_ci case USB_CDC_MBIM_TYPE: 242462306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_mbim_desc)) 242562306a36Sopenharmony_ci goto next_desc; 242662306a36Sopenharmony_ci 242762306a36Sopenharmony_ci hdr->usb_cdc_mbim_desc = (struct usb_cdc_mbim_desc *)buffer; 242862306a36Sopenharmony_ci break; 242962306a36Sopenharmony_ci case USB_CDC_MBIM_EXTENDED_TYPE: 243062306a36Sopenharmony_ci if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) 243162306a36Sopenharmony_ci break; 243262306a36Sopenharmony_ci hdr->usb_cdc_mbim_extended_desc = 243362306a36Sopenharmony_ci (struct usb_cdc_mbim_extended_desc *)buffer; 243462306a36Sopenharmony_ci break; 243562306a36Sopenharmony_ci case CDC_PHONET_MAGIC_NUMBER: 243662306a36Sopenharmony_ci hdr->phonet_magic_present = true; 243762306a36Sopenharmony_ci break; 243862306a36Sopenharmony_ci default: 243962306a36Sopenharmony_ci /* 244062306a36Sopenharmony_ci * there are LOTS more CDC descriptors that 244162306a36Sopenharmony_ci * could legitimately be found here. 244262306a36Sopenharmony_ci */ 244362306a36Sopenharmony_ci dev_dbg(&intf->dev, "Ignoring descriptor: type %02x, length %ud\n", 244462306a36Sopenharmony_ci buffer[2], elength); 244562306a36Sopenharmony_ci goto next_desc; 244662306a36Sopenharmony_ci } 244762306a36Sopenharmony_ci cnt++; 244862306a36Sopenharmony_cinext_desc: 244962306a36Sopenharmony_ci buflen -= elength; 245062306a36Sopenharmony_ci buffer += elength; 245162306a36Sopenharmony_ci } 245262306a36Sopenharmony_ci hdr->usb_cdc_union_desc = union_header; 245362306a36Sopenharmony_ci hdr->usb_cdc_header_desc = header; 245462306a36Sopenharmony_ci hdr->usb_cdc_mdlm_detail_desc = detail; 245562306a36Sopenharmony_ci hdr->usb_cdc_mdlm_desc = desc; 245662306a36Sopenharmony_ci hdr->usb_cdc_ether_desc = ether; 245762306a36Sopenharmony_ci return cnt; 245862306a36Sopenharmony_ci} 245962306a36Sopenharmony_ci 246062306a36Sopenharmony_ciEXPORT_SYMBOL(cdc_parse_cdc_header); 2461