1593 lines · 49.2 KB · C
RawDownload
/* * message.c - synchronous message handling */ #include <linux/pci.h>	/* for scatterlist macros */#include <linux/usb.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/mm.h>#include <linux/timer.h>#include <linux/ctype.h>#include <linux/device.h>#include <linux/usb/quirks.h>#include <asm/byteorder.h>#include <asm/scatterlist.h> #include "hcd.h"	/* for usbcore internals */#include "usb.h" static void usb_api_blocking_completion(struct urb *urb){	complete((struct completion *)urb->context);}  /* * Starts urb and waits for completion or timeout. Note that this call * is NOT interruptible. Many device driver i/o requests should be * interruptible and therefore these drivers should implement their * own interruptible routines. */static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length){ 	struct completion done;	unsigned long expire;	int status; 	init_completion(&done); 		urb->context = &done;	urb->actual_length = 0;	status = usb_submit_urb(urb, GFP_NOIO);	if (unlikely(status))		goto out; 	expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;	if (!wait_for_completion_timeout(&done, expire)) { 		dev_dbg(&urb->dev->dev,			"%s timed out on ep%d%s len=%d/%d\n",			current->comm,			usb_pipeendpoint(urb->pipe),			usb_pipein(urb->pipe) ? "in" : "out",			urb->actual_length,			urb->transfer_buffer_length); 		usb_kill_urb(urb);		status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status;	} else		status = urb->status;out:	if (actual_length)		*actual_length = urb->actual_length; 	usb_free_urb(urb);	return status;} /*-------------------------------------------------------------------*/// returns status (negative) or length (positive)static int usb_internal_control_msg(struct usb_device *usb_dev,				    unsigned int pipe, 				    struct usb_ctrlrequest *cmd,				    void *data, int len, int timeout){	struct urb *urb;	int retv;	int length; 	urb = usb_alloc_urb(0, GFP_NOIO);	if (!urb)		return -ENOMEM;  	usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,			     len, usb_api_blocking_completion, NULL); 	retv = usb_start_wait_urb(urb, timeout, &length);	if (retv < 0)		return retv;	else		return length;} /** *	usb_control_msg - Builds a control urb, sends it off and waits for completion *	@dev: pointer to the usb device to send the message to *	@pipe: endpoint "pipe" to send the message to *	@request: USB message request value *	@requesttype: USB message request type value *	@value: USB message value *	@index: USB message index value *	@data: pointer to the data to send *	@size: length in bytes of the data to send *	@timeout: time in msecs to wait for the message to complete before *		timing out (if 0 the wait is forever) *	Context: !in_interrupt () * *	This function sends a simple control message to a specified endpoint *	and waits for the message to complete, or timeout. *	 *	If successful, it returns the number of bytes transferred, otherwise a negative error number. * *	Don't use this function from within an interrupt context, like a *	bottom half handler.  If you need an asynchronous message, or need to send *	a message from within interrupt context, use usb_submit_urb() *      If a thread in your driver uses this call, make sure your disconnect() *      method can wait for it to complete.  Since you don't have a handle on *      the URB used, you can't cancel the request. */int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,			 __u16 value, __u16 index, void *data, __u16 size, int timeout){	struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);	int ret;		if (!dr)		return -ENOMEM; 	dr->bRequestType= requesttype;	dr->bRequest = request;	dr->wValue = cpu_to_le16p(&value);	dr->wIndex = cpu_to_le16p(&index);	dr->wLength = cpu_to_le16p(&size); 	//dbg("usb_control_msg");	 	ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); 	kfree(dr); 	return ret;}  /** * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion * @usb_dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @data: pointer to the data to send * @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred in bytes * @timeout: time in msecs to wait for the message to complete before *	timing out (if 0 the wait is forever) * Context: !in_interrupt () * * This function sends a simple interrupt message to a specified endpoint and * waits for the message to complete, or timeout. * * If successful, it returns 0, otherwise a negative error number.  The number * of actual bytes transferred will be stored in the actual_length paramater. * * Don't use this function from within an interrupt context, like a bottom half * handler.  If you need an asynchronous message, or need to send a message * from within interrupt context, use usb_submit_urb() If a thread in your * driver uses this call, make sure your disconnect() method can wait for it to * complete.  Since you don't have a handle on the URB used, you can't cancel * the request. */int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,		      void *data, int len, int *actual_length, int timeout){	return usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout);}EXPORT_SYMBOL_GPL(usb_interrupt_msg); /** *	usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion *	@usb_dev: pointer to the usb device to send the message to *	@pipe: endpoint "pipe" to send the message to *	@data: pointer to the data to send *	@len: length in bytes of the data to send *	@actual_length: pointer to a location to put the actual length transferred in bytes *	@timeout: time in msecs to wait for the message to complete before *		timing out (if 0 the wait is forever) *	Context: !in_interrupt () * *	This function sends a simple bulk message to a specified endpoint *	and waits for the message to complete, or timeout. *	 *	If successful, it returns 0, otherwise a negative error number. *	The number of actual bytes transferred will be stored in the  *	actual_length paramater. * *	Don't use this function from within an interrupt context, like a *	bottom half handler.  If you need an asynchronous message, or need to *	send a message from within interrupt context, use usb_submit_urb() *      If a thread in your driver uses this call, make sure your disconnect() *      method can wait for it to complete.  Since you don't have a handle on *      the URB used, you can't cancel the request. * *	Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT *	ioctl, users are forced to abuse this routine by using it to submit *	URBs for interrupt endpoints.  We will take the liberty of creating *	an interrupt URB (with the default interval) if the target is an *	interrupt endpoint. */int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, 			void *data, int len, int *actual_length, int timeout){	struct urb *urb;	struct usb_host_endpoint *ep; 	ep = (usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out)			[usb_pipeendpoint(pipe)];	if (!ep || len < 0)		return -EINVAL; 	urb = usb_alloc_urb(0, GFP_KERNEL);	if (!urb)		return -ENOMEM; 	if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==			USB_ENDPOINT_XFER_INT) {		int interval; 		if (usb_dev->speed == USB_SPEED_HIGH)			interval = 1 << min(15, ep->desc.bInterval - 1);		else			interval = ep->desc.bInterval;		pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);		usb_fill_int_urb(urb, usb_dev, pipe, data, len,				usb_api_blocking_completion, NULL, interval);	} else		usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,				usb_api_blocking_completion, NULL); 	return usb_start_wait_urb(urb, timeout, actual_length);} /*-------------------------------------------------------------------*/ static void sg_clean (struct usb_sg_request *io){	if (io->urbs) {		while (io->entries--)			usb_free_urb (io->urbs [io->entries]);		kfree (io->urbs);		io->urbs = NULL;	}	if (io->dev->dev.dma_mask != NULL)		usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);	io->dev = NULL;} static void sg_complete (struct urb *urb){	struct usb_sg_request	*io = urb->context; 	spin_lock (&io->lock); 	/* In 2.5 we require hcds' endpoint queues not to progress after fault	 * reports, until the completion callback (this!) returns.  That lets	 * device driver code (like this routine) unlink queued urbs first,	 * if it needs to, since the HC won't work on them at all.  So it's	 * not possible for page N+1 to overwrite page N, and so on.	 *	 * That's only for "hard" faults; "soft" faults (unlinks) sometimes	 * complete before the HCD can get requests away from hardware,	 * though never during cleanup after a hard fault.	 */	if (io->status			&& (io->status != -ECONNRESET				|| urb->status != -ECONNRESET)			&& urb->actual_length) {		dev_err (io->dev->bus->controller,			"dev %s ep%d%s scatterlist error %d/%d\n",			io->dev->devpath,			usb_pipeendpoint (urb->pipe),			usb_pipein (urb->pipe) ? "in" : "out",			urb->status, io->status);		// BUG ();	} 	if (io->status == 0 && urb->status && urb->status != -ECONNRESET) {		int		i, found, status; 		io->status = urb->status; 		/* the previous urbs, and this one, completed already.		 * unlink pending urbs so they won't rx/tx bad data.		 * careful: unlink can sometimes be synchronous...		 */		spin_unlock (&io->lock);		for (i = 0, found = 0; i < io->entries; i++) {			if (!io->urbs [i] || !io->urbs [i]->dev)				continue;			if (found) {				status = usb_unlink_urb (io->urbs [i]);				if (status != -EINPROGRESS						&& status != -ENODEV						&& status != -EBUSY)					dev_err (&io->dev->dev,						"%s, unlink --> %d\n",						__FUNCTION__, status);			} else if (urb == io->urbs [i])				found = 1;		}		spin_lock (&io->lock);	}	urb->dev = NULL; 	/* on the last completion, signal usb_sg_wait() */	io->bytes += urb->actual_length;	io->count--;	if (!io->count)		complete (&io->complete); 	spin_unlock (&io->lock);}  /** * usb_sg_init - initializes scatterlist-based bulk/interrupt I/O request * @io: request block being initialized.  until usb_sg_wait() returns, *	treat this as a pointer to an opaque block of memory, * @dev: the usb device that will send or receive the data * @pipe: endpoint "pipe" used to transfer the data * @period: polling rate for interrupt endpoints, in frames or * 	(for high speed endpoints) microframes; ignored for bulk * @sg: scatterlist entries * @nents: how many entries in the scatterlist * @length: how many bytes to send from the scatterlist, or zero to * 	send every byte identified in the list. * @mem_flags: SLAB_* flags affecting memory allocations in this call * * Returns zero for success, else a negative errno value.  This initializes a * scatter/gather request, allocating resources such as I/O mappings and urb * memory (except maybe memory used by USB controller drivers). * * The request must be issued using usb_sg_wait(), which waits for the I/O to * complete (or to be canceled) and then cleans up all resources allocated by * usb_sg_init(). * * The request may be canceled with usb_sg_cancel(), either before or after * usb_sg_wait() is called. */int usb_sg_init (	struct usb_sg_request	*io,	struct usb_device	*dev,	unsigned		pipe, 	unsigned		period,	struct scatterlist	*sg,	int			nents,	size_t			length,	gfp_t			mem_flags){	int			i;	int			urb_flags;	int			dma; 	if (!io || !dev || !sg			|| usb_pipecontrol (pipe)			|| usb_pipeisoc (pipe)			|| nents <= 0)		return -EINVAL; 	spin_lock_init (&io->lock);	io->dev = dev;	io->pipe = pipe;	io->sg = sg;	io->nents = nents; 	/* not all host controllers use DMA (like the mainstream pci ones);	 * they can use PIO (sl811) or be software over another transport.	 */	dma = (dev->dev.dma_mask != NULL);	if (dma)		io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);	else		io->entries = nents; 	/* initialize all the urbs we'll use */	if (io->entries <= 0)		return io->entries; 	io->count = io->entries;	io->urbs = kmalloc (io->entries * sizeof *io->urbs, mem_flags);	if (!io->urbs)		goto nomem; 	urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;	if (usb_pipein (pipe))		urb_flags |= URB_SHORT_NOT_OK; 	for (i = 0; i < io->entries; i++) {		unsigned		len; 		io->urbs [i] = usb_alloc_urb (0, mem_flags);		if (!io->urbs [i]) {			io->entries = i;			goto nomem;		} 		io->urbs [i]->dev = NULL;		io->urbs [i]->pipe = pipe;		io->urbs [i]->interval = period;		io->urbs [i]->transfer_flags = urb_flags; 		io->urbs [i]->complete = sg_complete;		io->urbs [i]->context = io;		io->urbs [i]->status = -EINPROGRESS;		io->urbs [i]->actual_length = 0; 		if (dma) {			/* hc may use _only_ transfer_dma */			io->urbs [i]->transfer_dma = sg_dma_address (sg + i);			len = sg_dma_len (sg + i);		} else {			/* hc may use _only_ transfer_buffer */			io->urbs [i]->transfer_buffer =				page_address (sg [i].page) + sg [i].offset;			len = sg [i].length;		} 		if (length) {			len = min_t (unsigned, len, length);			length -= len;			if (length == 0)				io->entries = i + 1;		}		io->urbs [i]->transfer_buffer_length = len;	}	io->urbs [--i]->transfer_flags &= ~URB_NO_INTERRUPT; 	/* transaction state */	io->status = 0;	io->bytes = 0;	init_completion (&io->complete);	return 0; nomem:	sg_clean (io);	return -ENOMEM;}  /** * usb_sg_wait - synchronously execute scatter/gather request * @io: request block handle, as initialized with usb_sg_init(). * 	some fields become accessible when this call returns. * Context: !in_interrupt () * * This function blocks until the specified I/O operation completes.  It * leverages the grouping of the related I/O requests to get good transfer * rates, by queueing the requests.  At higher speeds, such queuing can * significantly improve USB throughput. * * There are three kinds of completion for this function. * (1) success, where io->status is zero.  The number of io->bytes *     transferred is as requested. * (2) error, where io->status is a negative errno value.  The number *     of io->bytes transferred before the error is usually less *     than requested, and can be nonzero. * (3) cancellation, a type of error with status -ECONNRESET that *     is initiated by usb_sg_cancel(). * * When this function returns, all memory allocated through usb_sg_init() or * this call will have been freed.  The request block parameter may still be * passed to usb_sg_cancel(), or it may be freed.  It could also be * reinitialized and then reused. * * Data Transfer Rates: * * Bulk transfers are valid for full or high speed endpoints. * The best full speed data rate is 19 packets of 64 bytes each * per frame, or 1216 bytes per millisecond. * The best high speed data rate is 13 packets of 512 bytes each * per microframe, or 52 KBytes per millisecond. * * The reason to use interrupt transfers through this API would most likely * be to reserve high speed bandwidth, where up to 24 KBytes per millisecond * could be transferred.  That capability is less useful for low or full * speed interrupt endpoints, which allow at most one packet per millisecond, * of at most 8 or 64 bytes (respectively). */void usb_sg_wait (struct usb_sg_request *io){	int		i, entries = io->entries; 	/* queue the urbs.  */	spin_lock_irq (&io->lock);	for (i = 0; i < entries && !io->status; i++) {		int	retval; 		io->urbs [i]->dev = io->dev;		retval = usb_submit_urb (io->urbs [i], GFP_ATOMIC); 		/* after we submit, let completions or cancelations fire;		 * we handshake using io->status.

Lines 1–500 of 1593.