int usb_submit_urb(struct urb *urb, int mem_flags) 
int usb_submit_urb(struct urb *urb, unsigned mem_flags) 
int usb_submit_urb(struct urb *urb, int mem_flags){	int			pipe, temp, max;	struct usb_device	*dev;	struct usb_operations	*op;	int			is_out;	if (!urb || urb->hcpriv || !urb->complete)		return -EINVAL;	if (!(dev = urb->dev) ||	    (dev->state < USB_STATE_DEFAULT) ||	    (!dev->bus) || (dev->devnum <= 0))		return -ENODEV;	if (dev->state == USB_STATE_SUSPENDED)		return -EHOSTUNREACH;	if (!(op = dev->bus->op) || !op->submit_urb)		return -ENODEV;	urb->status = -EINPROGRESS;	urb->actual_length = 0;	urb->bandwidth = 0;	/* Lots of sanity checks, so HCDs can rely on clean data	 * and don't need to duplicate tests	 */	pipe = urb->pipe;	temp = usb_pipetype (pipe);	is_out = usb_pipeout (pipe);	if (!usb_pipecontrol (pipe) && dev->state < USB_STATE_CONFIGURED)		return -ENODEV;	/* FIXME there should be a sharable lock protecting us against	 * config/altsetting changes and disconnects, kicking in here.	 * (here == before maxpacket, and eventually endpoint type,	 * checks get made.)	 */	max = usb_maxpacket (dev, pipe, is_out);	if (max <= 0) {		dev_dbg(&dev->dev,			"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",			usb_pipeendpoint (pipe), is_out ? "out" : "in",			__FUNCTION__, max);		return -EMSGSIZE;	}	/* periodic transfers limit size per frame/uframe,	 * but drivers only control those sizes for ISO.	 * while we're checking, initialize return status.	 */	if (temp == PIPE_ISOCHRONOUS) {		int	n, len;		/* "high bandwidth" mode, 1-3 packets/uframe? */		if (dev->speed == USB_SPEED_HIGH) {			int	mult = 1 + ((max >> 11) & 0x03);			max &= 0x07ff;			max *= mult;		}		if (urb->number_of_packets <= 0)		    			return -EINVAL;		for (n = 0; n < urb->number_of_packets; n++) {			len = urb->iso_frame_desc [n].length;			if (len < 0 || len > max) 				return -EMSGSIZE;			urb->iso_frame_desc [n].status = -EXDEV;			urb->iso_frame_desc [n].actual_length = 0;		}	}	/* the I/O buffer must be mapped/unmapped, except when length=0 */	if (urb->transfer_buffer_length < 0)		return -EMSGSIZE;#ifdef DEBUG	/* stuff that drivers shouldn't do, but which shouldn't	 * cause problems in HCDs if they get it wrong.	 */	{	unsigned int	orig_flags = urb->transfer_flags;	unsigned int	allowed;	/* enforce simple/standard policy */	allowed = URB_ASYNC_UNLINK;	// affects later unlinks	allowed |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);	allowed |= URB_NO_INTERRUPT;	switch (temp) {	case PIPE_BULK:		if (is_out)			allowed |= URB_ZERO_PACKET;		/* FALLTHROUGH */	case PIPE_CONTROL:		allowed |= URB_NO_FSBR;	/* only affects UHCI */		/* FALLTHROUGH */	default:			/* all non-iso endpoints */		if (!is_out)			allowed |= URB_SHORT_NOT_OK;		break;	case PIPE_ISOCHRONOUS:		allowed |= URB_ISO_ASAP;		break;	}	urb->transfer_flags &= allowed;	/* fail if submitter gave bogus flags */	if (urb->transfer_flags != orig_flags) {		err ("BOGUS urb flags, %x --> %x",			orig_flags, urb->transfer_flags);		return -EINVAL;	}	}#endif	/*	 * Force periodic transfer intervals to be legal values that are	 * a power of two (so HCDs don't need to).	 *	 * FIXME want bus->{intr,iso}_sched_horizon values here.  Each HC	 * supports different values... this uses EHCI/UHCI defaults (and	 * EHCI can use smaller non-default values).	 */	switch (temp) {	case PIPE_ISOCHRONOUS:	case PIPE_INTERRUPT:		/* too small? */		if (urb->interval <= 0)			return -EINVAL;		/* too big? */		switch (dev->speed) {		case USB_SPEED_HIGH:	/* units are microframes */			// NOTE usb handles 2^15			if (urb->interval > (1024 * 8))				urb->interval = 1024 * 8;			temp = 1024 * 8;			break;		case USB_SPEED_FULL:	/* units are frames/msec */		case USB_SPEED_LOW:			if (temp == PIPE_INTERRUPT) {				if (urb->interval > 255)					return -EINVAL;				// NOTE ohci only handles up to 32				temp = 128;			} else {				if (urb->interval > 1024)					urb->interval = 1024;				// NOTE usb and ohci handle up to 2^15				temp = 1024;			}			break;		default:			return -EINVAL;		}		/* power of two? */		while (temp > urb->interval)			temp >>= 1;		urb->interval = temp;	}	return op->submit_urb (urb, mem_flags);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/5db539e49fc7471e23bf3c94ca304f008cb7b7f3/urb.c/clean/drivers/usb/core/urb.c