xref: /linux/drivers/usb/core/message.c (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
1aa1f3bb5SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * message.c - synchronous message handling
4b65fba3dSGreg Kroah-Hartman  *
5b65fba3dSGreg Kroah-Hartman  * Released under the GPLv2 only.
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
8a599a0fbSAndy Shevchenko #include <linux/acpi.h>
91da177e4SLinus Torvalds #include <linux/pci.h>	/* for scatterlist macros */
101da177e4SLinus Torvalds #include <linux/usb.h>
111da177e4SLinus Torvalds #include <linux/module.h>
12484468fbSRob Herring #include <linux/of.h>
131da177e4SLinus Torvalds #include <linux/slab.h>
141da177e4SLinus Torvalds #include <linux/mm.h>
151da177e4SLinus Torvalds #include <linux/timer.h>
161da177e4SLinus Torvalds #include <linux/ctype.h>
17a853a3d4SClemens Ladisch #include <linux/nls.h>
181da177e4SLinus Torvalds #include <linux/device.h>
1911763609SRalf Baechle #include <linux/scatterlist.h>
20e4c6fb77SOliver Neukum #include <linux/usb/cdc.h>
217ceec1f1SOliver Neukum #include <linux/usb/quirks.h>
2227729aadSEric Lescouet #include <linux/usb/hcd.h>	/* for usbcore internals */
231a7e3948SJohan Hovold #include <linux/usb/of.h>
241da177e4SLinus Torvalds #include <asm/byteorder.h>
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds #include "usb.h"
271da177e4SLinus Torvalds 
28df718962SAlan Stern static void cancel_async_set_config(struct usb_device *udev);
29df718962SAlan Stern 
3067f5dde3SAlan Stern struct api_context {
3167f5dde3SAlan Stern 	struct completion	done;
3267f5dde3SAlan Stern 	int			status;
3367f5dde3SAlan Stern };
3467f5dde3SAlan Stern 
usb_api_blocking_completion(struct urb * urb)357d12e780SDavid Howells static void usb_api_blocking_completion(struct urb *urb)
361da177e4SLinus Torvalds {
3767f5dde3SAlan Stern 	struct api_context *ctx = urb->context;
3867f5dde3SAlan Stern 
3967f5dde3SAlan Stern 	ctx->status = urb->status;
4067f5dde3SAlan Stern 	complete(&ctx->done);
411da177e4SLinus Torvalds }
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds 
44ecdc0a59SFranck Bui-Huu /*
45ecdc0a59SFranck Bui-Huu  * Starts urb and waits for completion or timeout. Note that this call
46ecdc0a59SFranck Bui-Huu  * is NOT interruptible. Many device driver i/o requests should be
47ecdc0a59SFranck Bui-Huu  * interruptible and therefore these drivers should implement their
48ecdc0a59SFranck Bui-Huu  * own interruptible routines.
49ecdc0a59SFranck Bui-Huu  */
usb_start_wait_urb(struct urb * urb,int timeout,int * actual_length)501da177e4SLinus Torvalds static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
511da177e4SLinus Torvalds {
5267f5dde3SAlan Stern 	struct api_context ctx;
53ecdc0a59SFranck Bui-Huu 	unsigned long expire;
543fc3e826SGreg Kroah-Hartman 	int retval;
551da177e4SLinus Torvalds 
5667f5dde3SAlan Stern 	init_completion(&ctx.done);
5767f5dde3SAlan Stern 	urb->context = &ctx;
581da177e4SLinus Torvalds 	urb->actual_length = 0;
593fc3e826SGreg Kroah-Hartman 	retval = usb_submit_urb(urb, GFP_NOIO);
603fc3e826SGreg Kroah-Hartman 	if (unlikely(retval))
61ecdc0a59SFranck Bui-Huu 		goto out;
621da177e4SLinus Torvalds 
63ecdc0a59SFranck Bui-Huu 	expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
6467f5dde3SAlan Stern 	if (!wait_for_completion_timeout(&ctx.done, expire)) {
6567f5dde3SAlan Stern 		usb_kill_urb(urb);
6667f5dde3SAlan Stern 		retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
67ecdc0a59SFranck Bui-Huu 
681da177e4SLinus Torvalds 		dev_dbg(&urb->dev->dev,
6971d2718fSRoel Kluin 			"%s timed out on ep%d%s len=%u/%u\n",
701da177e4SLinus Torvalds 			current->comm,
715e60a161SAlan Stern 			usb_endpoint_num(&urb->ep->desc),
725e60a161SAlan Stern 			usb_urb_dir_in(urb) ? "in" : "out",
731da177e4SLinus Torvalds 			urb->actual_length,
74ecdc0a59SFranck Bui-Huu 			urb->transfer_buffer_length);
75ecdc0a59SFranck Bui-Huu 	} else
7667f5dde3SAlan Stern 		retval = ctx.status;
77ecdc0a59SFranck Bui-Huu out:
781da177e4SLinus Torvalds 	if (actual_length)
791da177e4SLinus Torvalds 		*actual_length = urb->actual_length;
80ecdc0a59SFranck Bui-Huu 
811da177e4SLinus Torvalds 	usb_free_urb(urb);
823fc3e826SGreg Kroah-Hartman 	return retval;
831da177e4SLinus Torvalds }
841da177e4SLinus Torvalds 
851da177e4SLinus Torvalds /*-------------------------------------------------------------------*/
863e35bf39SGreg Kroah-Hartman /* returns status (negative) or length (positive) */
usb_internal_control_msg(struct usb_device * usb_dev,unsigned int pipe,struct usb_ctrlrequest * cmd,void * data,int len,int timeout)871da177e4SLinus Torvalds static int usb_internal_control_msg(struct usb_device *usb_dev,
881da177e4SLinus Torvalds 				    unsigned int pipe,
891da177e4SLinus Torvalds 				    struct usb_ctrlrequest *cmd,
901da177e4SLinus Torvalds 				    void *data, int len, int timeout)
911da177e4SLinus Torvalds {
921da177e4SLinus Torvalds 	struct urb *urb;
931da177e4SLinus Torvalds 	int retv;
941da177e4SLinus Torvalds 	int length;
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds 	urb = usb_alloc_urb(0, GFP_NOIO);
971da177e4SLinus Torvalds 	if (!urb)
981da177e4SLinus Torvalds 		return -ENOMEM;
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds 	usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
1011da177e4SLinus Torvalds 			     len, usb_api_blocking_completion, NULL);
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds 	retv = usb_start_wait_urb(urb, timeout, &length);
1041da177e4SLinus Torvalds 	if (retv < 0)
1051da177e4SLinus Torvalds 		return retv;
1061da177e4SLinus Torvalds 	else
1071da177e4SLinus Torvalds 		return length;
1081da177e4SLinus Torvalds }
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds /**
1111da177e4SLinus Torvalds  * usb_control_msg - Builds a control urb, sends it off and waits for completion
1121da177e4SLinus Torvalds  * @dev: pointer to the usb device to send the message to
1131da177e4SLinus Torvalds  * @pipe: endpoint "pipe" to send the message to
1141da177e4SLinus Torvalds  * @request: USB message request value
1151da177e4SLinus Torvalds  * @requesttype: USB message request type value
1161da177e4SLinus Torvalds  * @value: USB message value
1171da177e4SLinus Torvalds  * @index: USB message index value
1181da177e4SLinus Torvalds  * @data: pointer to the data to send
1191da177e4SLinus Torvalds  * @size: length in bytes of the data to send
1203e35bf39SGreg Kroah-Hartman  * @timeout: time in msecs to wait for the message to complete before timing
1213e35bf39SGreg Kroah-Hartman  *	out (if 0 the wait is forever)
1223e35bf39SGreg Kroah-Hartman  *
12341631d36SAhmed S. Darwish  * Context: task context, might sleep.
1241da177e4SLinus Torvalds  *
1253e35bf39SGreg Kroah-Hartman  * This function sends a simple control message to a specified endpoint and
1263e35bf39SGreg Kroah-Hartman  * waits for the message to complete, or timeout.
1271da177e4SLinus Torvalds  *
128123b7b30SJaejoong Kim  * Don't use this function from within an interrupt context. If you need
129123b7b30SJaejoong Kim  * an asynchronous message, or need to send a message from within interrupt
130123b7b30SJaejoong Kim  * context, use usb_submit_urb(). If a thread in your driver uses this call,
131123b7b30SJaejoong Kim  * make sure your disconnect() method can wait for it to complete. Since you
132123b7b30SJaejoong Kim  * don't have a handle on the URB used, you can't cancel the request.
133626f090cSYacine Belkadi  *
134626f090cSYacine Belkadi  * Return: If successful, the number of bytes transferred. Otherwise, a negative
135626f090cSYacine Belkadi  * error number.
1361da177e4SLinus Torvalds  */
usb_control_msg(struct usb_device * dev,unsigned int pipe,__u8 request,__u8 requesttype,__u16 value,__u16 index,void * data,__u16 size,int timeout)1373e35bf39SGreg Kroah-Hartman int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
1383e35bf39SGreg Kroah-Hartman 		    __u8 requesttype, __u16 value, __u16 index, void *data,
1393e35bf39SGreg Kroah-Hartman 		    __u16 size, int timeout)
1401da177e4SLinus Torvalds {
1413e35bf39SGreg Kroah-Hartman 	struct usb_ctrlrequest *dr;
1421da177e4SLinus Torvalds 	int ret;
1431da177e4SLinus Torvalds 
1443e35bf39SGreg Kroah-Hartman 	dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
1451da177e4SLinus Torvalds 	if (!dr)
1461da177e4SLinus Torvalds 		return -ENOMEM;
1471da177e4SLinus Torvalds 
1481da177e4SLinus Torvalds 	dr->bRequestType = requesttype;
1491da177e4SLinus Torvalds 	dr->bRequest = request;
150da2bbdccSHarvey Harrison 	dr->wValue = cpu_to_le16(value);
151da2bbdccSHarvey Harrison 	dr->wIndex = cpu_to_le16(index);
152da2bbdccSHarvey Harrison 	dr->wLength = cpu_to_le16(size);
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds 	ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
1551da177e4SLinus Torvalds 
156cb88a058SDanilo Krummrich 	/* Linger a bit, prior to the next control message. */
157cb88a058SDanilo Krummrich 	if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
158cb88a058SDanilo Krummrich 		msleep(200);
159cb88a058SDanilo Krummrich 
1601da177e4SLinus Torvalds 	kfree(dr);
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds 	return ret;
1631da177e4SLinus Torvalds }
164782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_control_msg);
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds /**
167719b8f28SGreg Kroah-Hartman  * usb_control_msg_send - Builds a control "send" message, sends it off and waits for completion
168719b8f28SGreg Kroah-Hartman  * @dev: pointer to the usb device to send the message to
169719b8f28SGreg Kroah-Hartman  * @endpoint: endpoint to send the message to
170719b8f28SGreg Kroah-Hartman  * @request: USB message request value
171719b8f28SGreg Kroah-Hartman  * @requesttype: USB message request type value
172719b8f28SGreg Kroah-Hartman  * @value: USB message value
173719b8f28SGreg Kroah-Hartman  * @index: USB message index value
174719b8f28SGreg Kroah-Hartman  * @driver_data: pointer to the data to send
175719b8f28SGreg Kroah-Hartman  * @size: length in bytes of the data to send
176719b8f28SGreg Kroah-Hartman  * @timeout: time in msecs to wait for the message to complete before timing
177719b8f28SGreg Kroah-Hartman  *	out (if 0 the wait is forever)
178ddd1198eSOliver Neukum  * @memflags: the flags for memory allocation for buffers
179719b8f28SGreg Kroah-Hartman  *
180719b8f28SGreg Kroah-Hartman  * Context: !in_interrupt ()
181719b8f28SGreg Kroah-Hartman  *
182719b8f28SGreg Kroah-Hartman  * This function sends a control message to a specified endpoint that is not
183719b8f28SGreg Kroah-Hartman  * expected to fill in a response (i.e. a "send message") and waits for the
184719b8f28SGreg Kroah-Hartman  * message to complete, or timeout.
185719b8f28SGreg Kroah-Hartman  *
186719b8f28SGreg Kroah-Hartman  * Do not use this function from within an interrupt context. If you need
187719b8f28SGreg Kroah-Hartman  * an asynchronous message, or need to send a message from within interrupt
188719b8f28SGreg Kroah-Hartman  * context, use usb_submit_urb(). If a thread in your driver uses this call,
189719b8f28SGreg Kroah-Hartman  * make sure your disconnect() method can wait for it to complete. Since you
190719b8f28SGreg Kroah-Hartman  * don't have a handle on the URB used, you can't cancel the request.
191719b8f28SGreg Kroah-Hartman  *
192719b8f28SGreg Kroah-Hartman  * The data pointer can be made to a reference on the stack, or anywhere else,
193719b8f28SGreg Kroah-Hartman  * as it will not be modified at all.  This does not have the restriction that
194719b8f28SGreg Kroah-Hartman  * usb_control_msg() has where the data pointer must be to dynamically allocated
195719b8f28SGreg Kroah-Hartman  * memory (i.e. memory that can be successfully DMAed to a device).
196719b8f28SGreg Kroah-Hartman  *
197719b8f28SGreg Kroah-Hartman  * Return: If successful, 0 is returned, Otherwise, a negative error number.
198719b8f28SGreg Kroah-Hartman  */
usb_control_msg_send(struct usb_device * dev,__u8 endpoint,__u8 request,__u8 requesttype,__u16 value,__u16 index,const void * driver_data,__u16 size,int timeout,gfp_t memflags)199719b8f28SGreg Kroah-Hartman int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request,
200719b8f28SGreg Kroah-Hartman 			 __u8 requesttype, __u16 value, __u16 index,
201ddd1198eSOliver Neukum 			 const void *driver_data, __u16 size, int timeout,
202ddd1198eSOliver Neukum 			 gfp_t memflags)
203719b8f28SGreg Kroah-Hartman {
204719b8f28SGreg Kroah-Hartman 	unsigned int pipe = usb_sndctrlpipe(dev, endpoint);
205719b8f28SGreg Kroah-Hartman 	int ret;
206719b8f28SGreg Kroah-Hartman 	u8 *data = NULL;
207719b8f28SGreg Kroah-Hartman 
208719b8f28SGreg Kroah-Hartman 	if (size) {
209ddd1198eSOliver Neukum 		data = kmemdup(driver_data, size, memflags);
210719b8f28SGreg Kroah-Hartman 		if (!data)
211719b8f28SGreg Kroah-Hartman 			return -ENOMEM;
212719b8f28SGreg Kroah-Hartman 	}
213719b8f28SGreg Kroah-Hartman 
214719b8f28SGreg Kroah-Hartman 	ret = usb_control_msg(dev, pipe, request, requesttype, value, index,
215719b8f28SGreg Kroah-Hartman 			      data, size, timeout);
216719b8f28SGreg Kroah-Hartman 	kfree(data);
217719b8f28SGreg Kroah-Hartman 
218719b8f28SGreg Kroah-Hartman 	if (ret < 0)
219719b8f28SGreg Kroah-Hartman 		return ret;
220baf7df45SJohan Hovold 
221719b8f28SGreg Kroah-Hartman 	return 0;
222719b8f28SGreg Kroah-Hartman }
223719b8f28SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_control_msg_send);
224719b8f28SGreg Kroah-Hartman 
225719b8f28SGreg Kroah-Hartman /**
226719b8f28SGreg Kroah-Hartman  * usb_control_msg_recv - Builds a control "receive" message, sends it off and waits for completion
227719b8f28SGreg Kroah-Hartman  * @dev: pointer to the usb device to send the message to
228719b8f28SGreg Kroah-Hartman  * @endpoint: endpoint to send the message to
229719b8f28SGreg Kroah-Hartman  * @request: USB message request value
230719b8f28SGreg Kroah-Hartman  * @requesttype: USB message request type value
231719b8f28SGreg Kroah-Hartman  * @value: USB message value
232719b8f28SGreg Kroah-Hartman  * @index: USB message index value
233719b8f28SGreg Kroah-Hartman  * @driver_data: pointer to the data to be filled in by the message
234719b8f28SGreg Kroah-Hartman  * @size: length in bytes of the data to be received
235719b8f28SGreg Kroah-Hartman  * @timeout: time in msecs to wait for the message to complete before timing
236719b8f28SGreg Kroah-Hartman  *	out (if 0 the wait is forever)
237ddd1198eSOliver Neukum  * @memflags: the flags for memory allocation for buffers
238719b8f28SGreg Kroah-Hartman  *
239719b8f28SGreg Kroah-Hartman  * Context: !in_interrupt ()
240719b8f28SGreg Kroah-Hartman  *
241719b8f28SGreg Kroah-Hartman  * This function sends a control message to a specified endpoint that is
242719b8f28SGreg Kroah-Hartman  * expected to fill in a response (i.e. a "receive message") and waits for the
243719b8f28SGreg Kroah-Hartman  * message to complete, or timeout.
244719b8f28SGreg Kroah-Hartman  *
245719b8f28SGreg Kroah-Hartman  * Do not use this function from within an interrupt context. If you need
246719b8f28SGreg Kroah-Hartman  * an asynchronous message, or need to send a message from within interrupt
247719b8f28SGreg Kroah-Hartman  * context, use usb_submit_urb(). If a thread in your driver uses this call,
248719b8f28SGreg Kroah-Hartman  * make sure your disconnect() method can wait for it to complete. Since you
249719b8f28SGreg Kroah-Hartman  * don't have a handle on the URB used, you can't cancel the request.
250719b8f28SGreg Kroah-Hartman  *
251719b8f28SGreg Kroah-Hartman  * The data pointer can be made to a reference on the stack, or anywhere else
252719b8f28SGreg Kroah-Hartman  * that can be successfully written to.  This function does not have the
253719b8f28SGreg Kroah-Hartman  * restriction that usb_control_msg() has where the data pointer must be to
254719b8f28SGreg Kroah-Hartman  * dynamically allocated memory (i.e. memory that can be successfully DMAed to a
255719b8f28SGreg Kroah-Hartman  * device).
256719b8f28SGreg Kroah-Hartman  *
257719b8f28SGreg Kroah-Hartman  * The "whole" message must be properly received from the device in order for
258719b8f28SGreg Kroah-Hartman  * this function to be successful.  If a device returns less than the expected
259719b8f28SGreg Kroah-Hartman  * amount of data, then the function will fail.  Do not use this for messages
260719b8f28SGreg Kroah-Hartman  * where a variable amount of data might be returned.
261719b8f28SGreg Kroah-Hartman  *
262719b8f28SGreg Kroah-Hartman  * Return: If successful, 0 is returned, Otherwise, a negative error number.
263719b8f28SGreg Kroah-Hartman  */
usb_control_msg_recv(struct usb_device * dev,__u8 endpoint,__u8 request,__u8 requesttype,__u16 value,__u16 index,void * driver_data,__u16 size,int timeout,gfp_t memflags)264719b8f28SGreg Kroah-Hartman int usb_control_msg_recv(struct usb_device *dev, __u8 endpoint, __u8 request,
265719b8f28SGreg Kroah-Hartman 			 __u8 requesttype, __u16 value, __u16 index,
266ddd1198eSOliver Neukum 			 void *driver_data, __u16 size, int timeout,
267ddd1198eSOliver Neukum 			 gfp_t memflags)
268719b8f28SGreg Kroah-Hartman {
269719b8f28SGreg Kroah-Hartman 	unsigned int pipe = usb_rcvctrlpipe(dev, endpoint);
270719b8f28SGreg Kroah-Hartman 	int ret;
271719b8f28SGreg Kroah-Hartman 	u8 *data;
272719b8f28SGreg Kroah-Hartman 
2737fe53dcbSJohan Hovold 	if (!size || !driver_data)
274719b8f28SGreg Kroah-Hartman 		return -EINVAL;
275719b8f28SGreg Kroah-Hartman 
276ddd1198eSOliver Neukum 	data = kmalloc(size, memflags);
277719b8f28SGreg Kroah-Hartman 	if (!data)
278719b8f28SGreg Kroah-Hartman 		return -ENOMEM;
279719b8f28SGreg Kroah-Hartman 
280719b8f28SGreg Kroah-Hartman 	ret = usb_control_msg(dev, pipe, request, requesttype, value, index,
281719b8f28SGreg Kroah-Hartman 			      data, size, timeout);
282719b8f28SGreg Kroah-Hartman 
283719b8f28SGreg Kroah-Hartman 	if (ret < 0)
284719b8f28SGreg Kroah-Hartman 		goto exit;
285719b8f28SGreg Kroah-Hartman 
286719b8f28SGreg Kroah-Hartman 	if (ret == size) {
287719b8f28SGreg Kroah-Hartman 		memcpy(driver_data, data, size);
288719b8f28SGreg Kroah-Hartman 		ret = 0;
289719b8f28SGreg Kroah-Hartman 	} else {
2909dc9c854SJohan Hovold 		ret = -EREMOTEIO;
291719b8f28SGreg Kroah-Hartman 	}
292719b8f28SGreg Kroah-Hartman 
293719b8f28SGreg Kroah-Hartman exit:
294719b8f28SGreg Kroah-Hartman 	kfree(data);
295719b8f28SGreg Kroah-Hartman 	return ret;
296719b8f28SGreg Kroah-Hartman }
297719b8f28SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_control_msg_recv);
298719b8f28SGreg Kroah-Hartman 
299719b8f28SGreg Kroah-Hartman /**
300782a7a63SGreg Kroah-Hartman  * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion
301782a7a63SGreg Kroah-Hartman  * @usb_dev: pointer to the usb device to send the message to
302782a7a63SGreg Kroah-Hartman  * @pipe: endpoint "pipe" to send the message to
303782a7a63SGreg Kroah-Hartman  * @data: pointer to the data to send
304782a7a63SGreg Kroah-Hartman  * @len: length in bytes of the data to send
3053e35bf39SGreg Kroah-Hartman  * @actual_length: pointer to a location to put the actual length transferred
3063e35bf39SGreg Kroah-Hartman  *	in bytes
307782a7a63SGreg Kroah-Hartman  * @timeout: time in msecs to wait for the message to complete before
308782a7a63SGreg Kroah-Hartman  *	timing out (if 0 the wait is forever)
3093e35bf39SGreg Kroah-Hartman  *
31041631d36SAhmed S. Darwish  * Context: task context, might sleep.
311782a7a63SGreg Kroah-Hartman  *
312782a7a63SGreg Kroah-Hartman  * This function sends a simple interrupt message to a specified endpoint and
313782a7a63SGreg Kroah-Hartman  * waits for the message to complete, or timeout.
314782a7a63SGreg Kroah-Hartman  *
315123b7b30SJaejoong Kim  * Don't use this function from within an interrupt context. If you need
316123b7b30SJaejoong Kim  * an asynchronous message, or need to send a message from within interrupt
317123b7b30SJaejoong Kim  * context, use usb_submit_urb() If a thread in your driver uses this call,
318123b7b30SJaejoong Kim  * make sure your disconnect() method can wait for it to complete. Since you
319123b7b30SJaejoong Kim  * don't have a handle on the URB used, you can't cancel the request.
320626f090cSYacine Belkadi  *
321626f090cSYacine Belkadi  * Return:
322626f090cSYacine Belkadi  * If successful, 0. Otherwise a negative error number. The number of actual
323e227867fSMasanari Iida  * bytes transferred will be stored in the @actual_length parameter.
324782a7a63SGreg Kroah-Hartman  */
usb_interrupt_msg(struct usb_device * usb_dev,unsigned int pipe,void * data,int len,int * actual_length,int timeout)325782a7a63SGreg Kroah-Hartman int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
326782a7a63SGreg Kroah-Hartman 		      void *data, int len, int *actual_length, int timeout)
327782a7a63SGreg Kroah-Hartman {
328782a7a63SGreg Kroah-Hartman 	return usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout);
329782a7a63SGreg Kroah-Hartman }
330782a7a63SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_interrupt_msg);
331782a7a63SGreg Kroah-Hartman 
332782a7a63SGreg Kroah-Hartman /**
3331da177e4SLinus Torvalds  * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion
3341da177e4SLinus Torvalds  * @usb_dev: pointer to the usb device to send the message to
3351da177e4SLinus Torvalds  * @pipe: endpoint "pipe" to send the message to
3361da177e4SLinus Torvalds  * @data: pointer to the data to send
3371da177e4SLinus Torvalds  * @len: length in bytes of the data to send
3383e35bf39SGreg Kroah-Hartman  * @actual_length: pointer to a location to put the actual length transferred
3393e35bf39SGreg Kroah-Hartman  *	in bytes
3401da177e4SLinus Torvalds  * @timeout: time in msecs to wait for the message to complete before
3411da177e4SLinus Torvalds  *	timing out (if 0 the wait is forever)
3423e35bf39SGreg Kroah-Hartman  *
34341631d36SAhmed S. Darwish  * Context: task context, might sleep.
3441da177e4SLinus Torvalds  *
3451da177e4SLinus Torvalds  * This function sends a simple bulk message to a specified endpoint
3461da177e4SLinus Torvalds  * and waits for the message to complete, or timeout.
3471da177e4SLinus Torvalds  *
348123b7b30SJaejoong Kim  * Don't use this function from within an interrupt context. If you need
349123b7b30SJaejoong Kim  * an asynchronous message, or need to send a message from within interrupt
350123b7b30SJaejoong Kim  * context, use usb_submit_urb() If a thread in your driver uses this call,
351123b7b30SJaejoong Kim  * make sure your disconnect() method can wait for it to complete. Since you
352123b7b30SJaejoong Kim  * don't have a handle on the URB used, you can't cancel the request.
353d09d36a9SAlan Stern  *
3543e35bf39SGreg Kroah-Hartman  * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT ioctl,
3553e35bf39SGreg Kroah-Hartman  * users are forced to abuse this routine by using it to submit URBs for
3563e35bf39SGreg Kroah-Hartman  * interrupt endpoints.  We will take the liberty of creating an interrupt URB
3573e35bf39SGreg Kroah-Hartman  * (with the default interval) if the target is an interrupt endpoint.
358626f090cSYacine Belkadi  *
359626f090cSYacine Belkadi  * Return:
360626f090cSYacine Belkadi  * If successful, 0. Otherwise a negative error number. The number of actual
361025d4430SRahul Bedarkar  * bytes transferred will be stored in the @actual_length parameter.
362626f090cSYacine Belkadi  *
3631da177e4SLinus Torvalds  */
usb_bulk_msg(struct usb_device * usb_dev,unsigned int pipe,void * data,int len,int * actual_length,int timeout)3641da177e4SLinus Torvalds int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
3651da177e4SLinus Torvalds 		 void *data, int len, int *actual_length, int timeout)
3661da177e4SLinus Torvalds {
3671da177e4SLinus Torvalds 	struct urb *urb;
368d09d36a9SAlan Stern 	struct usb_host_endpoint *ep;
3691da177e4SLinus Torvalds 
370fe54b058SMatthew Wilcox 	ep = usb_pipe_endpoint(usb_dev, pipe);
371d09d36a9SAlan Stern 	if (!ep || len < 0)
3721da177e4SLinus Torvalds 		return -EINVAL;
3731da177e4SLinus Torvalds 
3741da177e4SLinus Torvalds 	urb = usb_alloc_urb(0, GFP_KERNEL);
3751da177e4SLinus Torvalds 	if (!urb)
3761da177e4SLinus Torvalds 		return -ENOMEM;
3771da177e4SLinus Torvalds 
378d09d36a9SAlan Stern 	if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
379d09d36a9SAlan Stern 			USB_ENDPOINT_XFER_INT) {
380d09d36a9SAlan Stern 		pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
381d09d36a9SAlan Stern 		usb_fill_int_urb(urb, usb_dev, pipe, data, len,
3828d062b9aSAlan Stern 				usb_api_blocking_completion, NULL,
3838d062b9aSAlan Stern 				ep->desc.bInterval);
384d09d36a9SAlan Stern 	} else
3851da177e4SLinus Torvalds 		usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
3861da177e4SLinus Torvalds 				usb_api_blocking_completion, NULL);
3871da177e4SLinus Torvalds 
3881da177e4SLinus Torvalds 	return usb_start_wait_urb(urb, timeout, actual_length);
3891da177e4SLinus Torvalds }
390782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_bulk_msg);
3911da177e4SLinus Torvalds 
3921da177e4SLinus Torvalds /*-------------------------------------------------------------------*/
3931da177e4SLinus Torvalds 
sg_clean(struct usb_sg_request * io)3941da177e4SLinus Torvalds static void sg_clean(struct usb_sg_request *io)
3951da177e4SLinus Torvalds {
3961da177e4SLinus Torvalds 	if (io->urbs) {
3971da177e4SLinus Torvalds 		while (io->entries--)
3981da177e4SLinus Torvalds 			usb_free_urb(io->urbs[io->entries]);
3991da177e4SLinus Torvalds 		kfree(io->urbs);
4001da177e4SLinus Torvalds 		io->urbs = NULL;
4011da177e4SLinus Torvalds 	}
4021da177e4SLinus Torvalds 	io->dev = NULL;
4031da177e4SLinus Torvalds }
4041da177e4SLinus Torvalds 
sg_complete(struct urb * urb)4057d12e780SDavid Howells static void sg_complete(struct urb *urb)
4061da177e4SLinus Torvalds {
40731adcb0aSSebastian Andrzej Siewior 	unsigned long flags;
408ec17cf1cSTobias Klauser 	struct usb_sg_request *io = urb->context;
4093fc3e826SGreg Kroah-Hartman 	int status = urb->status;
4101da177e4SLinus Torvalds 
41131adcb0aSSebastian Andrzej Siewior 	spin_lock_irqsave(&io->lock, flags);
4121da177e4SLinus Torvalds 
4131da177e4SLinus Torvalds 	/* In 2.5 we require hcds' endpoint queues not to progress after fault
4141da177e4SLinus Torvalds 	 * reports, until the completion callback (this!) returns.  That lets
4151da177e4SLinus Torvalds 	 * device driver code (like this routine) unlink queued urbs first,
4161da177e4SLinus Torvalds 	 * if it needs to, since the HC won't work on them at all.  So it's
4171da177e4SLinus Torvalds 	 * not possible for page N+1 to overwrite page N, and so on.
4181da177e4SLinus Torvalds 	 *
4191da177e4SLinus Torvalds 	 * That's only for "hard" faults; "soft" faults (unlinks) sometimes
4201da177e4SLinus Torvalds 	 * complete before the HCD can get requests away from hardware,
4211da177e4SLinus Torvalds 	 * though never during cleanup after a hard fault.
4221da177e4SLinus Torvalds 	 */
4231da177e4SLinus Torvalds 	if (io->status
4241da177e4SLinus Torvalds 			&& (io->status != -ECONNRESET
4253fc3e826SGreg Kroah-Hartman 				|| status != -ECONNRESET)
4261da177e4SLinus Torvalds 			&& urb->actual_length) {
4271da177e4SLinus Torvalds 		dev_err(io->dev->bus->controller,
4281da177e4SLinus Torvalds 			"dev %s ep%d%s scatterlist error %d/%d\n",
4291da177e4SLinus Torvalds 			io->dev->devpath,
4305e60a161SAlan Stern 			usb_endpoint_num(&urb->ep->desc),
4315e60a161SAlan Stern 			usb_urb_dir_in(urb) ? "in" : "out",
4323fc3e826SGreg Kroah-Hartman 			status, io->status);
4333e35bf39SGreg Kroah-Hartman 		/* BUG (); */
4341da177e4SLinus Torvalds 	}
4351da177e4SLinus Torvalds 
4363fc3e826SGreg Kroah-Hartman 	if (io->status == 0 && status && status != -ECONNRESET) {
4373fc3e826SGreg Kroah-Hartman 		int i, found, retval;
4381da177e4SLinus Torvalds 
4393fc3e826SGreg Kroah-Hartman 		io->status = status;
4401da177e4SLinus Torvalds 
4411da177e4SLinus Torvalds 		/* the previous urbs, and this one, completed already.
4421da177e4SLinus Torvalds 		 * unlink pending urbs so they won't rx/tx bad data.
4431da177e4SLinus Torvalds 		 * careful: unlink can sometimes be synchronous...
4441da177e4SLinus Torvalds 		 */
44531adcb0aSSebastian Andrzej Siewior 		spin_unlock_irqrestore(&io->lock, flags);
4461da177e4SLinus Torvalds 		for (i = 0, found = 0; i < io->entries; i++) {
44798b74b0eSDavid Mosberger 			if (!io->urbs[i])
4481da177e4SLinus Torvalds 				continue;
4491da177e4SLinus Torvalds 			if (found) {
45098b74b0eSDavid Mosberger 				usb_block_urb(io->urbs[i]);
4513fc3e826SGreg Kroah-Hartman 				retval = usb_unlink_urb(io->urbs[i]);
4523fc3e826SGreg Kroah-Hartman 				if (retval != -EINPROGRESS &&
4533fc3e826SGreg Kroah-Hartman 				    retval != -ENODEV &&
454bcf39853SAlan Stern 				    retval != -EBUSY &&
455bcf39853SAlan Stern 				    retval != -EIDRM)
4561da177e4SLinus Torvalds 					dev_err(&io->dev->dev,
4571da177e4SLinus Torvalds 						"%s, unlink --> %d\n",
458441b62c1SHarvey Harrison 						__func__, retval);
4591da177e4SLinus Torvalds 			} else if (urb == io->urbs[i])
4601da177e4SLinus Torvalds 				found = 1;
4611da177e4SLinus Torvalds 		}
46231adcb0aSSebastian Andrzej Siewior 		spin_lock_irqsave(&io->lock, flags);
4631da177e4SLinus Torvalds 	}
4641da177e4SLinus Torvalds 
4651da177e4SLinus Torvalds 	/* on the last completion, signal usb_sg_wait() */
4661da177e4SLinus Torvalds 	io->bytes += urb->actual_length;
4671da177e4SLinus Torvalds 	io->count--;
4681da177e4SLinus Torvalds 	if (!io->count)
4691da177e4SLinus Torvalds 		complete(&io->complete);
4701da177e4SLinus Torvalds 
47131adcb0aSSebastian Andrzej Siewior 	spin_unlock_irqrestore(&io->lock, flags);
4721da177e4SLinus Torvalds }
4731da177e4SLinus Torvalds 
4741da177e4SLinus Torvalds 
4751da177e4SLinus Torvalds /**
4761da177e4SLinus Torvalds  * usb_sg_init - initializes scatterlist-based bulk/interrupt I/O request
4771da177e4SLinus Torvalds  * @io: request block being initialized.  until usb_sg_wait() returns,
4781da177e4SLinus Torvalds  *	treat this as a pointer to an opaque block of memory,
4791da177e4SLinus Torvalds  * @dev: the usb device that will send or receive the data
4801da177e4SLinus Torvalds  * @pipe: endpoint "pipe" used to transfer the data
4811da177e4SLinus Torvalds  * @period: polling rate for interrupt endpoints, in frames or
4821da177e4SLinus Torvalds  * 	(for high speed endpoints) microframes; ignored for bulk
4831da177e4SLinus Torvalds  * @sg: scatterlist entries
4841da177e4SLinus Torvalds  * @nents: how many entries in the scatterlist
4851da177e4SLinus Torvalds  * @length: how many bytes to send from the scatterlist, or zero to
4861da177e4SLinus Torvalds  * 	send every byte identified in the list.
4871da177e4SLinus Torvalds  * @mem_flags: SLAB_* flags affecting memory allocations in this call
4881da177e4SLinus Torvalds  *
489626f090cSYacine Belkadi  * This initializes a scatter/gather request, allocating resources such as
490626f090cSYacine Belkadi  * I/O mappings and urb memory (except maybe memory used by USB controller
491626f090cSYacine Belkadi  * drivers).
4921da177e4SLinus Torvalds  *
4931da177e4SLinus Torvalds  * The request must be issued using usb_sg_wait(), which waits for the I/O to
4941da177e4SLinus Torvalds  * complete (or to be canceled) and then cleans up all resources allocated by
4951da177e4SLinus Torvalds  * usb_sg_init().
4961da177e4SLinus Torvalds  *
4971da177e4SLinus Torvalds  * The request may be canceled with usb_sg_cancel(), either before or after
4981da177e4SLinus Torvalds  * usb_sg_wait() is called.
499626f090cSYacine Belkadi  *
500626f090cSYacine Belkadi  * Return: Zero for success, else a negative errno value.
5011da177e4SLinus Torvalds  */
usb_sg_init(struct usb_sg_request * io,struct usb_device * dev,unsigned pipe,unsigned period,struct scatterlist * sg,int nents,size_t length,gfp_t mem_flags)5023e35bf39SGreg Kroah-Hartman int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
5033e35bf39SGreg Kroah-Hartman 		unsigned pipe, unsigned	period, struct scatterlist *sg,
5043e35bf39SGreg Kroah-Hartman 		int nents, size_t length, gfp_t mem_flags)
5051da177e4SLinus Torvalds {
5061da177e4SLinus Torvalds 	int i;
5071da177e4SLinus Torvalds 	int urb_flags;
508e04748e3SSarah Sharp 	int use_sg;
5091da177e4SLinus Torvalds 
5101da177e4SLinus Torvalds 	if (!io || !dev || !sg
5111da177e4SLinus Torvalds 			|| usb_pipecontrol(pipe)
5121da177e4SLinus Torvalds 			|| usb_pipeisoc(pipe)
5131da177e4SLinus Torvalds 			|| nents <= 0)
5141da177e4SLinus Torvalds 		return -EINVAL;
5151da177e4SLinus Torvalds 
5161da177e4SLinus Torvalds 	spin_lock_init(&io->lock);
5171da177e4SLinus Torvalds 	io->dev = dev;
5181da177e4SLinus Torvalds 	io->pipe = pipe;
5190ba169afSAlan Stern 
5200ba169afSAlan Stern 	if (dev->bus->sg_tablesize > 0) {
5210ba169afSAlan Stern 		use_sg = true;
5220ba169afSAlan Stern 		io->entries = 1;
5230ba169afSAlan Stern 	} else {
5240ba169afSAlan Stern 		use_sg = false;
5251da177e4SLinus Torvalds 		io->entries = nents;
5260ba169afSAlan Stern 	}
5271da177e4SLinus Torvalds 
5281da177e4SLinus Torvalds 	/* initialize all the urbs we'll use */
5296da2ec56SKees Cook 	io->urbs = kmalloc_array(io->entries, sizeof(*io->urbs), mem_flags);
5301da177e4SLinus Torvalds 	if (!io->urbs)
5311da177e4SLinus Torvalds 		goto nomem;
5321da177e4SLinus Torvalds 
5330ba169afSAlan Stern 	urb_flags = URB_NO_INTERRUPT;
5341da177e4SLinus Torvalds 	if (usb_pipein(pipe))
5351da177e4SLinus Torvalds 		urb_flags |= URB_SHORT_NOT_OK;
5361da177e4SLinus Torvalds 
537e04748e3SSarah Sharp 	for_each_sg(sg, sg, io->entries, i) {
5380ba169afSAlan Stern 		struct urb *urb;
5391da177e4SLinus Torvalds 		unsigned len;
5401da177e4SLinus Torvalds 
5410ba169afSAlan Stern 		urb = usb_alloc_urb(0, mem_flags);
5420ba169afSAlan Stern 		if (!urb) {
5431da177e4SLinus Torvalds 			io->entries = i;
5441da177e4SLinus Torvalds 			goto nomem;
5451da177e4SLinus Torvalds 		}
5460ba169afSAlan Stern 		io->urbs[i] = urb;
5471da177e4SLinus Torvalds 
5480ba169afSAlan Stern 		urb->dev = NULL;
5490ba169afSAlan Stern 		urb->pipe = pipe;
5500ba169afSAlan Stern 		urb->interval = period;
5510ba169afSAlan Stern 		urb->transfer_flags = urb_flags;
5520ba169afSAlan Stern 		urb->complete = sg_complete;
5530ba169afSAlan Stern 		urb->context = io;
5540ba169afSAlan Stern 		urb->sg = sg;
5551da177e4SLinus Torvalds 
5560ba169afSAlan Stern 		if (use_sg) {
5570ba169afSAlan Stern 			/* There is no single transfer buffer */
5580ba169afSAlan Stern 			urb->transfer_buffer = NULL;
5590ba169afSAlan Stern 			urb->num_sgs = nents;
5601da177e4SLinus Torvalds 
5610ba169afSAlan Stern 			/* A length of zero means transfer the whole sg list */
5620ba169afSAlan Stern 			len = length;
5630ba169afSAlan Stern 			if (len == 0) {
56464d65872SAlan Stern 				struct scatterlist	*sg2;
56564d65872SAlan Stern 				int			j;
56664d65872SAlan Stern 
56764d65872SAlan Stern 				for_each_sg(sg, sg2, nents, j)
56864d65872SAlan Stern 					len += sg2->length;
5690ba169afSAlan Stern 			}
5700ba169afSAlan Stern 		} else {
57135d07fd5STony Lindgren 			/*
572ff9c895fSAlan Stern 			 * Some systems can't use DMA; they use PIO instead.
573ff9c895fSAlan Stern 			 * For their sakes, transfer_buffer is set whenever
574ff9c895fSAlan Stern 			 * possible.
57535d07fd5STony Lindgren 			 */
576ff9c895fSAlan Stern 			if (!PageHighMem(sg_page(sg)))
5770ba169afSAlan Stern 				urb->transfer_buffer = sg_virt(sg);
57881bf46f3SPete Zaitcev 			else
5790ba169afSAlan Stern 				urb->transfer_buffer = NULL;
58081bf46f3SPete Zaitcev 
5817c3e28bcSAlan Stern 			len = sg->length;
5821da177e4SLinus Torvalds 			if (length) {
583edb2b255SDan Carpenter 				len = min_t(size_t, len, length);
5841da177e4SLinus Torvalds 				length -= len;
5851da177e4SLinus Torvalds 				if (length == 0)
5861da177e4SLinus Torvalds 					io->entries = i + 1;
5871da177e4SLinus Torvalds 			}
5880ba169afSAlan Stern 		}
5890ba169afSAlan Stern 		urb->transfer_buffer_length = len;
5901da177e4SLinus Torvalds 	}
5911da177e4SLinus Torvalds 	io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT;
5921da177e4SLinus Torvalds 
5931da177e4SLinus Torvalds 	/* transaction state */
594580da348SAlan Stern 	io->count = io->entries;
5951da177e4SLinus Torvalds 	io->status = 0;
5961da177e4SLinus Torvalds 	io->bytes = 0;
5971da177e4SLinus Torvalds 	init_completion(&io->complete);
5981da177e4SLinus Torvalds 	return 0;
5991da177e4SLinus Torvalds 
6001da177e4SLinus Torvalds nomem:
6011da177e4SLinus Torvalds 	sg_clean(io);
6021da177e4SLinus Torvalds 	return -ENOMEM;
6031da177e4SLinus Torvalds }
604782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_sg_init);
6051da177e4SLinus Torvalds 
6061da177e4SLinus Torvalds /**
6071da177e4SLinus Torvalds  * usb_sg_wait - synchronously execute scatter/gather request
6081da177e4SLinus Torvalds  * @io: request block handle, as initialized with usb_sg_init().
6091da177e4SLinus Torvalds  * 	some fields become accessible when this call returns.
61041631d36SAhmed S. Darwish  *
61141631d36SAhmed S. Darwish  * Context: task context, might sleep.
6121da177e4SLinus Torvalds  *
6131da177e4SLinus Torvalds  * This function blocks until the specified I/O operation completes.  It
6141da177e4SLinus Torvalds  * leverages the grouping of the related I/O requests to get good transfer
6151da177e4SLinus Torvalds  * rates, by queueing the requests.  At higher speeds, such queuing can
6161da177e4SLinus Torvalds  * significantly improve USB throughput.
6171da177e4SLinus Torvalds  *
6181da177e4SLinus Torvalds  * There are three kinds of completion for this function.
619e0c34e90SMauro Carvalho Chehab  *
6201da177e4SLinus Torvalds  * (1) success, where io->status is zero.  The number of io->bytes
6211da177e4SLinus Torvalds  *     transferred is as requested.
6221da177e4SLinus Torvalds  * (2) error, where io->status is a negative errno value.  The number
6231da177e4SLinus Torvalds  *     of io->bytes transferred before the error is usually less
6241da177e4SLinus Torvalds  *     than requested, and can be nonzero.
625093cf723SSteven Cole  * (3) cancellation, a type of error with status -ECONNRESET that
6261da177e4SLinus Torvalds  *     is initiated by usb_sg_cancel().
6271da177e4SLinus Torvalds  *
6281da177e4SLinus Torvalds  * When this function returns, all memory allocated through usb_sg_init() or
6291da177e4SLinus Torvalds  * this call will have been freed.  The request block parameter may still be
6301da177e4SLinus Torvalds  * passed to usb_sg_cancel(), or it may be freed.  It could also be
6311da177e4SLinus Torvalds  * reinitialized and then reused.
6321da177e4SLinus Torvalds  *
6331da177e4SLinus Torvalds  * Data Transfer Rates:
6341da177e4SLinus Torvalds  *
6351da177e4SLinus Torvalds  * Bulk transfers are valid for full or high speed endpoints.
6361da177e4SLinus Torvalds  * The best full speed data rate is 19 packets of 64 bytes each
6371da177e4SLinus Torvalds  * per frame, or 1216 bytes per millisecond.
6381da177e4SLinus Torvalds  * The best high speed data rate is 13 packets of 512 bytes each
6391da177e4SLinus Torvalds  * per microframe, or 52 KBytes per millisecond.
6401da177e4SLinus Torvalds  *
6411da177e4SLinus Torvalds  * The reason to use interrupt transfers through this API would most likely
6421da177e4SLinus Torvalds  * be to reserve high speed bandwidth, where up to 24 KBytes per millisecond
6431da177e4SLinus Torvalds  * could be transferred.  That capability is less useful for low or full
6441da177e4SLinus Torvalds  * speed interrupt endpoints, which allow at most one packet per millisecond,
6451da177e4SLinus Torvalds  * of at most 8 or 64 bytes (respectively).
64679abb1abSSarah Sharp  *
64779abb1abSSarah Sharp  * It is not necessary to call this function to reserve bandwidth for devices
64879abb1abSSarah Sharp  * under an xHCI host controller, as the bandwidth is reserved when the
64979abb1abSSarah Sharp  * configuration or interface alt setting is selected.
6501da177e4SLinus Torvalds  */
usb_sg_wait(struct usb_sg_request * io)6511da177e4SLinus Torvalds void usb_sg_wait(struct usb_sg_request *io)
6521da177e4SLinus Torvalds {
6533e35bf39SGreg Kroah-Hartman 	int i;
6543e35bf39SGreg Kroah-Hartman 	int entries = io->entries;
6551da177e4SLinus Torvalds 
6561da177e4SLinus Torvalds 	/* queue the urbs.  */
6571da177e4SLinus Torvalds 	spin_lock_irq(&io->lock);
6588ccef0dfSAlan Stern 	i = 0;
6598ccef0dfSAlan Stern 	while (i < entries && !io->status) {
6601da177e4SLinus Torvalds 		int retval;
6611da177e4SLinus Torvalds 
6621da177e4SLinus Torvalds 		io->urbs[i]->dev = io->dev;
6631da177e4SLinus Torvalds 		spin_unlock_irq(&io->lock);
66498b74b0eSDavid Mosberger 
66598b74b0eSDavid Mosberger 		retval = usb_submit_urb(io->urbs[i], GFP_NOIO);
66698b74b0eSDavid Mosberger 
6671da177e4SLinus Torvalds 		switch (retval) {
6681da177e4SLinus Torvalds 			/* maybe we retrying will recover */
6693e35bf39SGreg Kroah-Hartman 		case -ENXIO:	/* hc didn't queue this one */
6701da177e4SLinus Torvalds 		case -EAGAIN:
6711da177e4SLinus Torvalds 		case -ENOMEM:
6721da177e4SLinus Torvalds 			retval = 0;
6731da177e4SLinus Torvalds 			yield();
6741da177e4SLinus Torvalds 			break;
6751da177e4SLinus Torvalds 
6761da177e4SLinus Torvalds 			/* no error? continue immediately.
6771da177e4SLinus Torvalds 			 *
6781da177e4SLinus Torvalds 			 * NOTE: to work better with UHCI (4K I/O buffer may
6791da177e4SLinus Torvalds 			 * need 3K of TDs) it may be good to limit how many
6801da177e4SLinus Torvalds 			 * URBs are queued at once; N milliseconds?
6811da177e4SLinus Torvalds 			 */
6821da177e4SLinus Torvalds 		case 0:
6838ccef0dfSAlan Stern 			++i;
6841da177e4SLinus Torvalds 			cpu_relax();
6851da177e4SLinus Torvalds 			break;
6861da177e4SLinus Torvalds 
6871da177e4SLinus Torvalds 			/* fail any uncompleted urbs */
6881da177e4SLinus Torvalds 		default:
6891da177e4SLinus Torvalds 			io->urbs[i]->status = retval;
6901da177e4SLinus Torvalds 			dev_dbg(&io->dev->dev, "%s, submit --> %d\n",
691441b62c1SHarvey Harrison 				__func__, retval);
6921da177e4SLinus Torvalds 			usb_sg_cancel(io);
6931da177e4SLinus Torvalds 		}
6941da177e4SLinus Torvalds 		spin_lock_irq(&io->lock);
6951da177e4SLinus Torvalds 		if (retval && (io->status == 0 || io->status == -ECONNRESET))
6961da177e4SLinus Torvalds 			io->status = retval;
6971da177e4SLinus Torvalds 	}
6981da177e4SLinus Torvalds 	io->count -= entries - i;
6991da177e4SLinus Torvalds 	if (io->count == 0)
7001da177e4SLinus Torvalds 		complete(&io->complete);
7011da177e4SLinus Torvalds 	spin_unlock_irq(&io->lock);
7021da177e4SLinus Torvalds 
7031da177e4SLinus Torvalds 	/* OK, yes, this could be packaged as non-blocking.
7041da177e4SLinus Torvalds 	 * So could the submit loop above ... but it's easier to
7051da177e4SLinus Torvalds 	 * solve neither problem than to solve both!
7061da177e4SLinus Torvalds 	 */
7071da177e4SLinus Torvalds 	wait_for_completion(&io->complete);
7081da177e4SLinus Torvalds 
7091da177e4SLinus Torvalds 	sg_clean(io);
7101da177e4SLinus Torvalds }
711782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_sg_wait);
7121da177e4SLinus Torvalds 
7131da177e4SLinus Torvalds /**
7141da177e4SLinus Torvalds  * usb_sg_cancel - stop scatter/gather i/o issued by usb_sg_wait()
7151da177e4SLinus Torvalds  * @io: request block, initialized with usb_sg_init()
7161da177e4SLinus Torvalds  *
7171da177e4SLinus Torvalds  * This stops a request after it has been started by usb_sg_wait().
7181da177e4SLinus Torvalds  * It can also prevents one initialized by usb_sg_init() from starting,
7191da177e4SLinus Torvalds  * so that call just frees resources allocated to the request.
7201da177e4SLinus Torvalds  */
usb_sg_cancel(struct usb_sg_request * io)7211da177e4SLinus Torvalds void usb_sg_cancel(struct usb_sg_request *io)
7221da177e4SLinus Torvalds {
7231da177e4SLinus Torvalds 	unsigned long flags;
7245f2e5fb8SDavid Mosberger 	int i, retval;
7251da177e4SLinus Torvalds 
7261da177e4SLinus Torvalds 	spin_lock_irqsave(&io->lock, flags);
727056ad39eSAlan Stern 	if (io->status || io->count == 0) {
7285f2e5fb8SDavid Mosberger 		spin_unlock_irqrestore(&io->lock, flags);
7295f2e5fb8SDavid Mosberger 		return;
7305f2e5fb8SDavid Mosberger 	}
7315f2e5fb8SDavid Mosberger 	/* shut everything down */
7321da177e4SLinus Torvalds 	io->status = -ECONNRESET;
733056ad39eSAlan Stern 	io->count++;		/* Keep the request alive until we're done */
7345f2e5fb8SDavid Mosberger 	spin_unlock_irqrestore(&io->lock, flags);
7351da177e4SLinus Torvalds 
7365f2e5fb8SDavid Mosberger 	for (i = io->entries - 1; i >= 0; --i) {
73798b74b0eSDavid Mosberger 		usb_block_urb(io->urbs[i]);
73898b74b0eSDavid Mosberger 
7391da177e4SLinus Torvalds 		retval = usb_unlink_urb(io->urbs[i]);
740bcf39853SAlan Stern 		if (retval != -EINPROGRESS
741bcf39853SAlan Stern 		    && retval != -ENODEV
742bcf39853SAlan Stern 		    && retval != -EBUSY
743bcf39853SAlan Stern 		    && retval != -EIDRM)
7441da177e4SLinus Torvalds 			dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
745441b62c1SHarvey Harrison 				 __func__, retval);
7461da177e4SLinus Torvalds 	}
747056ad39eSAlan Stern 
748056ad39eSAlan Stern 	spin_lock_irqsave(&io->lock, flags);
749056ad39eSAlan Stern 	io->count--;
750056ad39eSAlan Stern 	if (!io->count)
751056ad39eSAlan Stern 		complete(&io->complete);
752056ad39eSAlan Stern 	spin_unlock_irqrestore(&io->lock, flags);
7531da177e4SLinus Torvalds }
754782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_sg_cancel);
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds /*-------------------------------------------------------------------*/
7571da177e4SLinus Torvalds 
7581da177e4SLinus Torvalds /**
7591da177e4SLinus Torvalds  * usb_get_descriptor - issues a generic GET_DESCRIPTOR request
7601da177e4SLinus Torvalds  * @dev: the device whose descriptor is being retrieved
7611da177e4SLinus Torvalds  * @type: the descriptor type (USB_DT_*)
7621da177e4SLinus Torvalds  * @index: the number of the descriptor
7631da177e4SLinus Torvalds  * @buf: where to put the descriptor
7641da177e4SLinus Torvalds  * @size: how big is "buf"?
76541631d36SAhmed S. Darwish  *
76641631d36SAhmed S. Darwish  * Context: task context, might sleep.
7671da177e4SLinus Torvalds  *
7681da177e4SLinus Torvalds  * Gets a USB descriptor.  Convenience functions exist to simplify
7691da177e4SLinus Torvalds  * getting some types of descriptors.  Use
7701da177e4SLinus Torvalds  * usb_get_string() or usb_string() for USB_DT_STRING.
7711da177e4SLinus Torvalds  * Device (USB_DT_DEVICE) and configuration descriptors (USB_DT_CONFIG)
7721da177e4SLinus Torvalds  * are part of the device structure.
7731da177e4SLinus Torvalds  * In addition to a number of USB-standard descriptors, some
7741da177e4SLinus Torvalds  * devices also use class-specific or vendor-specific descriptors.
7751da177e4SLinus Torvalds  *
7761da177e4SLinus Torvalds  * This call is synchronous, and may not be used in an interrupt context.
7771da177e4SLinus Torvalds  *
778626f090cSYacine Belkadi  * Return: The number of bytes received on success, or else the status code
7791da177e4SLinus Torvalds  * returned by the underlying usb_control_msg() call.
7801da177e4SLinus Torvalds  */
usb_get_descriptor(struct usb_device * dev,unsigned char type,unsigned char index,void * buf,int size)7813e35bf39SGreg Kroah-Hartman int usb_get_descriptor(struct usb_device *dev, unsigned char type,
7823e35bf39SGreg Kroah-Hartman 		       unsigned char index, void *buf, int size)
7831da177e4SLinus Torvalds {
7841da177e4SLinus Torvalds 	int i;
7851da177e4SLinus Torvalds 	int result;
7861da177e4SLinus Torvalds 
78760dfe484SAlan Stern 	if (size <= 0)		/* No point in asking for no data */
78860dfe484SAlan Stern 		return -EINVAL;
78960dfe484SAlan Stern 
7903e35bf39SGreg Kroah-Hartman 	memset(buf, 0, size);	/* Make sure we parse really received data */
7911da177e4SLinus Torvalds 
7921da177e4SLinus Torvalds 	for (i = 0; i < 3; ++i) {
793c39772d8SAlan Stern 		/* retry on length 0 or error; some devices are flakey */
7941da177e4SLinus Torvalds 		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
7951da177e4SLinus Torvalds 				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
7961da177e4SLinus Torvalds 				(type << 8) + index, 0, buf, size,
7971da177e4SLinus Torvalds 				USB_CTRL_GET_TIMEOUT);
798c39772d8SAlan Stern 		if (result <= 0 && result != -ETIMEDOUT)
7991da177e4SLinus Torvalds 			continue;
8001da177e4SLinus Torvalds 		if (result > 1 && ((u8 *)buf)[1] != type) {
80167f5a4baSAlan Stern 			result = -ENODATA;
8021da177e4SLinus Torvalds 			continue;
8031da177e4SLinus Torvalds 		}
8041da177e4SLinus Torvalds 		break;
8051da177e4SLinus Torvalds 	}
8061da177e4SLinus Torvalds 	return result;
8071da177e4SLinus Torvalds }
808782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_get_descriptor);
8091da177e4SLinus Torvalds 
8101da177e4SLinus Torvalds /**
8111da177e4SLinus Torvalds  * usb_get_string - gets a string descriptor
8121da177e4SLinus Torvalds  * @dev: the device whose string descriptor is being retrieved
8131da177e4SLinus Torvalds  * @langid: code for language chosen (from string descriptor zero)
8141da177e4SLinus Torvalds  * @index: the number of the descriptor
8151da177e4SLinus Torvalds  * @buf: where to put the string
8161da177e4SLinus Torvalds  * @size: how big is "buf"?
81741631d36SAhmed S. Darwish  *
81841631d36SAhmed S. Darwish  * Context: task context, might sleep.
8191da177e4SLinus Torvalds  *
8201da177e4SLinus Torvalds  * Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character,
8211da177e4SLinus Torvalds  * in little-endian byte order).
8221da177e4SLinus Torvalds  * The usb_string() function will often be a convenient way to turn
8231da177e4SLinus Torvalds  * these strings into kernel-printable form.
8241da177e4SLinus Torvalds  *
8251da177e4SLinus Torvalds  * Strings may be referenced in device, configuration, interface, or other
8261da177e4SLinus Torvalds  * descriptors, and could also be used in vendor-specific ways.
8271da177e4SLinus Torvalds  *
8281da177e4SLinus Torvalds  * This call is synchronous, and may not be used in an interrupt context.
8291da177e4SLinus Torvalds  *
830626f090cSYacine Belkadi  * Return: The number of bytes received on success, or else the status code
8311da177e4SLinus Torvalds  * returned by the underlying usb_control_msg() call.
8321da177e4SLinus Torvalds  */
usb_get_string(struct usb_device * dev,unsigned short langid,unsigned char index,void * buf,int size)833e266a124SAdrian Bunk static int usb_get_string(struct usb_device *dev, unsigned short langid,
8341da177e4SLinus Torvalds 			  unsigned char index, void *buf, int size)
8351da177e4SLinus Torvalds {
8361da177e4SLinus Torvalds 	int i;
8371da177e4SLinus Torvalds 	int result;
8381da177e4SLinus Torvalds 
83960dfe484SAlan Stern 	if (size <= 0)		/* No point in asking for no data */
84060dfe484SAlan Stern 		return -EINVAL;
84160dfe484SAlan Stern 
8421da177e4SLinus Torvalds 	for (i = 0; i < 3; ++i) {
8431da177e4SLinus Torvalds 		/* retry on length 0 or stall; some devices are flakey */
8441da177e4SLinus Torvalds 		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
8451da177e4SLinus Torvalds 			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
8461da177e4SLinus Torvalds 			(USB_DT_STRING << 8) + index, langid, buf, size,
8471da177e4SLinus Torvalds 			USB_CTRL_GET_TIMEOUT);
84867f5a4baSAlan Stern 		if (result == 0 || result == -EPIPE)
84967f5a4baSAlan Stern 			continue;
85067f5a4baSAlan Stern 		if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) {
85167f5a4baSAlan Stern 			result = -ENODATA;
85267f5a4baSAlan Stern 			continue;
85367f5a4baSAlan Stern 		}
8541da177e4SLinus Torvalds 		break;
8551da177e4SLinus Torvalds 	}
8561da177e4SLinus Torvalds 	return result;
8571da177e4SLinus Torvalds }
8581da177e4SLinus Torvalds 
usb_try_string_workarounds(unsigned char * buf,int * length)8591da177e4SLinus Torvalds static void usb_try_string_workarounds(unsigned char *buf, int *length)
8601da177e4SLinus Torvalds {
8611da177e4SLinus Torvalds 	int newlength, oldlength = *length;
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds 	for (newlength = 2; newlength + 1 < oldlength; newlength += 2)
8641da177e4SLinus Torvalds 		if (!isprint(buf[newlength]) || buf[newlength + 1])
8651da177e4SLinus Torvalds 			break;
8661da177e4SLinus Torvalds 
8671da177e4SLinus Torvalds 	if (newlength > 2) {
8681da177e4SLinus Torvalds 		buf[0] = newlength;
8691da177e4SLinus Torvalds 		*length = newlength;
8701da177e4SLinus Torvalds 	}
8711da177e4SLinus Torvalds }
8721da177e4SLinus Torvalds 
usb_string_sub(struct usb_device * dev,unsigned int langid,unsigned int index,unsigned char * buf)8731da177e4SLinus Torvalds static int usb_string_sub(struct usb_device *dev, unsigned int langid,
8741da177e4SLinus Torvalds 			  unsigned int index, unsigned char *buf)
8751da177e4SLinus Torvalds {
8761da177e4SLinus Torvalds 	int rc;
8771da177e4SLinus Torvalds 
8781da177e4SLinus Torvalds 	/* Try to read the string descriptor by asking for the maximum
8791da177e4SLinus Torvalds 	 * possible number of bytes */
8807ceec1f1SOliver Neukum 	if (dev->quirks & USB_QUIRK_STRING_FETCH_255)
8817ceec1f1SOliver Neukum 		rc = -EIO;
8827ceec1f1SOliver Neukum 	else
8831da177e4SLinus Torvalds 		rc = usb_get_string(dev, langid, index, buf, 255);
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	/* If that failed try to read the descriptor length, then
8861da177e4SLinus Torvalds 	 * ask for just that many bytes */
8871da177e4SLinus Torvalds 	if (rc < 2) {
8881da177e4SLinus Torvalds 		rc = usb_get_string(dev, langid, index, buf, 2);
8891da177e4SLinus Torvalds 		if (rc == 2)
8901da177e4SLinus Torvalds 			rc = usb_get_string(dev, langid, index, buf, buf[0]);
8911da177e4SLinus Torvalds 	}
8921da177e4SLinus Torvalds 
8931da177e4SLinus Torvalds 	if (rc >= 2) {
8941da177e4SLinus Torvalds 		if (!buf[0] && !buf[1])
8951da177e4SLinus Torvalds 			usb_try_string_workarounds(buf, &rc);
8961da177e4SLinus Torvalds 
8971da177e4SLinus Torvalds 		/* There might be extra junk at the end of the descriptor */
8981da177e4SLinus Torvalds 		if (buf[0] < rc)
8991da177e4SLinus Torvalds 			rc = buf[0];
9001da177e4SLinus Torvalds 
9011da177e4SLinus Torvalds 		rc = rc - (rc & 1); /* force a multiple of two */
9021da177e4SLinus Torvalds 	}
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds 	if (rc < 2)
9051da177e4SLinus Torvalds 		rc = (rc < 0 ? rc : -EINVAL);
9061da177e4SLinus Torvalds 
9071da177e4SLinus Torvalds 	return rc;
9081da177e4SLinus Torvalds }
9091da177e4SLinus Torvalds 
usb_get_langid(struct usb_device * dev,unsigned char * tbuf)9100cce2edaSDaniel Mack static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
9110cce2edaSDaniel Mack {
9120cce2edaSDaniel Mack 	int err;
9130cce2edaSDaniel Mack 
9140cce2edaSDaniel Mack 	if (dev->have_langid)
9150cce2edaSDaniel Mack 		return 0;
9160cce2edaSDaniel Mack 
9170cce2edaSDaniel Mack 	if (dev->string_langid < 0)
9180cce2edaSDaniel Mack 		return -EPIPE;
9190cce2edaSDaniel Mack 
9200cce2edaSDaniel Mack 	err = usb_string_sub(dev, 0, 0, tbuf);
9210cce2edaSDaniel Mack 
9220cce2edaSDaniel Mack 	/* If the string was reported but is malformed, default to english
9230cce2edaSDaniel Mack 	 * (0x0409) */
9240cce2edaSDaniel Mack 	if (err == -ENODATA || (err > 0 && err < 4)) {
9250cce2edaSDaniel Mack 		dev->string_langid = 0x0409;
9260cce2edaSDaniel Mack 		dev->have_langid = 1;
9270cce2edaSDaniel Mack 		dev_err(&dev->dev,
928586af079SScot Doyle 			"language id specifier not provided by device, defaulting to English\n");
9290cce2edaSDaniel Mack 		return 0;
9300cce2edaSDaniel Mack 	}
9310cce2edaSDaniel Mack 
9320cce2edaSDaniel Mack 	/* In case of all other errors, we assume the device is not able to
9330cce2edaSDaniel Mack 	 * deal with strings at all. Set string_langid to -1 in order to
9340cce2edaSDaniel Mack 	 * prevent any string to be retrieved from the device */
9350cce2edaSDaniel Mack 	if (err < 0) {
9362124c888SKai-Heng Feng 		dev_info(&dev->dev, "string descriptor 0 read error: %d\n",
9370cce2edaSDaniel Mack 					err);
9380cce2edaSDaniel Mack 		dev->string_langid = -1;
9390cce2edaSDaniel Mack 		return -EPIPE;
9400cce2edaSDaniel Mack 	}
9410cce2edaSDaniel Mack 
9420cce2edaSDaniel Mack 	/* always use the first langid listed */
9430cce2edaSDaniel Mack 	dev->string_langid = tbuf[2] | (tbuf[3] << 8);
9440cce2edaSDaniel Mack 	dev->have_langid = 1;
9450cce2edaSDaniel Mack 	dev_dbg(&dev->dev, "default language 0x%04x\n",
9460cce2edaSDaniel Mack 				dev->string_langid);
9470cce2edaSDaniel Mack 	return 0;
9480cce2edaSDaniel Mack }
9490cce2edaSDaniel Mack 
9501da177e4SLinus Torvalds /**
951a853a3d4SClemens Ladisch  * usb_string - returns UTF-8 version of a string descriptor
9521da177e4SLinus Torvalds  * @dev: the device whose string descriptor is being retrieved
9531da177e4SLinus Torvalds  * @index: the number of the descriptor
9541da177e4SLinus Torvalds  * @buf: where to put the string
9551da177e4SLinus Torvalds  * @size: how big is "buf"?
95641631d36SAhmed S. Darwish  *
95741631d36SAhmed S. Darwish  * Context: task context, might sleep.
9581da177e4SLinus Torvalds  *
9591da177e4SLinus Torvalds  * This converts the UTF-16LE encoded strings returned by devices, from
960a853a3d4SClemens Ladisch  * usb_get_string_descriptor(), to null-terminated UTF-8 encoded ones
961a853a3d4SClemens Ladisch  * that are more usable in most kernel contexts.  Note that this function
9621da177e4SLinus Torvalds  * chooses strings in the first language supported by the device.
9631da177e4SLinus Torvalds  *
9641da177e4SLinus Torvalds  * This call is synchronous, and may not be used in an interrupt context.
9651da177e4SLinus Torvalds  *
966626f090cSYacine Belkadi  * Return: length of the string (>= 0) or usb_control_msg status (< 0).
9671da177e4SLinus Torvalds  */
usb_string(struct usb_device * dev,int index,char * buf,size_t size)9681da177e4SLinus Torvalds int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
9691da177e4SLinus Torvalds {
9701da177e4SLinus Torvalds 	unsigned char *tbuf;
9711da177e4SLinus Torvalds 	int err;
9721da177e4SLinus Torvalds 
9731da177e4SLinus Torvalds 	if (dev->state == USB_STATE_SUSPENDED)
9741da177e4SLinus Torvalds 		return -EHOSTUNREACH;
975c01c348eSAlan Stern 	if (size <= 0 || !buf)
9761da177e4SLinus Torvalds 		return -EINVAL;
9771da177e4SLinus Torvalds 	buf[0] = 0;
978c01c348eSAlan Stern 	if (index <= 0 || index >= 256)
979c01c348eSAlan Stern 		return -EINVAL;
98074675a58SAlan Stern 	tbuf = kmalloc(256, GFP_NOIO);
9811da177e4SLinus Torvalds 	if (!tbuf)
9821da177e4SLinus Torvalds 		return -ENOMEM;
9831da177e4SLinus Torvalds 
9840cce2edaSDaniel Mack 	err = usb_get_langid(dev, tbuf);
9850cce2edaSDaniel Mack 	if (err < 0)
9860cce2edaSDaniel Mack 		goto errout;
9871da177e4SLinus Torvalds 
9881da177e4SLinus Torvalds 	err = usb_string_sub(dev, dev->string_langid, index, tbuf);
9891da177e4SLinus Torvalds 	if (err < 0)
9901da177e4SLinus Torvalds 		goto errout;
9911da177e4SLinus Torvalds 
9921da177e4SLinus Torvalds 	size--;		/* leave room for trailing NULL char in output buffer */
99374675a58SAlan Stern 	err = utf16s_to_utf8s((wchar_t *) &tbuf[2], (err - 2) / 2,
99474675a58SAlan Stern 			UTF16_LITTLE_ENDIAN, buf, size);
995a853a3d4SClemens Ladisch 	buf[err] = 0;
9961da177e4SLinus Torvalds 
9971da177e4SLinus Torvalds 	if (tbuf[1] != USB_DT_STRING)
9983e35bf39SGreg Kroah-Hartman 		dev_dbg(&dev->dev,
9993e35bf39SGreg Kroah-Hartman 			"wrong descriptor type %02x for string %d (\"%s\")\n",
10003e35bf39SGreg Kroah-Hartman 			tbuf[1], index, buf);
10011da177e4SLinus Torvalds 
10021da177e4SLinus Torvalds  errout:
10031da177e4SLinus Torvalds 	kfree(tbuf);
10041da177e4SLinus Torvalds 	return err;
10051da177e4SLinus Torvalds }
1006782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_string);
10071da177e4SLinus Torvalds 
1008a853a3d4SClemens Ladisch /* one UTF-8-encoded 16-bit character has at most three bytes */
1009a853a3d4SClemens Ladisch #define MAX_USB_STRING_SIZE (127 * 3 + 1)
1010a853a3d4SClemens Ladisch 
10114f62efe6SAlan Stern /**
10124f62efe6SAlan Stern  * usb_cache_string - read a string descriptor and cache it for later use
10134f62efe6SAlan Stern  * @udev: the device whose string descriptor is being read
10144f62efe6SAlan Stern  * @index: the descriptor index
10154f62efe6SAlan Stern  *
1016626f090cSYacine Belkadi  * Return: A pointer to a kmalloc'ed buffer containing the descriptor string,
1017626f090cSYacine Belkadi  * or %NULL if the index is 0 or the string could not be read.
10184f62efe6SAlan Stern  */
usb_cache_string(struct usb_device * udev,int index)10194f62efe6SAlan Stern char *usb_cache_string(struct usb_device *udev, int index)
10204f62efe6SAlan Stern {
10214f62efe6SAlan Stern 	char *buf;
10224f62efe6SAlan Stern 	char *smallbuf = NULL;
10234f62efe6SAlan Stern 	int len;
10244f62efe6SAlan Stern 
10253e35bf39SGreg Kroah-Hartman 	if (index <= 0)
10263e35bf39SGreg Kroah-Hartman 		return NULL;
10273e35bf39SGreg Kroah-Hartman 
1028acbe2febSOliver Neukum 	buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
10293e35bf39SGreg Kroah-Hartman 	if (buf) {
1030a853a3d4SClemens Ladisch 		len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
10313e35bf39SGreg Kroah-Hartman 		if (len > 0) {
1032acbe2febSOliver Neukum 			smallbuf = kmalloc(++len, GFP_NOIO);
10333e35bf39SGreg Kroah-Hartman 			if (!smallbuf)
10344f62efe6SAlan Stern 				return buf;
10354f62efe6SAlan Stern 			memcpy(smallbuf, buf, len);
10364f62efe6SAlan Stern 		}
10374f62efe6SAlan Stern 		kfree(buf);
10384f62efe6SAlan Stern 	}
10394f62efe6SAlan Stern 	return smallbuf;
10404f62efe6SAlan Stern }
1041983055bfSVincent Mailhol EXPORT_SYMBOL_GPL(usb_cache_string);
10424f62efe6SAlan Stern 
10431da177e4SLinus Torvalds /*
1044de28e469SAlan Stern  * usb_get_device_descriptor - read the device descriptor
1045de28e469SAlan Stern  * @udev: the device whose device descriptor should be read
104641631d36SAhmed S. Darwish  *
104741631d36SAhmed S. Darwish  * Context: task context, might sleep.
10481da177e4SLinus Torvalds  *
10491da177e4SLinus Torvalds  * Not exported, only for use by the core.  If drivers really want to read
10501da177e4SLinus Torvalds  * the device descriptor directly, they can call usb_get_descriptor() with
10511da177e4SLinus Torvalds  * type = USB_DT_DEVICE and index = 0.
10521da177e4SLinus Torvalds  *
1053de28e469SAlan Stern  * Returns: a pointer to a dynamically allocated usb_device_descriptor
1054de28e469SAlan Stern  * structure (which the caller must deallocate), or an ERR_PTR value.
10551da177e4SLinus Torvalds  */
usb_get_device_descriptor(struct usb_device * udev)1056de28e469SAlan Stern struct usb_device_descriptor *usb_get_device_descriptor(struct usb_device *udev)
10571da177e4SLinus Torvalds {
10581da177e4SLinus Torvalds 	struct usb_device_descriptor *desc;
10591da177e4SLinus Torvalds 	int ret;
10601da177e4SLinus Torvalds 
10611da177e4SLinus Torvalds 	desc = kmalloc(sizeof(*desc), GFP_NOIO);
10621da177e4SLinus Torvalds 	if (!desc)
1063de28e469SAlan Stern 		return ERR_PTR(-ENOMEM);
10641da177e4SLinus Torvalds 
1065de28e469SAlan Stern 	ret = usb_get_descriptor(udev, USB_DT_DEVICE, 0, desc, sizeof(*desc));
1066de28e469SAlan Stern 	if (ret == sizeof(*desc))
1067de28e469SAlan Stern 		return desc;
1068de28e469SAlan Stern 
10691da177e4SLinus Torvalds 	if (ret >= 0)
1070de28e469SAlan Stern 		ret = -EMSGSIZE;
10711da177e4SLinus Torvalds 	kfree(desc);
1072de28e469SAlan Stern 	return ERR_PTR(ret);
10731da177e4SLinus Torvalds }
10741da177e4SLinus Torvalds 
1075886ee36eSFelipe Balbi /*
1076886ee36eSFelipe Balbi  * usb_set_isoch_delay - informs the device of the packet transmit delay
1077886ee36eSFelipe Balbi  * @dev: the device whose delay is to be informed
107841631d36SAhmed S. Darwish  * Context: task context, might sleep
1079886ee36eSFelipe Balbi  *
1080886ee36eSFelipe Balbi  * Since this is an optional request, we don't bother if it fails.
1081886ee36eSFelipe Balbi  */
usb_set_isoch_delay(struct usb_device * dev)1082886ee36eSFelipe Balbi int usb_set_isoch_delay(struct usb_device *dev)
1083886ee36eSFelipe Balbi {
1084886ee36eSFelipe Balbi 	/* skip hub devices */
1085886ee36eSFelipe Balbi 	if (dev->descriptor.bDeviceClass == USB_CLASS_HUB)
1086886ee36eSFelipe Balbi 		return 0;
1087886ee36eSFelipe Balbi 
1088886ee36eSFelipe Balbi 	/* skip non-SS/non-SSP devices */
1089886ee36eSFelipe Balbi 	if (dev->speed < USB_SPEED_SUPER)
1090886ee36eSFelipe Balbi 		return 0;
1091886ee36eSFelipe Balbi 
1092297e84c0SGreg Kroah-Hartman 	return usb_control_msg_send(dev, 0,
1093886ee36eSFelipe Balbi 			USB_REQ_SET_ISOCH_DELAY,
1094886ee36eSFelipe Balbi 			USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
109548b73d0fSRuslan Bilovol 			dev->hub_delay, 0, NULL, 0,
1096ddd1198eSOliver Neukum 			USB_CTRL_SET_TIMEOUT,
1097ddd1198eSOliver Neukum 			GFP_NOIO);
1098886ee36eSFelipe Balbi }
1099886ee36eSFelipe Balbi 
11001da177e4SLinus Torvalds /**
11011da177e4SLinus Torvalds  * usb_get_status - issues a GET_STATUS call
11021da177e4SLinus Torvalds  * @dev: the device whose status is being checked
11033c377ef1SFelipe Balbi  * @recip: USB_RECIP_*; for device, interface, or endpoint
11042e43f0feSFelipe Balbi  * @type: USB_STATUS_TYPE_*; for standard or PTM status types
11051da177e4SLinus Torvalds  * @target: zero (for device), else interface or endpoint number
11061da177e4SLinus Torvalds  * @data: pointer to two bytes of bitmap data
110741631d36SAhmed S. Darwish  *
110841631d36SAhmed S. Darwish  * Context: task context, might sleep.
11091da177e4SLinus Torvalds  *
11101da177e4SLinus Torvalds  * Returns device, interface, or endpoint status.  Normally only of
11111da177e4SLinus Torvalds  * interest to see if the device is self powered, or has enabled the
11121da177e4SLinus Torvalds  * remote wakeup facility; or whether a bulk or interrupt endpoint
11131da177e4SLinus Torvalds  * is halted ("stalled").
11141da177e4SLinus Torvalds  *
11151da177e4SLinus Torvalds  * Bits in these status bitmaps are set using the SET_FEATURE request,
11161da177e4SLinus Torvalds  * and cleared using the CLEAR_FEATURE request.  The usb_clear_halt()
11171da177e4SLinus Torvalds  * function should be used to clear halt ("stall") status.
11181da177e4SLinus Torvalds  *
11191da177e4SLinus Torvalds  * This call is synchronous, and may not be used in an interrupt context.
11201da177e4SLinus Torvalds  *
112115b7336eSAlan Stern  * Returns 0 and the status value in *@data (in host byte order) on success,
112215b7336eSAlan Stern  * or else the status code from the underlying usb_control_msg() call.
11231da177e4SLinus Torvalds  */
usb_get_status(struct usb_device * dev,int recip,int type,int target,void * data)11242e43f0feSFelipe Balbi int usb_get_status(struct usb_device *dev, int recip, int type, int target,
11252e43f0feSFelipe Balbi 		void *data)
11261da177e4SLinus Torvalds {
11271da177e4SLinus Torvalds 	int ret;
11282e43f0feSFelipe Balbi 	void *status;
11292e43f0feSFelipe Balbi 	int length;
11301da177e4SLinus Torvalds 
11312e43f0feSFelipe Balbi 	switch (type) {
11322e43f0feSFelipe Balbi 	case USB_STATUS_TYPE_STANDARD:
11332e43f0feSFelipe Balbi 		length = 2;
11342e43f0feSFelipe Balbi 		break;
11352e43f0feSFelipe Balbi 	case USB_STATUS_TYPE_PTM:
11362e43f0feSFelipe Balbi 		if (recip != USB_RECIP_DEVICE)
11372e43f0feSFelipe Balbi 			return -EINVAL;
11382e43f0feSFelipe Balbi 
11392e43f0feSFelipe Balbi 		length = 4;
11402e43f0feSFelipe Balbi 		break;
11412e43f0feSFelipe Balbi 	default:
11422e43f0feSFelipe Balbi 		return -EINVAL;
11432e43f0feSFelipe Balbi 	}
11442e43f0feSFelipe Balbi 
11452e43f0feSFelipe Balbi 	status =  kmalloc(length, GFP_KERNEL);
11461da177e4SLinus Torvalds 	if (!status)
11471da177e4SLinus Torvalds 		return -ENOMEM;
11481da177e4SLinus Torvalds 
11491da177e4SLinus Torvalds 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
11503c377ef1SFelipe Balbi 		USB_REQ_GET_STATUS, USB_DIR_IN | recip, USB_STATUS_TYPE_STANDARD,
11512e43f0feSFelipe Balbi 		target, status, length, USB_CTRL_GET_TIMEOUT);
11521da177e4SLinus Torvalds 
11532e43f0feSFelipe Balbi 	switch (ret) {
11542e43f0feSFelipe Balbi 	case 4:
11552e43f0feSFelipe Balbi 		if (type != USB_STATUS_TYPE_PTM) {
11562e43f0feSFelipe Balbi 			ret = -EIO;
11572e43f0feSFelipe Balbi 			break;
11582e43f0feSFelipe Balbi 		}
11592e43f0feSFelipe Balbi 
11602e43f0feSFelipe Balbi 		*(u32 *) data = le32_to_cpu(*(__le32 *) status);
1161d656fa32SFelipe Balbi 		ret = 0;
11622e43f0feSFelipe Balbi 		break;
11632e43f0feSFelipe Balbi 	case 2:
11642e43f0feSFelipe Balbi 		if (type != USB_STATUS_TYPE_STANDARD) {
11652e43f0feSFelipe Balbi 			ret = -EIO;
11662e43f0feSFelipe Balbi 			break;
11672e43f0feSFelipe Balbi 		}
11682e43f0feSFelipe Balbi 
11692e43f0feSFelipe Balbi 		*(u16 *) data = le16_to_cpu(*(__le16 *) status);
1170d656fa32SFelipe Balbi 		ret = 0;
11712e43f0feSFelipe Balbi 		break;
11722e43f0feSFelipe Balbi 	default:
117315b7336eSAlan Stern 		ret = -EIO;
117415b7336eSAlan Stern 	}
11752e43f0feSFelipe Balbi 
11761da177e4SLinus Torvalds 	kfree(status);
11771da177e4SLinus Torvalds 	return ret;
11781da177e4SLinus Torvalds }
1179782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_get_status);
11801da177e4SLinus Torvalds 
11811da177e4SLinus Torvalds /**
11821da177e4SLinus Torvalds  * usb_clear_halt - tells device to clear endpoint halt/stall condition
11831da177e4SLinus Torvalds  * @dev: device whose endpoint is halted
11841da177e4SLinus Torvalds  * @pipe: endpoint "pipe" being cleared
118541631d36SAhmed S. Darwish  *
118641631d36SAhmed S. Darwish  * Context: task context, might sleep.
11871da177e4SLinus Torvalds  *
11881da177e4SLinus Torvalds  * This is used to clear halt conditions for bulk and interrupt endpoints,
11891da177e4SLinus Torvalds  * as reported by URB completion status.  Endpoints that are halted are
11901da177e4SLinus Torvalds  * sometimes referred to as being "stalled".  Such endpoints are unable
11911da177e4SLinus Torvalds  * to transmit or receive data until the halt status is cleared.  Any URBs
11921da177e4SLinus Torvalds  * queued for such an endpoint should normally be unlinked by the driver
11931da177e4SLinus Torvalds  * before clearing the halt condition, as described in sections 5.7.5
11941da177e4SLinus Torvalds  * and 5.8.5 of the USB 2.0 spec.
11951da177e4SLinus Torvalds  *
11961da177e4SLinus Torvalds  * Note that control and isochronous endpoints don't halt, although control
11971da177e4SLinus Torvalds  * endpoints report "protocol stall" (for unsupported requests) using the
11981da177e4SLinus Torvalds  * same status code used to report a true stall.
11991da177e4SLinus Torvalds  *
12001da177e4SLinus Torvalds  * This call is synchronous, and may not be used in an interrupt context.
1201*9f2a3933SMichal Pecio  * If a thread in your driver uses this call, make sure your disconnect()
1202*9f2a3933SMichal Pecio  * method can wait for it to complete.
12031da177e4SLinus Torvalds  *
1204626f090cSYacine Belkadi  * Return: Zero on success, or else the status code returned by the
12051da177e4SLinus Torvalds  * underlying usb_control_msg() call.
12061da177e4SLinus Torvalds  */
usb_clear_halt(struct usb_device * dev,int pipe)12071da177e4SLinus Torvalds int usb_clear_halt(struct usb_device *dev, int pipe)
12081da177e4SLinus Torvalds {
12091da177e4SLinus Torvalds 	int result;
12101da177e4SLinus Torvalds 	int endp = usb_pipeendpoint(pipe);
12111da177e4SLinus Torvalds 
12121da177e4SLinus Torvalds 	if (usb_pipein(pipe))
12131da177e4SLinus Torvalds 		endp |= USB_DIR_IN;
12141da177e4SLinus Torvalds 
12151da177e4SLinus Torvalds 	/* we don't care if it wasn't halted first. in fact some devices
12161da177e4SLinus Torvalds 	 * (like some ibmcam model 1 units) seem to expect hosts to make
12171da177e4SLinus Torvalds 	 * this request for iso endpoints, which can't halt!
12181da177e4SLinus Torvalds 	 */
1219297e84c0SGreg Kroah-Hartman 	result = usb_control_msg_send(dev, 0,
12201da177e4SLinus Torvalds 				      USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
12211da177e4SLinus Torvalds 				      USB_ENDPOINT_HALT, endp, NULL, 0,
1222ddd1198eSOliver Neukum 				      USB_CTRL_SET_TIMEOUT, GFP_NOIO);
12231da177e4SLinus Torvalds 
12241da177e4SLinus Torvalds 	/* don't un-halt or force to DATA0 except on success */
1225297e84c0SGreg Kroah-Hartman 	if (result)
12261da177e4SLinus Torvalds 		return result;
12271da177e4SLinus Torvalds 
12281da177e4SLinus Torvalds 	/* NOTE:  seems like Microsoft and Apple don't bother verifying
12291da177e4SLinus Torvalds 	 * the clear "took", so some devices could lock up if you check...
12301da177e4SLinus Torvalds 	 * such as the Hagiwara FlashGate DUAL.  So we won't bother.
12311da177e4SLinus Torvalds 	 *
12321da177e4SLinus Torvalds 	 * NOTE:  make sure the logic here doesn't diverge much from
12331da177e4SLinus Torvalds 	 * the copy in usb-storage, for as long as we need two copies.
12341da177e4SLinus Torvalds 	 */
12351da177e4SLinus Torvalds 
12363444b26aSDavid Vrabel 	usb_reset_endpoint(dev, endp);
12371da177e4SLinus Torvalds 
12381da177e4SLinus Torvalds 	return 0;
12391da177e4SLinus Torvalds }
1240782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_clear_halt);
12411da177e4SLinus Torvalds 
create_intf_ep_devs(struct usb_interface * intf)12423b23dd6fSAlan Stern static int create_intf_ep_devs(struct usb_interface *intf)
12433b23dd6fSAlan Stern {
12443b23dd6fSAlan Stern 	struct usb_device *udev = interface_to_usbdev(intf);
12453b23dd6fSAlan Stern 	struct usb_host_interface *alt = intf->cur_altsetting;
12463b23dd6fSAlan Stern 	int i;
12473b23dd6fSAlan Stern 
12483b23dd6fSAlan Stern 	if (intf->ep_devs_created || intf->unregistering)
12493b23dd6fSAlan Stern 		return 0;
12503b23dd6fSAlan Stern 
12513b23dd6fSAlan Stern 	for (i = 0; i < alt->desc.bNumEndpoints; ++i)
12523b23dd6fSAlan Stern 		(void) usb_create_ep_devs(&intf->dev, &alt->endpoint[i], udev);
12533b23dd6fSAlan Stern 	intf->ep_devs_created = 1;
12543b23dd6fSAlan Stern 	return 0;
12553b23dd6fSAlan Stern }
12563b23dd6fSAlan Stern 
remove_intf_ep_devs(struct usb_interface * intf)12573b23dd6fSAlan Stern static void remove_intf_ep_devs(struct usb_interface *intf)
12583b23dd6fSAlan Stern {
12593b23dd6fSAlan Stern 	struct usb_host_interface *alt = intf->cur_altsetting;
12603b23dd6fSAlan Stern 	int i;
12613b23dd6fSAlan Stern 
12623b23dd6fSAlan Stern 	if (!intf->ep_devs_created)
12633b23dd6fSAlan Stern 		return;
12643b23dd6fSAlan Stern 
12653b23dd6fSAlan Stern 	for (i = 0; i < alt->desc.bNumEndpoints; ++i)
12663b23dd6fSAlan Stern 		usb_remove_ep_devs(&alt->endpoint[i]);
12673b23dd6fSAlan Stern 	intf->ep_devs_created = 0;
12683b23dd6fSAlan Stern }
12693b23dd6fSAlan Stern 
12701da177e4SLinus Torvalds /**
12711da177e4SLinus Torvalds  * usb_disable_endpoint -- Disable an endpoint by address
12721da177e4SLinus Torvalds  * @dev: the device whose endpoint is being disabled
12731da177e4SLinus Torvalds  * @epaddr: the endpoint's address.  Endpoint number for output,
12741da177e4SLinus Torvalds  *	endpoint number + USB_DIR_IN for input
1275ddeac4e7SAlan Stern  * @reset_hardware: flag to erase any endpoint state stored in the
1276ddeac4e7SAlan Stern  *	controller hardware
12771da177e4SLinus Torvalds  *
1278ddeac4e7SAlan Stern  * Disables the endpoint for URB submission and nukes all pending URBs.
1279ddeac4e7SAlan Stern  * If @reset_hardware is set then also deallocates hcd/hardware state
1280ddeac4e7SAlan Stern  * for the endpoint.
12811da177e4SLinus Torvalds  */
usb_disable_endpoint(struct usb_device * dev,unsigned int epaddr,bool reset_hardware)1282ddeac4e7SAlan Stern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
1283ddeac4e7SAlan Stern 		bool reset_hardware)
12841da177e4SLinus Torvalds {
12851da177e4SLinus Torvalds 	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
12861da177e4SLinus Torvalds 	struct usb_host_endpoint *ep;
12871da177e4SLinus Torvalds 
12881da177e4SLinus Torvalds 	if (!dev)
12891da177e4SLinus Torvalds 		return;
12901da177e4SLinus Torvalds 
12911da177e4SLinus Torvalds 	if (usb_endpoint_out(epaddr)) {
12921da177e4SLinus Torvalds 		ep = dev->ep_out[epnum];
1293ac854131SAlan Stern 		if (reset_hardware && epnum != 0)
12941da177e4SLinus Torvalds 			dev->ep_out[epnum] = NULL;
12951da177e4SLinus Torvalds 	} else {
12961da177e4SLinus Torvalds 		ep = dev->ep_in[epnum];
1297ac854131SAlan Stern 		if (reset_hardware && epnum != 0)
12981da177e4SLinus Torvalds 			dev->ep_in[epnum] = NULL;
12991da177e4SLinus Torvalds 	}
1300bdd016baSAlan Stern 	if (ep) {
1301bdd016baSAlan Stern 		ep->enabled = 0;
130295cf82f9SAlan Stern 		usb_hcd_flush_endpoint(dev, ep);
1303ddeac4e7SAlan Stern 		if (reset_hardware)
130495cf82f9SAlan Stern 			usb_hcd_disable_endpoint(dev, ep);
13051da177e4SLinus Torvalds 	}
1306bdd016baSAlan Stern }
13071da177e4SLinus Torvalds 
13081da177e4SLinus Torvalds /**
13093444b26aSDavid Vrabel  * usb_reset_endpoint - Reset an endpoint's state.
13103444b26aSDavid Vrabel  * @dev: the device whose endpoint is to be reset
13113444b26aSDavid Vrabel  * @epaddr: the endpoint's address.  Endpoint number for output,
13123444b26aSDavid Vrabel  *	endpoint number + USB_DIR_IN for input
13133444b26aSDavid Vrabel  *
13143444b26aSDavid Vrabel  * Resets any host-side endpoint state such as the toggle bit,
13153444b26aSDavid Vrabel  * sequence number or current window.
13163444b26aSDavid Vrabel  */
usb_reset_endpoint(struct usb_device * dev,unsigned int epaddr)13173444b26aSDavid Vrabel void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr)
13183444b26aSDavid Vrabel {
13193444b26aSDavid Vrabel 	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
13203444b26aSDavid Vrabel 	struct usb_host_endpoint *ep;
13213444b26aSDavid Vrabel 
13223444b26aSDavid Vrabel 	if (usb_endpoint_out(epaddr))
13233444b26aSDavid Vrabel 		ep = dev->ep_out[epnum];
13243444b26aSDavid Vrabel 	else
13253444b26aSDavid Vrabel 		ep = dev->ep_in[epnum];
13263444b26aSDavid Vrabel 	if (ep)
13273444b26aSDavid Vrabel 		usb_hcd_reset_endpoint(dev, ep);
13283444b26aSDavid Vrabel }
13293444b26aSDavid Vrabel EXPORT_SYMBOL_GPL(usb_reset_endpoint);
13303444b26aSDavid Vrabel 
13313444b26aSDavid Vrabel 
13323444b26aSDavid Vrabel /**
13331da177e4SLinus Torvalds  * usb_disable_interface -- Disable all endpoints for an interface
13341da177e4SLinus Torvalds  * @dev: the device whose interface is being disabled
13351da177e4SLinus Torvalds  * @intf: pointer to the interface descriptor
1336ddeac4e7SAlan Stern  * @reset_hardware: flag to erase any endpoint state stored in the
1337ddeac4e7SAlan Stern  *	controller hardware
13381da177e4SLinus Torvalds  *
13391da177e4SLinus Torvalds  * Disables all the endpoints for the interface's current altsetting.
13401da177e4SLinus Torvalds  */
usb_disable_interface(struct usb_device * dev,struct usb_interface * intf,bool reset_hardware)1341ddeac4e7SAlan Stern void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
1342ddeac4e7SAlan Stern 		bool reset_hardware)
13431da177e4SLinus Torvalds {
13441da177e4SLinus Torvalds 	struct usb_host_interface *alt = intf->cur_altsetting;
13451da177e4SLinus Torvalds 	int i;
13461da177e4SLinus Torvalds 
13471da177e4SLinus Torvalds 	for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
13481da177e4SLinus Torvalds 		usb_disable_endpoint(dev,
1349ddeac4e7SAlan Stern 				alt->endpoint[i].desc.bEndpointAddress,
1350ddeac4e7SAlan Stern 				reset_hardware);
13511da177e4SLinus Torvalds 	}
13521da177e4SLinus Torvalds }
13531da177e4SLinus Torvalds 
1354cfd54fa8SMathias Nyman /*
1355cfd54fa8SMathias Nyman  * usb_disable_device_endpoints -- Disable all endpoints for a device
1356cfd54fa8SMathias Nyman  * @dev: the device whose endpoints are being disabled
1357cfd54fa8SMathias Nyman  * @skip_ep0: 0 to disable endpoint 0, 1 to skip it.
1358cfd54fa8SMathias Nyman  */
usb_disable_device_endpoints(struct usb_device * dev,int skip_ep0)1359cfd54fa8SMathias Nyman static void usb_disable_device_endpoints(struct usb_device *dev, int skip_ep0)
1360cfd54fa8SMathias Nyman {
1361cfd54fa8SMathias Nyman 	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
1362cfd54fa8SMathias Nyman 	int i;
1363cfd54fa8SMathias Nyman 
1364cfd54fa8SMathias Nyman 	if (hcd->driver->check_bandwidth) {
1365cfd54fa8SMathias Nyman 		/* First pass: Cancel URBs, leave endpoint pointers intact. */
1366cfd54fa8SMathias Nyman 		for (i = skip_ep0; i < 16; ++i) {
1367cfd54fa8SMathias Nyman 			usb_disable_endpoint(dev, i, false);
1368cfd54fa8SMathias Nyman 			usb_disable_endpoint(dev, i + USB_DIR_IN, false);
1369cfd54fa8SMathias Nyman 		}
1370cfd54fa8SMathias Nyman 		/* Remove endpoints from the host controller internal state */
1371cfd54fa8SMathias Nyman 		mutex_lock(hcd->bandwidth_mutex);
1372cfd54fa8SMathias Nyman 		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
1373cfd54fa8SMathias Nyman 		mutex_unlock(hcd->bandwidth_mutex);
1374cfd54fa8SMathias Nyman 	}
1375cfd54fa8SMathias Nyman 	/* Second pass: remove endpoint pointers */
1376cfd54fa8SMathias Nyman 	for (i = skip_ep0; i < 16; ++i) {
1377cfd54fa8SMathias Nyman 		usb_disable_endpoint(dev, i, true);
1378cfd54fa8SMathias Nyman 		usb_disable_endpoint(dev, i + USB_DIR_IN, true);
1379cfd54fa8SMathias Nyman 	}
1380cfd54fa8SMathias Nyman }
1381cfd54fa8SMathias Nyman 
13823e35bf39SGreg Kroah-Hartman /**
13831da177e4SLinus Torvalds  * usb_disable_device - Disable all the endpoints for a USB device
13841da177e4SLinus Torvalds  * @dev: the device whose endpoints are being disabled
13851da177e4SLinus Torvalds  * @skip_ep0: 0 to disable endpoint 0, 1 to skip it.
13861da177e4SLinus Torvalds  *
13871da177e4SLinus Torvalds  * Disables all the device's endpoints, potentially including endpoint 0.
13881da177e4SLinus Torvalds  * Deallocates hcd/hardware state for the endpoints (nuking all or most
13891da177e4SLinus Torvalds  * pending urbs) and usbcore state for the interfaces, so that usbcore
13901da177e4SLinus Torvalds  * must usb_set_configuration() before any interfaces could be used.
13911da177e4SLinus Torvalds  */
usb_disable_device(struct usb_device * dev,int skip_ep0)13921da177e4SLinus Torvalds void usb_disable_device(struct usb_device *dev, int skip_ep0)
13931da177e4SLinus Torvalds {
13941da177e4SLinus Torvalds 	int i;
13951da177e4SLinus Torvalds 
13961da177e4SLinus Torvalds 	/* getting rid of interfaces will disconnect
13971da177e4SLinus Torvalds 	 * any drivers bound to them (a key side effect)
13981da177e4SLinus Torvalds 	 */
13991da177e4SLinus Torvalds 	if (dev->actconfig) {
1400ca5c485fSAlan Stern 		/*
1401ca5c485fSAlan Stern 		 * FIXME: In order to avoid self-deadlock involving the
1402ca5c485fSAlan Stern 		 * bandwidth_mutex, we have to mark all the interfaces
1403ca5c485fSAlan Stern 		 * before unregistering any of them.
1404ca5c485fSAlan Stern 		 */
1405ca5c485fSAlan Stern 		for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++)
1406ca5c485fSAlan Stern 			dev->actconfig->interface[i]->unregistering = 1;
1407ca5c485fSAlan Stern 
14081da177e4SLinus Torvalds 		for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
14091da177e4SLinus Torvalds 			struct usb_interface	*interface;
14101da177e4SLinus Torvalds 
141186d30741SAlan Stern 			/* remove this interface if it has been registered */
14121da177e4SLinus Torvalds 			interface = dev->actconfig->interface[i];
1413d305ef5dSDaniel Ritz 			if (!device_is_registered(&interface->dev))
141486d30741SAlan Stern 				continue;
14151da177e4SLinus Torvalds 			dev_dbg(&dev->dev, "unregistering interface %s\n",
14167071a3ceSKay Sievers 				dev_name(&interface->dev));
14173b23dd6fSAlan Stern 			remove_intf_ep_devs(interface);
14181a21175aSAlan Stern 			device_del(&interface->dev);
14191da177e4SLinus Torvalds 		}
14201da177e4SLinus Torvalds 
14211da177e4SLinus Torvalds 		/* Now that the interfaces are unbound, nobody should
14221da177e4SLinus Torvalds 		 * try to access them.
14231da177e4SLinus Torvalds 		 */
14241da177e4SLinus Torvalds 		for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
14251da177e4SLinus Torvalds 			put_device(&dev->actconfig->interface[i]->dev);
14261da177e4SLinus Torvalds 			dev->actconfig->interface[i] = NULL;
14271da177e4SLinus Torvalds 		}
1428f468f7b9SSarah Sharp 
14297529b257SKai-Heng Feng 		usb_disable_usb2_hardware_lpm(dev);
143024971912SSarah Sharp 		usb_unlocked_disable_lpm(dev);
1431f74631e3SSarah Sharp 		usb_disable_ltm(dev);
1432f468f7b9SSarah Sharp 
14331da177e4SLinus Torvalds 		dev->actconfig = NULL;
14341da177e4SLinus Torvalds 		if (dev->state == USB_STATE_CONFIGURED)
14351da177e4SLinus Torvalds 			usb_set_device_state(dev, USB_STATE_ADDRESS);
14361da177e4SLinus Torvalds 	}
143780f0cf39SAlan Stern 
143880f0cf39SAlan Stern 	dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
143980f0cf39SAlan Stern 		skip_ep0 ? "non-ep0" : "all");
1440cfd54fa8SMathias Nyman 
1441cfd54fa8SMathias Nyman 	usb_disable_device_endpoints(dev, skip_ep0);
14421da177e4SLinus Torvalds }
14431da177e4SLinus Torvalds 
14443e35bf39SGreg Kroah-Hartman /**
14451da177e4SLinus Torvalds  * usb_enable_endpoint - Enable an endpoint for USB communications
14461da177e4SLinus Torvalds  * @dev: the device whose interface is being enabled
14471da177e4SLinus Torvalds  * @ep: the endpoint
14483444b26aSDavid Vrabel  * @reset_ep: flag to reset the endpoint state
14491da177e4SLinus Torvalds  *
14503444b26aSDavid Vrabel  * Resets the endpoint state if asked, and sets dev->ep_{in,out} pointers.
14511da177e4SLinus Torvalds  * For control endpoints, both the input and output sides are handled.
14521da177e4SLinus Torvalds  */
usb_enable_endpoint(struct usb_device * dev,struct usb_host_endpoint * ep,bool reset_ep)14532caf7fcdSAlan Stern void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
14543444b26aSDavid Vrabel 		bool reset_ep)
14551da177e4SLinus Torvalds {
1456bdd016baSAlan Stern 	int epnum = usb_endpoint_num(&ep->desc);
1457bdd016baSAlan Stern 	int is_out = usb_endpoint_dir_out(&ep->desc);
1458bdd016baSAlan Stern 	int is_control = usb_endpoint_xfer_control(&ep->desc);
14591da177e4SLinus Torvalds 
14603444b26aSDavid Vrabel 	if (reset_ep)
14613444b26aSDavid Vrabel 		usb_hcd_reset_endpoint(dev, ep);
14623444b26aSDavid Vrabel 	if (is_out || is_control)
14631da177e4SLinus Torvalds 		dev->ep_out[epnum] = ep;
14643444b26aSDavid Vrabel 	if (!is_out || is_control)
14651da177e4SLinus Torvalds 		dev->ep_in[epnum] = ep;
1466bdd016baSAlan Stern 	ep->enabled = 1;
14671da177e4SLinus Torvalds }
14681da177e4SLinus Torvalds 
14693e35bf39SGreg Kroah-Hartman /**
14701da177e4SLinus Torvalds  * usb_enable_interface - Enable all the endpoints for an interface
14711da177e4SLinus Torvalds  * @dev: the device whose interface is being enabled
14721da177e4SLinus Torvalds  * @intf: pointer to the interface descriptor
14733444b26aSDavid Vrabel  * @reset_eps: flag to reset the endpoints' state
14741da177e4SLinus Torvalds  *
14751da177e4SLinus Torvalds  * Enables all the endpoints for the interface's current altsetting.
14761da177e4SLinus Torvalds  */
usb_enable_interface(struct usb_device * dev,struct usb_interface * intf,bool reset_eps)14772caf7fcdSAlan Stern void usb_enable_interface(struct usb_device *dev,
14783444b26aSDavid Vrabel 		struct usb_interface *intf, bool reset_eps)
14791da177e4SLinus Torvalds {
14801da177e4SLinus Torvalds 	struct usb_host_interface *alt = intf->cur_altsetting;
14811da177e4SLinus Torvalds 	int i;
14821da177e4SLinus Torvalds 
14831da177e4SLinus Torvalds 	for (i = 0; i < alt->desc.bNumEndpoints; ++i)
14843444b26aSDavid Vrabel 		usb_enable_endpoint(dev, &alt->endpoint[i], reset_eps);
14851da177e4SLinus Torvalds }
14861da177e4SLinus Torvalds 
14871da177e4SLinus Torvalds /**
14881da177e4SLinus Torvalds  * usb_set_interface - Makes a particular alternate setting be current
14891da177e4SLinus Torvalds  * @dev: the device whose interface is being updated
14901da177e4SLinus Torvalds  * @interface: the interface being updated
14911da177e4SLinus Torvalds  * @alternate: the setting being chosen.
149241631d36SAhmed S. Darwish  *
149341631d36SAhmed S. Darwish  * Context: task context, might sleep.
14941da177e4SLinus Torvalds  *
14951da177e4SLinus Torvalds  * This is used to enable data transfers on interfaces that may not
14961da177e4SLinus Torvalds  * be enabled by default.  Not all devices support such configurability.
14971da177e4SLinus Torvalds  * Only the driver bound to an interface may change its setting.
14981da177e4SLinus Torvalds  *
14991da177e4SLinus Torvalds  * Within any given configuration, each interface may have several
15001da177e4SLinus Torvalds  * alternative settings.  These are often used to control levels of
15011da177e4SLinus Torvalds  * bandwidth consumption.  For example, the default setting for a high
15021da177e4SLinus Torvalds  * speed interrupt endpoint may not send more than 64 bytes per microframe,
15031da177e4SLinus Torvalds  * while interrupt transfers of up to 3KBytes per microframe are legal.
15041da177e4SLinus Torvalds  * Also, isochronous endpoints may never be part of an
15051da177e4SLinus Torvalds  * interface's default setting.  To access such bandwidth, alternate
15061da177e4SLinus Torvalds  * interface settings must be made current.
15071da177e4SLinus Torvalds  *
15081da177e4SLinus Torvalds  * Note that in the Linux USB subsystem, bandwidth associated with
15091da177e4SLinus Torvalds  * an endpoint in a given alternate setting is not reserved until an URB
15101da177e4SLinus Torvalds  * is submitted that needs that bandwidth.  Some other operating systems
15111da177e4SLinus Torvalds  * allocate bandwidth early, when a configuration is chosen.
15121da177e4SLinus Torvalds  *
1513f9a5b4f5SMathias Nyman  * xHCI reserves bandwidth and configures the alternate setting in
1514f9a5b4f5SMathias Nyman  * usb_hcd_alloc_bandwidth(). If it fails the original interface altsetting
1515f9a5b4f5SMathias Nyman  * may be disabled. Drivers cannot rely on any particular alternate
1516f9a5b4f5SMathias Nyman  * setting being in effect after a failure.
1517f9a5b4f5SMathias Nyman  *
15181da177e4SLinus Torvalds  * This call is synchronous, and may not be used in an interrupt context.
15191da177e4SLinus Torvalds  * Also, drivers must not change altsettings while urbs are scheduled for
15201da177e4SLinus Torvalds  * endpoints in that interface; all such urbs must first be completed
1521*9f2a3933SMichal Pecio  * (perhaps forced by unlinking). If a thread in your driver uses this call,
1522*9f2a3933SMichal Pecio  * make sure your disconnect() method can wait for it to complete.
15231da177e4SLinus Torvalds  *
1524626f090cSYacine Belkadi  * Return: Zero on success, or else the status code returned by the
15251da177e4SLinus Torvalds  * underlying usb_control_msg() call.
15261da177e4SLinus Torvalds  */
usb_set_interface(struct usb_device * dev,int interface,int alternate)15271da177e4SLinus Torvalds int usb_set_interface(struct usb_device *dev, int interface, int alternate)
15281da177e4SLinus Torvalds {
15291da177e4SLinus Torvalds 	struct usb_interface *iface;
15301da177e4SLinus Torvalds 	struct usb_host_interface *alt;
15313f0479e0SSarah Sharp 	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
15327a7b562dSHans de Goede 	int i, ret, manual = 0;
15333e35bf39SGreg Kroah-Hartman 	unsigned int epaddr;
15343e35bf39SGreg Kroah-Hartman 	unsigned int pipe;
15351da177e4SLinus Torvalds 
15361da177e4SLinus Torvalds 	if (dev->state == USB_STATE_SUSPENDED)
15371da177e4SLinus Torvalds 		return -EHOSTUNREACH;
15381da177e4SLinus Torvalds 
15391da177e4SLinus Torvalds 	iface = usb_ifnum_to_if(dev, interface);
15401da177e4SLinus Torvalds 	if (!iface) {
15411da177e4SLinus Torvalds 		dev_dbg(&dev->dev, "selecting invalid interface %d\n",
15421da177e4SLinus Torvalds 			interface);
15431da177e4SLinus Torvalds 		return -EINVAL;
15441da177e4SLinus Torvalds 	}
1545e534c5b8SAlan Stern 	if (iface->unregistering)
1546e534c5b8SAlan Stern 		return -ENODEV;
15471da177e4SLinus Torvalds 
15481da177e4SLinus Torvalds 	alt = usb_altnum_to_altsetting(iface, alternate);
15491da177e4SLinus Torvalds 	if (!alt) {
1550385f690bSThadeu Lima de Souza Cascardo 		dev_warn(&dev->dev, "selecting invalid altsetting %d\n",
15513b6004f3SGreg Kroah-Hartman 			 alternate);
15521da177e4SLinus Torvalds 		return -EINVAL;
15531da177e4SLinus Torvalds 	}
1554f9a5b4f5SMathias Nyman 	/*
1555f9a5b4f5SMathias Nyman 	 * usb3 hosts configure the interface in usb_hcd_alloc_bandwidth,
1556f9a5b4f5SMathias Nyman 	 * including freeing dropped endpoint ring buffers.
1557f9a5b4f5SMathias Nyman 	 * Make sure the interface endpoints are flushed before that
1558f9a5b4f5SMathias Nyman 	 */
1559f9a5b4f5SMathias Nyman 	usb_disable_interface(dev, iface, false);
15601da177e4SLinus Torvalds 
15613f0479e0SSarah Sharp 	/* Make sure we have enough bandwidth for this alternate interface.
15623f0479e0SSarah Sharp 	 * Remove the current alt setting and add the new alt setting.
15633f0479e0SSarah Sharp 	 */
1564d673bfcbSSarah Sharp 	mutex_lock(hcd->bandwidth_mutex);
15658306095fSSarah Sharp 	/* Disable LPM, and re-enable it once the new alt setting is installed,
15668306095fSSarah Sharp 	 * so that the xHCI driver can recalculate the U1/U2 timeouts.
15678306095fSSarah Sharp 	 */
15688306095fSSarah Sharp 	if (usb_disable_lpm(dev)) {
15691ccc417eSJoe Perches 		dev_err(&iface->dev, "%s Failed to disable LPM\n", __func__);
15708306095fSSarah Sharp 		mutex_unlock(hcd->bandwidth_mutex);
15718306095fSSarah Sharp 		return -ENOMEM;
15728306095fSSarah Sharp 	}
15737a7b562dSHans de Goede 	/* Changing alt-setting also frees any allocated streams */
15747a7b562dSHans de Goede 	for (i = 0; i < iface->cur_altsetting->desc.bNumEndpoints; i++)
15757a7b562dSHans de Goede 		iface->cur_altsetting->endpoint[i].streams = 0;
15767a7b562dSHans de Goede 
15773f0479e0SSarah Sharp 	ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);
15783f0479e0SSarah Sharp 	if (ret < 0) {
15793f0479e0SSarah Sharp 		dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",
15803f0479e0SSarah Sharp 				alternate);
15818306095fSSarah Sharp 		usb_enable_lpm(dev);
1582d673bfcbSSarah Sharp 		mutex_unlock(hcd->bandwidth_mutex);
15833f0479e0SSarah Sharp 		return ret;
15843f0479e0SSarah Sharp 	}
15853f0479e0SSarah Sharp 
1586392e1d98SAlan Stern 	if (dev->quirks & USB_QUIRK_NO_SET_INTF)
1587392e1d98SAlan Stern 		ret = -EPIPE;
1588392e1d98SAlan Stern 	else
1589297e84c0SGreg Kroah-Hartman 		ret = usb_control_msg_send(dev, 0,
1590297e84c0SGreg Kroah-Hartman 					   USB_REQ_SET_INTERFACE,
1591297e84c0SGreg Kroah-Hartman 					   USB_RECIP_INTERFACE, alternate,
1592ddd1198eSOliver Neukum 					   interface, NULL, 0, 5000,
1593ddd1198eSOliver Neukum 					   GFP_NOIO);
15941da177e4SLinus Torvalds 
15951da177e4SLinus Torvalds 	/* 9.4.10 says devices don't need this and are free to STALL the
15961da177e4SLinus Torvalds 	 * request if the interface only has one alternate setting.
15971da177e4SLinus Torvalds 	 */
15981da177e4SLinus Torvalds 	if (ret == -EPIPE && iface->num_altsetting == 1) {
15991da177e4SLinus Torvalds 		dev_dbg(&dev->dev,
16001da177e4SLinus Torvalds 			"manual set_interface for iface %d, alt %d\n",
16011da177e4SLinus Torvalds 			interface, alternate);
16021da177e4SLinus Torvalds 		manual = 1;
1603297e84c0SGreg Kroah-Hartman 	} else if (ret) {
16043f0479e0SSarah Sharp 		/* Re-instate the old alt setting */
16053f0479e0SSarah Sharp 		usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting);
16068306095fSSarah Sharp 		usb_enable_lpm(dev);
1607d673bfcbSSarah Sharp 		mutex_unlock(hcd->bandwidth_mutex);
16081da177e4SLinus Torvalds 		return ret;
16093f0479e0SSarah Sharp 	}
1610d673bfcbSSarah Sharp 	mutex_unlock(hcd->bandwidth_mutex);
16111da177e4SLinus Torvalds 
16121da177e4SLinus Torvalds 	/* FIXME drivers shouldn't need to replicate/bugfix the logic here
16131da177e4SLinus Torvalds 	 * when they implement async or easily-killable versions of this or
16141da177e4SLinus Torvalds 	 * other "should-be-internal" functions (like clear_halt).
16151da177e4SLinus Torvalds 	 * should hcd+usbcore postprocess control requests?
16161da177e4SLinus Torvalds 	 */
16171da177e4SLinus Torvalds 
16181da177e4SLinus Torvalds 	/* prevent submissions using previous endpoint settings */
16193b23dd6fSAlan Stern 	if (iface->cur_altsetting != alt) {
16203b23dd6fSAlan Stern 		remove_intf_ep_devs(iface);
16210e6c8e8dSAlan Stern 		usb_remove_sysfs_intf_files(iface);
16223b23dd6fSAlan Stern 	}
1623ddeac4e7SAlan Stern 	usb_disable_interface(dev, iface, true);
16241da177e4SLinus Torvalds 
16251da177e4SLinus Torvalds 	iface->cur_altsetting = alt;
16261da177e4SLinus Torvalds 
16278306095fSSarah Sharp 	/* Now that the interface is installed, re-enable LPM. */
16288306095fSSarah Sharp 	usb_unlocked_enable_lpm(dev);
16298306095fSSarah Sharp 
16301da177e4SLinus Torvalds 	/* If the interface only has one altsetting and the device didn't
1631a81e7eccSDavid Brownell 	 * accept the request, we attempt to carry out the equivalent action
16321da177e4SLinus Torvalds 	 * by manually clearing the HALT feature for each endpoint in the
16331da177e4SLinus Torvalds 	 * new altsetting.
16341da177e4SLinus Torvalds 	 */
16351da177e4SLinus Torvalds 	if (manual) {
16361da177e4SLinus Torvalds 		for (i = 0; i < alt->desc.bNumEndpoints; i++) {
16373e35bf39SGreg Kroah-Hartman 			epaddr = alt->endpoint[i].desc.bEndpointAddress;
16383e35bf39SGreg Kroah-Hartman 			pipe = __create_pipe(dev,
16393e35bf39SGreg Kroah-Hartman 					USB_ENDPOINT_NUMBER_MASK & epaddr) |
16403e35bf39SGreg Kroah-Hartman 					(usb_endpoint_out(epaddr) ?
16413e35bf39SGreg Kroah-Hartman 					USB_DIR_OUT : USB_DIR_IN);
16421da177e4SLinus Torvalds 
16431da177e4SLinus Torvalds 			usb_clear_halt(dev, pipe);
16441da177e4SLinus Torvalds 		}
16451da177e4SLinus Torvalds 	}
16461da177e4SLinus Torvalds 
16471da177e4SLinus Torvalds 	/* 9.1.1.5: reset toggles for all endpoints in the new altsetting
16481da177e4SLinus Torvalds 	 *
16491da177e4SLinus Torvalds 	 * Note:
16501da177e4SLinus Torvalds 	 * Despite EP0 is always present in all interfaces/AS, the list of
16511da177e4SLinus Torvalds 	 * endpoints from the descriptor does not contain EP0. Due to its
16521da177e4SLinus Torvalds 	 * omnipresence one might expect EP0 being considered "affected" by
16531da177e4SLinus Torvalds 	 * any SetInterface request and hence assume toggles need to be reset.
16541da177e4SLinus Torvalds 	 * However, EP0 toggles are re-synced for every individual transfer
16551da177e4SLinus Torvalds 	 * during the SETUP stage - hence EP0 toggles are "don't care" here.
16561da177e4SLinus Torvalds 	 * (Likewise, EP0 never "halts" on well designed devices.)
16571da177e4SLinus Torvalds 	 */
16582caf7fcdSAlan Stern 	usb_enable_interface(dev, iface, true);
16593b23dd6fSAlan Stern 	if (device_is_registered(&iface->dev)) {
16600e6c8e8dSAlan Stern 		usb_create_sysfs_intf_files(iface);
16613b23dd6fSAlan Stern 		create_intf_ep_devs(iface);
16623b23dd6fSAlan Stern 	}
16631da177e4SLinus Torvalds 	return 0;
16641da177e4SLinus Torvalds }
1665782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_set_interface);
16661da177e4SLinus Torvalds 
16671da177e4SLinus Torvalds /**
16681da177e4SLinus Torvalds  * usb_reset_configuration - lightweight device reset
16691da177e4SLinus Torvalds  * @dev: the device whose configuration is being reset
16701da177e4SLinus Torvalds  *
16711da177e4SLinus Torvalds  * This issues a standard SET_CONFIGURATION request to the device using
16721da177e4SLinus Torvalds  * the current configuration.  The effect is to reset most USB-related
16731da177e4SLinus Torvalds  * state in the device, including interface altsettings (reset to zero),
16743444b26aSDavid Vrabel  * endpoint halts (cleared), and endpoint state (only for bulk and interrupt
16751da177e4SLinus Torvalds  * endpoints).  Other usbcore state is unchanged, including bindings of
16761da177e4SLinus Torvalds  * usb device drivers to interfaces.
16771da177e4SLinus Torvalds  *
16781da177e4SLinus Torvalds  * Because this affects multiple interfaces, avoid using this with composite
16791da177e4SLinus Torvalds  * (multi-interface) devices.  Instead, the driver for each interface may
1680a81e7eccSDavid Brownell  * use usb_set_interface() on the interfaces it claims.  Be careful though;
1681a81e7eccSDavid Brownell  * some devices don't support the SET_INTERFACE request, and others won't
16823444b26aSDavid Vrabel  * reset all the interface state (notably endpoint state).  Resetting the whole
16831da177e4SLinus Torvalds  * configuration would affect other drivers' interfaces.
16841da177e4SLinus Torvalds  *
16851da177e4SLinus Torvalds  * The caller must own the device lock.
16861da177e4SLinus Torvalds  *
1687626f090cSYacine Belkadi  * Return: Zero on success, else a negative error code.
1688cfd54fa8SMathias Nyman  *
1689cfd54fa8SMathias Nyman  * If this routine fails the device will probably be in an unusable state
1690cfd54fa8SMathias Nyman  * with endpoints disabled, and interfaces only partially enabled.
16911da177e4SLinus Torvalds  */
usb_reset_configuration(struct usb_device * dev)16921da177e4SLinus Torvalds int usb_reset_configuration(struct usb_device *dev)
16931da177e4SLinus Torvalds {
16941da177e4SLinus Torvalds 	int			i, retval;
16951da177e4SLinus Torvalds 	struct usb_host_config	*config;
16963f0479e0SSarah Sharp 	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
16971da177e4SLinus Torvalds 
16981da177e4SLinus Torvalds 	if (dev->state == USB_STATE_SUSPENDED)
16991da177e4SLinus Torvalds 		return -EHOSTUNREACH;
17001da177e4SLinus Torvalds 
17011da177e4SLinus Torvalds 	/* caller must have locked the device and must own
17021da177e4SLinus Torvalds 	 * the usb bus readlock (so driver bindings are stable);
17031da177e4SLinus Torvalds 	 * calls during probe() are fine
17041da177e4SLinus Torvalds 	 */
17051da177e4SLinus Torvalds 
1706cfd54fa8SMathias Nyman 	usb_disable_device_endpoints(dev, 1); /* skip ep0*/
17071da177e4SLinus Torvalds 
17081da177e4SLinus Torvalds 	config = dev->actconfig;
17093f0479e0SSarah Sharp 	retval = 0;
1710d673bfcbSSarah Sharp 	mutex_lock(hcd->bandwidth_mutex);
17118306095fSSarah Sharp 	/* Disable LPM, and re-enable it once the configuration is reset, so
17128306095fSSarah Sharp 	 * that the xHCI driver can recalculate the U1/U2 timeouts.
17138306095fSSarah Sharp 	 */
17148306095fSSarah Sharp 	if (usb_disable_lpm(dev)) {
17151ccc417eSJoe Perches 		dev_err(&dev->dev, "%s Failed to disable LPM\n", __func__);
17168306095fSSarah Sharp 		mutex_unlock(hcd->bandwidth_mutex);
17178306095fSSarah Sharp 		return -ENOMEM;
17188306095fSSarah Sharp 	}
17193f0479e0SSarah Sharp 
1720cfd54fa8SMathias Nyman 	/* xHCI adds all endpoints in usb_hcd_alloc_bandwidth */
1721cfd54fa8SMathias Nyman 	retval = usb_hcd_alloc_bandwidth(dev, config, NULL, NULL);
17223f0479e0SSarah Sharp 	if (retval < 0) {
17238306095fSSarah Sharp 		usb_enable_lpm(dev);
1724d673bfcbSSarah Sharp 		mutex_unlock(hcd->bandwidth_mutex);
17253f0479e0SSarah Sharp 		return retval;
17263f0479e0SSarah Sharp 	}
1727297e84c0SGreg Kroah-Hartman 	retval = usb_control_msg_send(dev, 0, USB_REQ_SET_CONFIGURATION, 0,
17281da177e4SLinus Torvalds 				      config->desc.bConfigurationValue, 0,
1729ddd1198eSOliver Neukum 				      NULL, 0, USB_CTRL_SET_TIMEOUT,
1730ddd1198eSOliver Neukum 				      GFP_NOIO);
1731297e84c0SGreg Kroah-Hartman 	if (retval) {
1732cfd54fa8SMathias Nyman 		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
1733cfd54fa8SMathias Nyman 		usb_enable_lpm(dev);
1734cfd54fa8SMathias Nyman 		mutex_unlock(hcd->bandwidth_mutex);
1735cfd54fa8SMathias Nyman 		return retval;
1736cfd54fa8SMathias Nyman 	}
1737d673bfcbSSarah Sharp 	mutex_unlock(hcd->bandwidth_mutex);
17381da177e4SLinus Torvalds 
17391da177e4SLinus Torvalds 	/* re-init hc/hcd interface/endpoint state */
17401da177e4SLinus Torvalds 	for (i = 0; i < config->desc.bNumInterfaces; i++) {
17411da177e4SLinus Torvalds 		struct usb_interface *intf = config->interface[i];
17421da177e4SLinus Torvalds 		struct usb_host_interface *alt;
17431da177e4SLinus Torvalds 
17441da177e4SLinus Torvalds 		alt = usb_altnum_to_altsetting(intf, 0);
17451da177e4SLinus Torvalds 
17461da177e4SLinus Torvalds 		/* No altsetting 0?  We'll assume the first altsetting.
17471da177e4SLinus Torvalds 		 * We could use a GetInterface call, but if a device is
17481da177e4SLinus Torvalds 		 * so non-compliant that it doesn't have altsetting 0
17491da177e4SLinus Torvalds 		 * then I wouldn't trust its reply anyway.
17501da177e4SLinus Torvalds 		 */
17511da177e4SLinus Torvalds 		if (!alt)
17521da177e4SLinus Torvalds 			alt = &intf->altsetting[0];
17531da177e4SLinus Torvalds 
17543b23dd6fSAlan Stern 		if (alt != intf->cur_altsetting) {
17553b23dd6fSAlan Stern 			remove_intf_ep_devs(intf);
17563b23dd6fSAlan Stern 			usb_remove_sysfs_intf_files(intf);
17573b23dd6fSAlan Stern 		}
17581da177e4SLinus Torvalds 		intf->cur_altsetting = alt;
17592caf7fcdSAlan Stern 		usb_enable_interface(dev, intf, true);
17603b23dd6fSAlan Stern 		if (device_is_registered(&intf->dev)) {
17610e6c8e8dSAlan Stern 			usb_create_sysfs_intf_files(intf);
17623b23dd6fSAlan Stern 			create_intf_ep_devs(intf);
17633b23dd6fSAlan Stern 		}
17641da177e4SLinus Torvalds 	}
17658306095fSSarah Sharp 	/* Now that the interfaces are installed, re-enable LPM. */
17668306095fSSarah Sharp 	usb_unlocked_enable_lpm(dev);
17671da177e4SLinus Torvalds 	return 0;
17681da177e4SLinus Torvalds }
1769782e70c6SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(usb_reset_configuration);
17701da177e4SLinus Torvalds 
usb_release_interface(struct device * dev)1771b0e396e3SGreg Kroah-Hartman static void usb_release_interface(struct device *dev)
17721da177e4SLinus Torvalds {
17731da177e4SLinus Torvalds 	struct usb_interface *intf = to_usb_interface(dev);
17741da177e4SLinus Torvalds 	struct usb_interface_cache *intfc =
17751da177e4SLinus Torvalds 			altsetting_to_usb_interface_cache(intf->altsetting);
17761da177e4SLinus Torvalds 
17771da177e4SLinus Torvalds 	kref_put(&intfc->ref, usb_release_interface_cache);
1778524134d4SAlan Stern 	usb_put_dev(interface_to_usbdev(intf));
17791a7e3948SJohan Hovold 	of_node_put(dev->of_node);
17801da177e4SLinus Torvalds 	kfree(intf);
17811da177e4SLinus Torvalds }
17821da177e4SLinus Torvalds 
1783b3910cefSStefan Koch /*
1784b3910cefSStefan Koch  * usb_deauthorize_interface - deauthorize an USB interface
1785b3910cefSStefan Koch  *
1786b3910cefSStefan Koch  * @intf: USB interface structure
1787b3910cefSStefan Koch  */
usb_deauthorize_interface(struct usb_interface * intf)1788b3910cefSStefan Koch void usb_deauthorize_interface(struct usb_interface *intf)
1789b3910cefSStefan Koch {
1790b3910cefSStefan Koch 	struct device *dev = &intf->dev;
1791b3910cefSStefan Koch 
1792b3910cefSStefan Koch 	device_lock(dev->parent);
1793b3910cefSStefan Koch 
1794b3910cefSStefan Koch 	if (intf->authorized) {
1795b3910cefSStefan Koch 		device_lock(dev);
1796b3910cefSStefan Koch 		intf->authorized = 0;
1797b3910cefSStefan Koch 		device_unlock(dev);
1798b3910cefSStefan Koch 
1799b3910cefSStefan Koch 		usb_forced_unbind_intf(intf);
1800b3910cefSStefan Koch 	}
1801b3910cefSStefan Koch 
1802b3910cefSStefan Koch 	device_unlock(dev->parent);
1803b3910cefSStefan Koch }
1804b3910cefSStefan Koch 
1805b3910cefSStefan Koch /*
1806b3910cefSStefan Koch  * usb_authorize_interface - authorize an USB interface
1807b3910cefSStefan Koch  *
1808b3910cefSStefan Koch  * @intf: USB interface structure
1809b3910cefSStefan Koch  */
usb_authorize_interface(struct usb_interface * intf)1810b3910cefSStefan Koch void usb_authorize_interface(struct usb_interface *intf)
1811b3910cefSStefan Koch {
1812b3910cefSStefan Koch 	struct device *dev = &intf->dev;
1813b3910cefSStefan Koch 
1814b3910cefSStefan Koch 	if (!intf->authorized) {
1815b3910cefSStefan Koch 		device_lock(dev);
1816b3910cefSStefan Koch 		intf->authorized = 1; /* authorize interface */
1817b3910cefSStefan Koch 		device_unlock(dev);
1818b3910cefSStefan Koch 	}
1819b3910cefSStefan Koch }
1820b3910cefSStefan Koch 
usb_if_uevent(const struct device * dev,struct kobj_uevent_env * env)1821162736b0SGreg Kroah-Hartman static int usb_if_uevent(const struct device *dev, struct kobj_uevent_env *env)
18229f8b17e6SKay Sievers {
1823162736b0SGreg Kroah-Hartman 	const struct usb_device *usb_dev;
1824162736b0SGreg Kroah-Hartman 	const struct usb_interface *intf;
1825162736b0SGreg Kroah-Hartman 	const struct usb_host_interface *alt;
18269f8b17e6SKay Sievers 
18279f8b17e6SKay Sievers 	intf = to_usb_interface(dev);
18289f8b17e6SKay Sievers 	usb_dev = interface_to_usbdev(intf);
18299f8b17e6SKay Sievers 	alt = intf->cur_altsetting;
18309f8b17e6SKay Sievers 
18317eff2e7aSKay Sievers 	if (add_uevent_var(env, "INTERFACE=%d/%d/%d",
18329f8b17e6SKay Sievers 		   alt->desc.bInterfaceClass,
18339f8b17e6SKay Sievers 		   alt->desc.bInterfaceSubClass,
18349f8b17e6SKay Sievers 		   alt->desc.bInterfaceProtocol))
18359f8b17e6SKay Sievers 		return -ENOMEM;
18369f8b17e6SKay Sievers 
18377eff2e7aSKay Sievers 	if (add_uevent_var(env,
18383e35bf39SGreg Kroah-Hartman 		   "MODALIAS=usb:"
183981df2d59SBjørn Mork 		   "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X",
18409f8b17e6SKay Sievers 		   le16_to_cpu(usb_dev->descriptor.idVendor),
18419f8b17e6SKay Sievers 		   le16_to_cpu(usb_dev->descriptor.idProduct),
18429f8b17e6SKay Sievers 		   le16_to_cpu(usb_dev->descriptor.bcdDevice),
18439f8b17e6SKay Sievers 		   usb_dev->descriptor.bDeviceClass,
18449f8b17e6SKay Sievers 		   usb_dev->descriptor.bDeviceSubClass,
18459f8b17e6SKay Sievers 		   usb_dev->descriptor.bDeviceProtocol,
18469f8b17e6SKay Sievers 		   alt->desc.bInterfaceClass,
18479f8b17e6SKay Sievers 		   alt->desc.bInterfaceSubClass,
184881df2d59SBjørn Mork 		   alt->desc.bInterfaceProtocol,
184981df2d59SBjørn Mork 		   alt->desc.bInterfaceNumber))
18509f8b17e6SKay Sievers 		return -ENOMEM;
18519f8b17e6SKay Sievers 
18529f8b17e6SKay Sievers 	return 0;
18539f8b17e6SKay Sievers }
18549f8b17e6SKay Sievers 
18551ab40abcSRicardo B. Marliere const struct device_type usb_if_device_type = {
18569f8b17e6SKay Sievers 	.name =		"usb_interface",
18579f8b17e6SKay Sievers 	.release =	usb_release_interface,
18589f8b17e6SKay Sievers 	.uevent =	usb_if_uevent,
18599f8b17e6SKay Sievers };
18609f8b17e6SKay Sievers 
find_iad(struct usb_device * dev,struct usb_host_config * config,u8 inum)1861165fe97eSCraig W. Nadler static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
1862165fe97eSCraig W. Nadler 						struct usb_host_config *config,
1863165fe97eSCraig W. Nadler 						u8 inum)
1864165fe97eSCraig W. Nadler {
1865165fe97eSCraig W. Nadler 	struct usb_interface_assoc_descriptor *retval = NULL;
1866165fe97eSCraig W. Nadler 	struct usb_interface_assoc_descriptor *intf_assoc;
1867165fe97eSCraig W. Nadler 	int first_intf;
1868165fe97eSCraig W. Nadler 	int last_intf;
1869165fe97eSCraig W. Nadler 	int i;
1870165fe97eSCraig W. Nadler 
1871165fe97eSCraig W. Nadler 	for (i = 0; (i < USB_MAXIADS && config->intf_assoc[i]); i++) {
1872165fe97eSCraig W. Nadler 		intf_assoc = config->intf_assoc[i];
1873165fe97eSCraig W. Nadler 		if (intf_assoc->bInterfaceCount == 0)
1874165fe97eSCraig W. Nadler 			continue;
1875165fe97eSCraig W. Nadler 
1876165fe97eSCraig W. Nadler 		first_intf = intf_assoc->bFirstInterface;
1877165fe97eSCraig W. Nadler 		last_intf = first_intf + (intf_assoc->bInterfaceCount - 1);
1878165fe97eSCraig W. Nadler 		if (inum >= first_intf && inum <= last_intf) {
1879165fe97eSCraig W. Nadler 			if (!retval)
1880165fe97eSCraig W. Nadler 				retval = intf_assoc;
1881165fe97eSCraig W. Nadler 			else
1882165fe97eSCraig W. Nadler 				dev_err(&dev->dev, "Interface #%d referenced"
1883165fe97eSCraig W. Nadler 					" by multiple IADs\n", inum);
1884165fe97eSCraig W. Nadler 		}
1885165fe97eSCraig W. Nadler 	}
1886165fe97eSCraig W. Nadler 
1887165fe97eSCraig W. Nadler 	return retval;
1888165fe97eSCraig W. Nadler }
1889165fe97eSCraig W. Nadler 
1890dc023dceSInaky Perez-Gonzalez 
1891dc023dceSInaky Perez-Gonzalez /*
1892dc023dceSInaky Perez-Gonzalez  * Internal function to queue a device reset
1893dc023dceSInaky Perez-Gonzalez  * See usb_queue_reset_device() for more details
1894dc023dceSInaky Perez-Gonzalez  */
__usb_queue_reset_device(struct work_struct * ws)189509e81f3dSFelipe Balbi static void __usb_queue_reset_device(struct work_struct *ws)
1896dc023dceSInaky Perez-Gonzalez {
1897dc023dceSInaky Perez-Gonzalez 	int rc;
1898dc023dceSInaky Perez-Gonzalez 	struct usb_interface *iface =
1899dc023dceSInaky Perez-Gonzalez 		container_of(ws, struct usb_interface, reset_ws);
1900dc023dceSInaky Perez-Gonzalez 	struct usb_device *udev = interface_to_usbdev(iface);
1901dc023dceSInaky Perez-Gonzalez 
1902dc023dceSInaky Perez-Gonzalez 	rc = usb_lock_device_for_reset(udev, iface);
1903dc023dceSInaky Perez-Gonzalez 	if (rc >= 0) {
1904dc023dceSInaky Perez-Gonzalez 		usb_reset_device(udev);
1905dc023dceSInaky Perez-Gonzalez 		usb_unlock_device(udev);
1906dc023dceSInaky Perez-Gonzalez 	}
1907524134d4SAlan Stern 	usb_put_intf(iface);	/* Undo _get_ in usb_queue_reset_device() */
1908dc023dceSInaky Perez-Gonzalez }
1909dc023dceSInaky Perez-Gonzalez 
19100a4db185SBastien Nocera /*
19110a4db185SBastien Nocera  * Internal function to set the wireless_status sysfs attribute
19120a4db185SBastien Nocera  * See usb_set_wireless_status() for more details
19130a4db185SBastien Nocera  */
__usb_wireless_status_intf(struct work_struct * ws)19140a4db185SBastien Nocera static void __usb_wireless_status_intf(struct work_struct *ws)
19150a4db185SBastien Nocera {
19160a4db185SBastien Nocera 	struct usb_interface *iface =
19170a4db185SBastien Nocera 		container_of(ws, struct usb_interface, wireless_status_work);
19180a4db185SBastien Nocera 
19190a4db185SBastien Nocera 	device_lock(iface->dev.parent);
19200a4db185SBastien Nocera 	if (iface->sysfs_files_created)
19210a4db185SBastien Nocera 		usb_update_wireless_status_attr(iface);
19220a4db185SBastien Nocera 	device_unlock(iface->dev.parent);
19230a4db185SBastien Nocera 	usb_put_intf(iface);	/* Undo _get_ in usb_set_wireless_status() */
19240a4db185SBastien Nocera }
19250a4db185SBastien Nocera 
19260a4db185SBastien Nocera /**
19270a4db185SBastien Nocera  * usb_set_wireless_status - sets the wireless_status struct member
1928539adfedSBastien Nocera  * @iface: the interface to modify
19290a4db185SBastien Nocera  * @status: the new wireless status
19300a4db185SBastien Nocera  *
19310a4db185SBastien Nocera  * Set the wireless_status struct member to the new value, and emit
19320a4db185SBastien Nocera  * sysfs changes as necessary.
19330a4db185SBastien Nocera  *
19340a4db185SBastien Nocera  * Returns: 0 on success, -EALREADY if already set.
19350a4db185SBastien Nocera  */
usb_set_wireless_status(struct usb_interface * iface,enum usb_wireless_status status)19360a4db185SBastien Nocera int usb_set_wireless_status(struct usb_interface *iface,
19370a4db185SBastien Nocera 		enum usb_wireless_status status)
19380a4db185SBastien Nocera {
19390a4db185SBastien Nocera 	if (iface->wireless_status == status)
19400a4db185SBastien Nocera 		return -EALREADY;
19410a4db185SBastien Nocera 
19420a4db185SBastien Nocera 	usb_get_intf(iface);
19430a4db185SBastien Nocera 	iface->wireless_status = status;
19440a4db185SBastien Nocera 	schedule_work(&iface->wireless_status_work);
19450a4db185SBastien Nocera 
19460a4db185SBastien Nocera 	return 0;
19470a4db185SBastien Nocera }
19480a4db185SBastien Nocera EXPORT_SYMBOL_GPL(usb_set_wireless_status);
1949dc023dceSInaky Perez-Gonzalez 
19501da177e4SLinus Torvalds /*
19511da177e4SLinus Torvalds  * usb_set_configuration - Makes a particular device setting be current
19521da177e4SLinus Torvalds  * @dev: the device whose configuration is being updated
19531da177e4SLinus Torvalds  * @configuration: the configuration being chosen.
195441631d36SAhmed S. Darwish  *
195541631d36SAhmed S. Darwish  * Context: task context, might sleep. Caller holds device lock.
19561da177e4SLinus Torvalds  *
19571da177e4SLinus Torvalds  * This is used to enable non-default device modes.  Not all devices
19581da177e4SLinus Torvalds  * use this kind of configurability; many devices only have one
19591da177e4SLinus Torvalds  * configuration.
19601da177e4SLinus Torvalds  *
19613f141e2aSAlan Stern  * @configuration is the value of the configuration to be installed.
19623f141e2aSAlan Stern  * According to the USB spec (e.g. section 9.1.1.5), configuration values
19633f141e2aSAlan Stern  * must be non-zero; a value of zero indicates that the device in
19643f141e2aSAlan Stern  * unconfigured.  However some devices erroneously use 0 as one of their
19653f141e2aSAlan Stern  * configuration values.  To help manage such devices, this routine will
19663f141e2aSAlan Stern  * accept @configuration = -1 as indicating the device should be put in
19673f141e2aSAlan Stern  * an unconfigured state.
19683f141e2aSAlan Stern  *
19691da177e4SLinus Torvalds  * USB device configurations may affect Linux interoperability,
19701da177e4SLinus Torvalds  * power consumption and the functionality available.  For example,
19711da177e4SLinus Torvalds  * the default configuration is limited to using 100mA of bus power,
19721da177e4SLinus Torvalds  * so that when certain device functionality requires more power,
19731da177e4SLinus Torvalds  * and the device is bus powered, that functionality should be in some
19741da177e4SLinus Torvalds  * non-default device configuration.  Other device modes may also be
19751da177e4SLinus Torvalds  * reflected as configuration options, such as whether two ISDN
19761da177e4SLinus Torvalds  * channels are available independently; and choosing between open
19771da177e4SLinus Torvalds  * standard device protocols (like CDC) or proprietary ones.
19781da177e4SLinus Torvalds  *
197916bbab29SInaky Perez-Gonzalez  * Note that a non-authorized device (dev->authorized == 0) will only
198016bbab29SInaky Perez-Gonzalez  * be put in unconfigured mode.
198116bbab29SInaky Perez-Gonzalez  *
19821da177e4SLinus Torvalds  * Note that USB has an additional level of device configurability,
19831da177e4SLinus Torvalds  * associated with interfaces.  That configurability is accessed using
19841da177e4SLinus Torvalds  * usb_set_interface().
19851da177e4SLinus Torvalds  *
19861da177e4SLinus Torvalds  * This call is synchronous. The calling context must be able to sleep,
19871da177e4SLinus Torvalds  * must own the device lock, and must not hold the driver model's USB
19886d243e5cSMing Lei  * bus mutex; usb interface driver probe() methods cannot use this routine.
19891da177e4SLinus Torvalds  *
19901da177e4SLinus Torvalds  * Returns zero on success, or else the status code returned by the
1991093cf723SSteven Cole  * underlying call that failed.  On successful completion, each interface
19921da177e4SLinus Torvalds  * in the original device configuration has been destroyed, and each one
19931da177e4SLinus Torvalds  * in the new configuration has been probed by all relevant usb device
19941da177e4SLinus Torvalds  * drivers currently known to the kernel.
19951da177e4SLinus Torvalds  */
usb_set_configuration(struct usb_device * dev,int configuration)19961da177e4SLinus Torvalds int usb_set_configuration(struct usb_device *dev, int configuration)
19971da177e4SLinus Torvalds {
19981da177e4SLinus Torvalds 	int i, ret;
19991da177e4SLinus Torvalds 	struct usb_host_config *cp = NULL;
20001da177e4SLinus Torvalds 	struct usb_interface **new_interfaces = NULL;
20013f0479e0SSarah Sharp 	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
20021da177e4SLinus Torvalds 	int n, nintf;
20031da177e4SLinus Torvalds 
200416bbab29SInaky Perez-Gonzalez 	if (dev->authorized == 0 || configuration == -1)
20053f141e2aSAlan Stern 		configuration = 0;
20063f141e2aSAlan Stern 	else {
20071da177e4SLinus Torvalds 		for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
20083f141e2aSAlan Stern 			if (dev->config[i].desc.bConfigurationValue ==
20093f141e2aSAlan Stern 					configuration) {
20101da177e4SLinus Torvalds 				cp = &dev->config[i];
20111da177e4SLinus Torvalds 				break;
20121da177e4SLinus Torvalds 			}
20131da177e4SLinus Torvalds 		}
20143f141e2aSAlan Stern 	}
20151da177e4SLinus Torvalds 	if ((!cp && configuration != 0))
20161da177e4SLinus Torvalds 		return -EINVAL;
20171da177e4SLinus Torvalds 
20181da177e4SLinus Torvalds 	/* The USB spec says configuration 0 means unconfigured.
20191da177e4SLinus Torvalds 	 * But if a device includes a configuration numbered 0,
20201da177e4SLinus Torvalds 	 * we will accept it as a correctly configured state.
20213f141e2aSAlan Stern 	 * Use -1 if you really want to unconfigure the device.
20221da177e4SLinus Torvalds 	 */
20231da177e4SLinus Torvalds 	if (cp && configuration == 0)
20241da177e4SLinus Torvalds 		dev_warn(&dev->dev, "config 0 descriptor??\n");
20251da177e4SLinus Torvalds 
20261da177e4SLinus Torvalds 	/* Allocate memory for new interfaces before doing anything else,
20271da177e4SLinus Torvalds 	 * so that if we run out then nothing will have changed. */
20281da177e4SLinus Torvalds 	n = nintf = 0;
20291da177e4SLinus Torvalds 	if (cp) {
20301da177e4SLinus Torvalds 		nintf = cp->desc.bNumInterfaces;
20316da2ec56SKees Cook 		new_interfaces = kmalloc_array(nintf, sizeof(*new_interfaces),
2032acbe2febSOliver Neukum 					       GFP_NOIO);
203393fab795SWolfram Sang 		if (!new_interfaces)
20341da177e4SLinus Torvalds 			return -ENOMEM;
20351da177e4SLinus Torvalds 
20361da177e4SLinus Torvalds 		for (; n < nintf; ++n) {
20370a1ef3b5SAlan Stern 			new_interfaces[n] = kzalloc(
20381da177e4SLinus Torvalds 					sizeof(struct usb_interface),
2039acbe2febSOliver Neukum 					GFP_NOIO);
20401da177e4SLinus Torvalds 			if (!new_interfaces[n]) {
20411da177e4SLinus Torvalds 				ret = -ENOMEM;
20421da177e4SLinus Torvalds free_interfaces:
20431da177e4SLinus Torvalds 				while (--n >= 0)
20441da177e4SLinus Torvalds 					kfree(new_interfaces[n]);
20451da177e4SLinus Torvalds 				kfree(new_interfaces);
20461da177e4SLinus Torvalds 				return ret;
20471da177e4SLinus Torvalds 			}
20481da177e4SLinus Torvalds 		}
20496ad07129SAlan Stern 
20508d8479dbSSebastian Andrzej Siewior 		i = dev->bus_mA - usb_get_max_power(dev, cp);
20516ad07129SAlan Stern 		if (i < 0)
20526ad07129SAlan Stern 			dev_warn(&dev->dev, "new config #%d exceeds power "
20536ad07129SAlan Stern 					"limit by %dmA\n",
20546ad07129SAlan Stern 					configuration, -i);
20551da177e4SLinus Torvalds 	}
20561da177e4SLinus Torvalds 
205701d883d4SAlan Stern 	/* Wake up the device so we can send it the Set-Config request */
205894fcda1fSAlan Stern 	ret = usb_autoresume_device(dev);
205901d883d4SAlan Stern 	if (ret)
206001d883d4SAlan Stern 		goto free_interfaces;
206101d883d4SAlan Stern 
20620791971bSThadeu Lima de Souza Cascardo 	/* if it's already configured, clear out old state first.
20630791971bSThadeu Lima de Souza Cascardo 	 * getting rid of old interfaces means unbinding their drivers.
20640791971bSThadeu Lima de Souza Cascardo 	 */
20650791971bSThadeu Lima de Souza Cascardo 	if (dev->state != USB_STATE_ADDRESS)
20660791971bSThadeu Lima de Souza Cascardo 		usb_disable_device(dev, 1);	/* Skip ep0 */
20670791971bSThadeu Lima de Souza Cascardo 
20680791971bSThadeu Lima de Souza Cascardo 	/* Get rid of pending async Set-Config requests for this device */
20690791971bSThadeu Lima de Souza Cascardo 	cancel_async_set_config(dev);
20700791971bSThadeu Lima de Souza Cascardo 
207179abb1abSSarah Sharp 	/* Make sure we have bandwidth (and available HCD resources) for this
207279abb1abSSarah Sharp 	 * configuration.  Remove endpoints from the schedule if we're dropping
207379abb1abSSarah Sharp 	 * this configuration to set configuration 0.  After this point, the
207479abb1abSSarah Sharp 	 * host controller will not allow submissions to dropped endpoints.  If
207579abb1abSSarah Sharp 	 * this call fails, the device state is unchanged.
207679abb1abSSarah Sharp 	 */
20778963c487SAlan Stern 	mutex_lock(hcd->bandwidth_mutex);
20788306095fSSarah Sharp 	/* Disable LPM, and re-enable it once the new configuration is
20798306095fSSarah Sharp 	 * installed, so that the xHCI driver can recalculate the U1/U2
20808306095fSSarah Sharp 	 * timeouts.
20818306095fSSarah Sharp 	 */
20829cf65991SSarah Sharp 	if (dev->actconfig && usb_disable_lpm(dev)) {
20831ccc417eSJoe Perches 		dev_err(&dev->dev, "%s Failed to disable LPM\n", __func__);
20848306095fSSarah Sharp 		mutex_unlock(hcd->bandwidth_mutex);
2085c058f7abSSachin Kamat 		ret = -ENOMEM;
2086c058f7abSSachin Kamat 		goto free_interfaces;
20878306095fSSarah Sharp 	}
20883f0479e0SSarah Sharp 	ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
208979abb1abSSarah Sharp 	if (ret < 0) {
20909cf65991SSarah Sharp 		if (dev->actconfig)
20918306095fSSarah Sharp 			usb_enable_lpm(dev);
2092d673bfcbSSarah Sharp 		mutex_unlock(hcd->bandwidth_mutex);
20930791971bSThadeu Lima de Souza Cascardo 		usb_autosuspend_device(dev);
209479abb1abSSarah Sharp 		goto free_interfaces;
209579abb1abSSarah Sharp 	}
209679abb1abSSarah Sharp 
209736caff5dSAlan Stern 	/*
209836caff5dSAlan Stern 	 * Initialize the new interface structures and the
20991da177e4SLinus Torvalds 	 * hc/hcd/usbcore interface/endpoint state.
21001da177e4SLinus Torvalds 	 */
21011da177e4SLinus Torvalds 	for (i = 0; i < nintf; ++i) {
21021da177e4SLinus Torvalds 		struct usb_interface_cache *intfc;
21031da177e4SLinus Torvalds 		struct usb_interface *intf;
21041da177e4SLinus Torvalds 		struct usb_host_interface *alt;
21051a7e3948SJohan Hovold 		u8 ifnum;
21061da177e4SLinus Torvalds 
21071da177e4SLinus Torvalds 		cp->interface[i] = intf = new_interfaces[i];
21081da177e4SLinus Torvalds 		intfc = cp->intf_cache[i];
21091da177e4SLinus Torvalds 		intf->altsetting = intfc->altsetting;
21101da177e4SLinus Torvalds 		intf->num_altsetting = intfc->num_altsetting;
21116b2bd3c8SStefan Koch 		intf->authorized = !!HCD_INTF_AUTHORIZED(hcd);
21121da177e4SLinus Torvalds 		kref_get(&intfc->ref);
21131da177e4SLinus Torvalds 
21141da177e4SLinus Torvalds 		alt = usb_altnum_to_altsetting(intf, 0);
21151da177e4SLinus Torvalds 
21161da177e4SLinus Torvalds 		/* No altsetting 0?  We'll assume the first altsetting.
21171da177e4SLinus Torvalds 		 * We could use a GetInterface call, but if a device is
21181da177e4SLinus Torvalds 		 * so non-compliant that it doesn't have altsetting 0
21191da177e4SLinus Torvalds 		 * then I wouldn't trust its reply anyway.
21201da177e4SLinus Torvalds 		 */
21211da177e4SLinus Torvalds 		if (!alt)
21221da177e4SLinus Torvalds 			alt = &intf->altsetting[0];
21231da177e4SLinus Torvalds 
21241a7e3948SJohan Hovold 		ifnum = alt->desc.bInterfaceNumber;
21251a7e3948SJohan Hovold 		intf->intf_assoc = find_iad(dev, cp, ifnum);
21261da177e4SLinus Torvalds 		intf->cur_altsetting = alt;
21272caf7fcdSAlan Stern 		usb_enable_interface(dev, intf, true);
21281da177e4SLinus Torvalds 		intf->dev.parent = &dev->dev;
21291a7e3948SJohan Hovold 		if (usb_of_has_combined_node(dev)) {
21301a7e3948SJohan Hovold 			device_set_of_node_from_dev(&intf->dev, &dev->dev);
21311a7e3948SJohan Hovold 		} else {
21321a7e3948SJohan Hovold 			intf->dev.of_node = usb_of_get_interface_node(dev,
21331a7e3948SJohan Hovold 					configuration, ifnum);
21341a7e3948SJohan Hovold 		}
2135a599a0fbSAndy Shevchenko 		ACPI_COMPANION_SET(&intf->dev, ACPI_COMPANION(&dev->dev));
21361da177e4SLinus Torvalds 		intf->dev.driver = NULL;
21371da177e4SLinus Torvalds 		intf->dev.bus = &usb_bus_type;
21389f8b17e6SKay Sievers 		intf->dev.type = &usb_if_device_type;
21392e5f10e4SAlan Stern 		intf->dev.groups = usb_interface_groups;
2140dc023dceSInaky Perez-Gonzalez 		INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
21410a4db185SBastien Nocera 		INIT_WORK(&intf->wireless_status_work, __usb_wireless_status_intf);
21420026e005SAlan Stern 		intf->minor = -1;
21431da177e4SLinus Torvalds 		device_initialize(&intf->dev);
214463defa73SMing Lei 		pm_runtime_no_callbacks(&intf->dev);
21451a7e3948SJohan Hovold 		dev_set_name(&intf->dev, "%d-%s:%d.%d", dev->bus->busnum,
21461a7e3948SJohan Hovold 				dev->devpath, configuration, ifnum);
2147524134d4SAlan Stern 		usb_get_dev(dev);
21481da177e4SLinus Torvalds 	}
21491da177e4SLinus Torvalds 	kfree(new_interfaces);
21501da177e4SLinus Torvalds 
2151297e84c0SGreg Kroah-Hartman 	ret = usb_control_msg_send(dev, 0, USB_REQ_SET_CONFIGURATION, 0,
2152297e84c0SGreg Kroah-Hartman 				   configuration, 0, NULL, 0,
2153ddd1198eSOliver Neukum 				   USB_CTRL_SET_TIMEOUT, GFP_NOIO);
2154297e84c0SGreg Kroah-Hartman 	if (ret && cp) {
215536caff5dSAlan Stern 		/*
215636caff5dSAlan Stern 		 * All the old state is gone, so what else can we do?
215736caff5dSAlan Stern 		 * The device is probably useless now anyway.
215836caff5dSAlan Stern 		 */
215936caff5dSAlan Stern 		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
216036caff5dSAlan Stern 		for (i = 0; i < nintf; ++i) {
216136caff5dSAlan Stern 			usb_disable_interface(dev, cp->interface[i], true);
216236caff5dSAlan Stern 			put_device(&cp->interface[i]->dev);
216336caff5dSAlan Stern 			cp->interface[i] = NULL;
216436caff5dSAlan Stern 		}
216536caff5dSAlan Stern 		cp = NULL;
216636caff5dSAlan Stern 	}
216736caff5dSAlan Stern 
216836caff5dSAlan Stern 	dev->actconfig = cp;
216936caff5dSAlan Stern 	mutex_unlock(hcd->bandwidth_mutex);
217036caff5dSAlan Stern 
217136caff5dSAlan Stern 	if (!cp) {
217236caff5dSAlan Stern 		usb_set_device_state(dev, USB_STATE_ADDRESS);
217336caff5dSAlan Stern 
217436caff5dSAlan Stern 		/* Leave LPM disabled while the device is unconfigured. */
217536caff5dSAlan Stern 		usb_autosuspend_device(dev);
217636caff5dSAlan Stern 		return ret;
217736caff5dSAlan Stern 	}
217836caff5dSAlan Stern 	usb_set_device_state(dev, USB_STATE_CONFIGURED);
217936caff5dSAlan Stern 
21801662e3a7SAlan Stern 	if (cp->string == NULL &&
21811662e3a7SAlan Stern 			!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
21826ad07129SAlan Stern 		cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
21831da177e4SLinus Torvalds 
21848306095fSSarah Sharp 	/* Now that the interfaces are installed, re-enable LPM. */
21858306095fSSarah Sharp 	usb_unlocked_enable_lpm(dev);
2186f74631e3SSarah Sharp 	/* Enable LTM if it was turned off by usb_disable_device. */
2187f74631e3SSarah Sharp 	usb_enable_ltm(dev);
21888306095fSSarah Sharp 
21891da177e4SLinus Torvalds 	/* Now that all the interfaces are set up, register them
21901da177e4SLinus Torvalds 	 * to trigger binding of drivers to interfaces.  probe()
21911da177e4SLinus Torvalds 	 * routines may install different altsettings and may
21921da177e4SLinus Torvalds 	 * claim() any interfaces not yet bound.  Many class drivers
21931da177e4SLinus Torvalds 	 * need that: CDC, audio, video, etc.
21941da177e4SLinus Torvalds 	 */
21951da177e4SLinus Torvalds 	for (i = 0; i < nintf; ++i) {
21961da177e4SLinus Torvalds 		struct usb_interface *intf = cp->interface[i];
21971da177e4SLinus Torvalds 
219801fdf179SMans Rullgard 		if (intf->dev.of_node &&
219901fdf179SMans Rullgard 		    !of_device_is_available(intf->dev.of_node)) {
220001fdf179SMans Rullgard 			dev_info(&dev->dev, "skipping disabled interface %d\n",
220101fdf179SMans Rullgard 				 intf->cur_altsetting->desc.bInterfaceNumber);
220201fdf179SMans Rullgard 			continue;
220301fdf179SMans Rullgard 		}
220401fdf179SMans Rullgard 
22051da177e4SLinus Torvalds 		dev_dbg(&dev->dev,
22061da177e4SLinus Torvalds 			"adding %s (config #%d, interface %d)\n",
22077071a3ceSKay Sievers 			dev_name(&intf->dev), configuration,
2208d4ece29dSDmitry Torokhov 			intf->cur_altsetting->desc.bInterfaceNumber);
2209927bc916SRafael J. Wysocki 		device_enable_async_suspend(&intf->dev);
22101da177e4SLinus Torvalds 		ret = device_add(&intf->dev);
22111da177e4SLinus Torvalds 		if (ret != 0) {
22126ad07129SAlan Stern 			dev_err(&dev->dev, "device_add(%s) --> %d\n",
22137071a3ceSKay Sievers 				dev_name(&intf->dev), ret);
22141da177e4SLinus Torvalds 			continue;
22151da177e4SLinus Torvalds 		}
22163b23dd6fSAlan Stern 		create_intf_ep_devs(intf);
22171da177e4SLinus Torvalds 	}
22181da177e4SLinus Torvalds 
221994fcda1fSAlan Stern 	usb_autosuspend_device(dev);
222086d30741SAlan Stern 	return 0;
22211da177e4SLinus Torvalds }
2222b7945b77SValentina Manea EXPORT_SYMBOL_GPL(usb_set_configuration);
22231da177e4SLinus Torvalds 
2224df718962SAlan Stern static LIST_HEAD(set_config_list);
2225df718962SAlan Stern static DEFINE_SPINLOCK(set_config_lock);
2226df718962SAlan Stern 
2227088dc270SAlan Stern struct set_config_request {
2228088dc270SAlan Stern 	struct usb_device	*udev;
2229088dc270SAlan Stern 	int			config;
2230088dc270SAlan Stern 	struct work_struct	work;
2231df718962SAlan Stern 	struct list_head	node;
2232088dc270SAlan Stern };
2233088dc270SAlan Stern 
2234088dc270SAlan Stern /* Worker routine for usb_driver_set_configuration() */
driver_set_config_work(struct work_struct * work)2235c4028958SDavid Howells static void driver_set_config_work(struct work_struct *work)
2236088dc270SAlan Stern {
2237c4028958SDavid Howells 	struct set_config_request *req =
2238c4028958SDavid Howells 		container_of(work, struct set_config_request, work);
2239df718962SAlan Stern 	struct usb_device *udev = req->udev;
2240088dc270SAlan Stern 
2241df718962SAlan Stern 	usb_lock_device(udev);
2242df718962SAlan Stern 	spin_lock(&set_config_lock);
2243df718962SAlan Stern 	list_del(&req->node);
2244df718962SAlan Stern 	spin_unlock(&set_config_lock);
2245df718962SAlan Stern 
2246df718962SAlan Stern 	if (req->config >= -1)		/* Is req still valid? */
2247df718962SAlan Stern 		usb_set_configuration(udev, req->config);
2248df718962SAlan Stern 	usb_unlock_device(udev);
2249df718962SAlan Stern 	usb_put_dev(udev);
2250088dc270SAlan Stern 	kfree(req);
2251088dc270SAlan Stern }
2252088dc270SAlan Stern 
2253df718962SAlan Stern /* Cancel pending Set-Config requests for a device whose configuration
2254df718962SAlan Stern  * was just changed
2255df718962SAlan Stern  */
cancel_async_set_config(struct usb_device * udev)2256df718962SAlan Stern static void cancel_async_set_config(struct usb_device *udev)
2257df718962SAlan Stern {
2258df718962SAlan Stern 	struct set_config_request *req;
2259df718962SAlan Stern 
2260df718962SAlan Stern 	spin_lock(&set_config_lock);
2261df718962SAlan Stern 	list_for_each_entry(req, &set_config_list, node) {
2262df718962SAlan Stern 		if (req->udev == udev)
2263df718962SAlan Stern 			req->config = -999;	/* Mark as cancelled */
2264df718962SAlan Stern 	}
2265df718962SAlan Stern 	spin_unlock(&set_config_lock);
2266df718962SAlan Stern }
2267df718962SAlan Stern 
2268088dc270SAlan Stern /**
2269088dc270SAlan Stern  * usb_driver_set_configuration - Provide a way for drivers to change device configurations
2270088dc270SAlan Stern  * @udev: the device whose configuration is being updated
2271088dc270SAlan Stern  * @config: the configuration being chosen.
2272088dc270SAlan Stern  * Context: In process context, must be able to sleep
2273088dc270SAlan Stern  *
2274088dc270SAlan Stern  * Device interface drivers are not allowed to change device configurations.
2275088dc270SAlan Stern  * This is because changing configurations will destroy the interface the
2276088dc270SAlan Stern  * driver is bound to and create new ones; it would be like a floppy-disk
2277088dc270SAlan Stern  * driver telling the computer to replace the floppy-disk drive with a
2278088dc270SAlan Stern  * tape drive!
2279088dc270SAlan Stern  *
2280088dc270SAlan Stern  * Still, in certain specialized circumstances the need may arise.  This
2281088dc270SAlan Stern  * routine gets around the normal restrictions by using a work thread to
2282088dc270SAlan Stern  * submit the change-config request.
2283088dc270SAlan Stern  *
2284626f090cSYacine Belkadi  * Return: 0 if the request was successfully queued, error code otherwise.
2285088dc270SAlan Stern  * The caller has no way to know whether the queued request will eventually
2286088dc270SAlan Stern  * succeed.
2287088dc270SAlan Stern  */
usb_driver_set_configuration(struct usb_device * udev,int config)2288088dc270SAlan Stern int usb_driver_set_configuration(struct usb_device *udev, int config)
2289088dc270SAlan Stern {
2290088dc270SAlan Stern 	struct set_config_request *req;
2291088dc270SAlan Stern 
2292088dc270SAlan Stern 	req = kmalloc(sizeof(*req), GFP_KERNEL);
2293088dc270SAlan Stern 	if (!req)
2294088dc270SAlan Stern 		return -ENOMEM;
2295088dc270SAlan Stern 	req->udev = udev;
2296088dc270SAlan Stern 	req->config = config;
2297c4028958SDavid Howells 	INIT_WORK(&req->work, driver_set_config_work);
2298088dc270SAlan Stern 
2299df718962SAlan Stern 	spin_lock(&set_config_lock);
2300df718962SAlan Stern 	list_add(&req->node, &set_config_list);
2301df718962SAlan Stern 	spin_unlock(&set_config_lock);
2302df718962SAlan Stern 
2303088dc270SAlan Stern 	usb_get_dev(udev);
23041737bf2cSAlan Stern 	schedule_work(&req->work);
2305088dc270SAlan Stern 	return 0;
2306088dc270SAlan Stern }
2307088dc270SAlan Stern EXPORT_SYMBOL_GPL(usb_driver_set_configuration);
2308e4c6fb77SOliver Neukum 
2309e4c6fb77SOliver Neukum /**
2310e4c6fb77SOliver Neukum  * cdc_parse_cdc_header - parse the extra headers present in CDC devices
2311e4c6fb77SOliver Neukum  * @hdr: the place to put the results of the parsing
2312e4c6fb77SOliver Neukum  * @intf: the interface for which parsing is requested
2313e4c6fb77SOliver Neukum  * @buffer: pointer to the extra headers to be parsed
2314e4c6fb77SOliver Neukum  * @buflen: length of the extra headers
2315e4c6fb77SOliver Neukum  *
2316e4c6fb77SOliver Neukum  * This evaluates the extra headers present in CDC devices which
2317e4c6fb77SOliver Neukum  * bind the interfaces for data and control and provide details
2318e4c6fb77SOliver Neukum  * about the capabilities of the device.
2319e4c6fb77SOliver Neukum  *
2320e4c6fb77SOliver Neukum  * Return: number of descriptors parsed or -EINVAL
2321e4c6fb77SOliver Neukum  * if the header is contradictory beyond salvage
2322e4c6fb77SOliver Neukum  */
2323e4c6fb77SOliver Neukum 
cdc_parse_cdc_header(struct usb_cdc_parsed_header * hdr,struct usb_interface * intf,u8 * buffer,int buflen)2324e4c6fb77SOliver Neukum int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr,
2325e4c6fb77SOliver Neukum 				struct usb_interface *intf,
2326e4c6fb77SOliver Neukum 				u8 *buffer,
2327e4c6fb77SOliver Neukum 				int buflen)
2328e4c6fb77SOliver Neukum {
2329e4c6fb77SOliver Neukum 	/* duplicates are ignored */
2330e4c6fb77SOliver Neukum 	struct usb_cdc_union_desc *union_header = NULL;
2331e4c6fb77SOliver Neukum 
2332e4c6fb77SOliver Neukum 	/* duplicates are not tolerated */
2333e4c6fb77SOliver Neukum 	struct usb_cdc_header_desc *header = NULL;
2334e4c6fb77SOliver Neukum 	struct usb_cdc_ether_desc *ether = NULL;
2335e4c6fb77SOliver Neukum 	struct usb_cdc_mdlm_detail_desc *detail = NULL;
2336e4c6fb77SOliver Neukum 	struct usb_cdc_mdlm_desc *desc = NULL;
2337e4c6fb77SOliver Neukum 
2338e4c6fb77SOliver Neukum 	unsigned int elength;
2339e4c6fb77SOliver Neukum 	int cnt = 0;
2340e4c6fb77SOliver Neukum 
2341e4c6fb77SOliver Neukum 	memset(hdr, 0x00, sizeof(struct usb_cdc_parsed_header));
2342e4c6fb77SOliver Neukum 	hdr->phonet_magic_present = false;
2343e4c6fb77SOliver Neukum 	while (buflen > 0) {
2344e4c6fb77SOliver Neukum 		elength = buffer[0];
2345e4c6fb77SOliver Neukum 		if (!elength) {
2346e4c6fb77SOliver Neukum 			dev_err(&intf->dev, "skipping garbage byte\n");
2347e4c6fb77SOliver Neukum 			elength = 1;
2348e4c6fb77SOliver Neukum 			goto next_desc;
2349e4c6fb77SOliver Neukum 		}
23502e1c4239SGreg Kroah-Hartman 		if ((buflen < elength) || (elength < 3)) {
23512e1c4239SGreg Kroah-Hartman 			dev_err(&intf->dev, "invalid descriptor buffer length\n");
23522e1c4239SGreg Kroah-Hartman 			break;
23532e1c4239SGreg Kroah-Hartman 		}
2354e4c6fb77SOliver Neukum 		if (buffer[1] != USB_DT_CS_INTERFACE) {
2355e4c6fb77SOliver Neukum 			dev_err(&intf->dev, "skipping garbage\n");
2356e4c6fb77SOliver Neukum 			goto next_desc;
2357e4c6fb77SOliver Neukum 		}
2358e4c6fb77SOliver Neukum 
2359e4c6fb77SOliver Neukum 		switch (buffer[2]) {
2360e4c6fb77SOliver Neukum 		case USB_CDC_UNION_TYPE: /* we've found it */
2361e4c6fb77SOliver Neukum 			if (elength < sizeof(struct usb_cdc_union_desc))
2362e4c6fb77SOliver Neukum 				goto next_desc;
2363e4c6fb77SOliver Neukum 			if (union_header) {
2364e4c6fb77SOliver Neukum 				dev_err(&intf->dev, "More than one union descriptor, skipping ...\n");
2365e4c6fb77SOliver Neukum 				goto next_desc;
2366e4c6fb77SOliver Neukum 			}
2367e4c6fb77SOliver Neukum 			union_header = (struct usb_cdc_union_desc *)buffer;
2368e4c6fb77SOliver Neukum 			break;
2369e4c6fb77SOliver Neukum 		case USB_CDC_COUNTRY_TYPE:
2370e4c6fb77SOliver Neukum 			if (elength < sizeof(struct usb_cdc_country_functional_desc))
2371e4c6fb77SOliver Neukum 				goto next_desc;
2372e4c6fb77SOliver Neukum 			hdr->usb_cdc_country_functional_desc =
2373e4c6fb77SOliver Neukum 				(struct usb_cdc_country_functional_desc *)buffer;
2374e4c6fb77SOliver Neukum 			break;
2375e4c6fb77SOliver Neukum 		case USB_CDC_HEADER_TYPE:
2376e4c6fb77SOliver Neukum 			if (elength != sizeof(struct usb_cdc_header_desc))
2377e4c6fb77SOliver Neukum 				goto next_desc;
2378e4c6fb77SOliver Neukum 			if (header)
2379e4c6fb77SOliver Neukum 				return -EINVAL;
2380e4c6fb77SOliver Neukum 			header = (struct usb_cdc_header_desc *)buffer;
2381e4c6fb77SOliver Neukum 			break;
2382e4c6fb77SOliver Neukum 		case USB_CDC_ACM_TYPE:
2383e4c6fb77SOliver Neukum 			if (elength < sizeof(struct usb_cdc_acm_descriptor))
2384e4c6fb77SOliver Neukum 				goto next_desc;
2385e4c6fb77SOliver Neukum 			hdr->usb_cdc_acm_descriptor =
2386e4c6fb77SOliver Neukum 				(struct usb_cdc_acm_descriptor *)buffer;
2387e4c6fb77SOliver Neukum 			break;
2388e4c6fb77SOliver Neukum 		case USB_CDC_ETHERNET_TYPE:
2389e4c6fb77SOliver Neukum 			if (elength != sizeof(struct usb_cdc_ether_desc))
2390e4c6fb77SOliver Neukum 				goto next_desc;
2391e4c6fb77SOliver Neukum 			if (ether)
2392e4c6fb77SOliver Neukum 				return -EINVAL;
2393e4c6fb77SOliver Neukum 			ether = (struct usb_cdc_ether_desc *)buffer;
2394e4c6fb77SOliver Neukum 			break;
2395e4c6fb77SOliver Neukum 		case USB_CDC_CALL_MANAGEMENT_TYPE:
2396e4c6fb77SOliver Neukum 			if (elength < sizeof(struct usb_cdc_call_mgmt_descriptor))
2397e4c6fb77SOliver Neukum 				goto next_desc;
2398e4c6fb77SOliver Neukum 			hdr->usb_cdc_call_mgmt_descriptor =
2399e4c6fb77SOliver Neukum 				(struct usb_cdc_call_mgmt_descriptor *)buffer;
2400e4c6fb77SOliver Neukum 			break;
2401e4c6fb77SOliver Neukum 		case USB_CDC_DMM_TYPE:
2402e4c6fb77SOliver Neukum 			if (elength < sizeof(struct usb_cdc_dmm_desc))
2403e4c6fb77SOliver Neukum 				goto next_desc;
2404e4c6fb77SOliver Neukum 			hdr->usb_cdc_dmm_desc =
2405e4c6fb77SOliver Neukum 				(struct usb_cdc_dmm_desc *)buffer;
2406e4c6fb77SOliver Neukum 			break;
2407e4c6fb77SOliver Neukum 		case USB_CDC_MDLM_TYPE:
240854364278SOliver Neukum 			if (elength < sizeof(struct usb_cdc_mdlm_desc))
2409e4c6fb77SOliver Neukum 				goto next_desc;
2410e4c6fb77SOliver Neukum 			if (desc)
2411e4c6fb77SOliver Neukum 				return -EINVAL;
2412e4c6fb77SOliver Neukum 			desc = (struct usb_cdc_mdlm_desc *)buffer;
2413e4c6fb77SOliver Neukum 			break;
2414e4c6fb77SOliver Neukum 		case USB_CDC_MDLM_DETAIL_TYPE:
241554364278SOliver Neukum 			if (elength < sizeof(struct usb_cdc_mdlm_detail_desc))
2416e4c6fb77SOliver Neukum 				goto next_desc;
2417e4c6fb77SOliver Neukum 			if (detail)
2418e4c6fb77SOliver Neukum 				return -EINVAL;
2419e4c6fb77SOliver Neukum 			detail = (struct usb_cdc_mdlm_detail_desc *)buffer;
2420e4c6fb77SOliver Neukum 			break;
2421e4c6fb77SOliver Neukum 		case USB_CDC_NCM_TYPE:
2422e4c6fb77SOliver Neukum 			if (elength < sizeof(struct usb_cdc_ncm_desc))
2423e4c6fb77SOliver Neukum 				goto next_desc;
2424e4c6fb77SOliver Neukum 			hdr->usb_cdc_ncm_desc = (struct usb_cdc_ncm_desc *)buffer;
2425e4c6fb77SOliver Neukum 			break;
2426e4c6fb77SOliver Neukum 		case USB_CDC_MBIM_TYPE:
2427e4c6fb77SOliver Neukum 			if (elength < sizeof(struct usb_cdc_mbim_desc))
2428e4c6fb77SOliver Neukum 				goto next_desc;
2429e4c6fb77SOliver Neukum 
2430e4c6fb77SOliver Neukum 			hdr->usb_cdc_mbim_desc = (struct usb_cdc_mbim_desc *)buffer;
2431e4c6fb77SOliver Neukum 			break;
2432e4c6fb77SOliver Neukum 		case USB_CDC_MBIM_EXTENDED_TYPE:
2433e4c6fb77SOliver Neukum 			if (elength < sizeof(struct usb_cdc_mbim_extended_desc))
2434e4c6fb77SOliver Neukum 				break;
2435e4c6fb77SOliver Neukum 			hdr->usb_cdc_mbim_extended_desc =
2436e4c6fb77SOliver Neukum 				(struct usb_cdc_mbim_extended_desc *)buffer;
2437e4c6fb77SOliver Neukum 			break;
2438e4c6fb77SOliver Neukum 		case CDC_PHONET_MAGIC_NUMBER:
2439e4c6fb77SOliver Neukum 			hdr->phonet_magic_present = true;
2440e4c6fb77SOliver Neukum 			break;
2441e4c6fb77SOliver Neukum 		default:
2442e4c6fb77SOliver Neukum 			/*
2443e4c6fb77SOliver Neukum 			 * there are LOTS more CDC descriptors that
2444e4c6fb77SOliver Neukum 			 * could legitimately be found here.
2445e4c6fb77SOliver Neukum 			 */
2446e4c6fb77SOliver Neukum 			dev_dbg(&intf->dev, "Ignoring descriptor: type %02x, length %ud\n",
2447e4c6fb77SOliver Neukum 					buffer[2], elength);
2448e4c6fb77SOliver Neukum 			goto next_desc;
2449e4c6fb77SOliver Neukum 		}
2450e4c6fb77SOliver Neukum 		cnt++;
2451e4c6fb77SOliver Neukum next_desc:
2452e4c6fb77SOliver Neukum 		buflen -= elength;
2453e4c6fb77SOliver Neukum 		buffer += elength;
2454e4c6fb77SOliver Neukum 	}
2455e4c6fb77SOliver Neukum 	hdr->usb_cdc_union_desc = union_header;
2456e4c6fb77SOliver Neukum 	hdr->usb_cdc_header_desc = header;
2457e4c6fb77SOliver Neukum 	hdr->usb_cdc_mdlm_detail_desc = detail;
2458e4c6fb77SOliver Neukum 	hdr->usb_cdc_mdlm_desc = desc;
2459e4c6fb77SOliver Neukum 	hdr->usb_cdc_ether_desc = ether;
2460e4c6fb77SOliver Neukum 	return cnt;
2461e4c6fb77SOliver Neukum }
2462e4c6fb77SOliver Neukum 
2463e4c6fb77SOliver Neukum EXPORT_SYMBOL(cdc_parse_cdc_header);
2464