as->task = current; 
as->pid = current->pid; as->uid = current->uid; as->euid = current->euid; 
static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,			     struct usbdevfs_iso_packet_desc __user *iso_frame_desc,			     void __user *arg){	struct usbdevfs_iso_packet_desc *isopkt = NULL;	struct usb_host_endpoint *ep;	struct async *as;	struct usb_ctrlrequest *dr = NULL;	unsigned int u, totlen, isofrmlen;	int ret, interval = 0, ifnum = -1;	if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK|			   URB_NO_FSBR|URB_ZERO_PACKET))		return -EINVAL;	if (!uurb->buffer)		return -EINVAL;	if (uurb->signr != 0 && (uurb->signr < SIGRTMIN || uurb->signr > SIGRTMAX))		return -EINVAL;	if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {		if ((ifnum = findintfep(ps->dev, uurb->endpoint)) < 0)			return ifnum;		if ((ret = checkintf(ps, ifnum)))			return ret;	}	if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0)		ep = ps->dev->ep_in [uurb->endpoint & USB_ENDPOINT_NUMBER_MASK];	else		ep = ps->dev->ep_out [uurb->endpoint & USB_ENDPOINT_NUMBER_MASK];	if (!ep)		return -ENOENT;	switch(uurb->type) {	case USBDEVFS_URB_TYPE_CONTROL:		if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)				!= USB_ENDPOINT_XFER_CONTROL)			return -EINVAL;		/* min 8 byte setup packet, max arbitrary */		if (uurb->buffer_length < 8 || uurb->buffer_length > PAGE_SIZE)			return -EINVAL;		if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL)))			return -ENOMEM;		if (copy_from_user(dr, uurb->buffer, 8)) {			kfree(dr);			return -EFAULT;		}		if (uurb->buffer_length < (le16_to_cpup(&dr->wLength) + 8)) {			kfree(dr);			return -EINVAL;		}		if ((ret = check_ctrlrecip(ps, dr->bRequestType, le16_to_cpup(&dr->wIndex)))) {			kfree(dr);			return ret;		}		uurb->endpoint = (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) | (dr->bRequestType & USB_ENDPOINT_DIR_MASK);		uurb->number_of_packets = 0;		uurb->buffer_length = le16_to_cpup(&dr->wLength);		uurb->buffer += 8;		if (!access_ok((uurb->endpoint & USB_DIR_IN) ?  VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) {			kfree(dr);			return -EFAULT;		}		break;	case USBDEVFS_URB_TYPE_BULK:		switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {		case USB_ENDPOINT_XFER_CONTROL:		case USB_ENDPOINT_XFER_ISOC:			return -EINVAL;		/* allow single-shot interrupt transfers, at bogus rates */		}		uurb->number_of_packets = 0;		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)			return -EINVAL;		if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length))			return -EFAULT;		break;	case USBDEVFS_URB_TYPE_ISO:		/* arbitrary limit */		if (uurb->number_of_packets < 1 || uurb->number_of_packets > 128)			return -EINVAL;		if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)				!= USB_ENDPOINT_XFER_ISOC)			return -EINVAL;		interval = 1 << min (15, ep->desc.bInterval - 1);		isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets;		if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))			return -ENOMEM;		if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) {			kfree(isopkt);			return -EFAULT;		}		for (totlen = u = 0; u < uurb->number_of_packets; u++) {			if (isopkt[u].length > 1023) {				kfree(isopkt);				return -EINVAL;			}			totlen += isopkt[u].length;		}		if (totlen > 32768) {			kfree(isopkt);			return -EINVAL;		}		uurb->buffer_length = totlen;		break;	case USBDEVFS_URB_TYPE_INTERRUPT:		uurb->number_of_packets = 0;		if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)				!= USB_ENDPOINT_XFER_INT)			return -EINVAL;		if (ps->dev->speed == USB_SPEED_HIGH)			interval = 1 << min (15, ep->desc.bInterval - 1);		else			interval = ep->desc.bInterval;		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)			return -EINVAL;		if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length))			return -EFAULT;		break;	default:		return -EINVAL;	}	if (!(as = alloc_async(uurb->number_of_packets))) {		kfree(isopkt);		kfree(dr);		return -ENOMEM;	}	if (!(as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL))) {		kfree(isopkt);		kfree(dr);		free_async(as);		return -ENOMEM;	}        as->urb->dev = ps->dev;        as->urb->pipe = (uurb->type << 30) | __create_pipe(ps->dev, uurb->endpoint & 0xf) | (uurb->endpoint & USB_DIR_IN);        as->urb->transfer_flags = uurb->flags;	as->urb->transfer_buffer_length = uurb->buffer_length;	as->urb->setup_packet = (unsigned char*)dr;	as->urb->start_frame = uurb->start_frame;	as->urb->number_of_packets = uurb->number_of_packets;	as->urb->interval = interval;        as->urb->context = as;        as->urb->complete = async_completed;	for (totlen = u = 0; u < uurb->number_of_packets; u++) {		as->urb->iso_frame_desc[u].offset = totlen;		as->urb->iso_frame_desc[u].length = isopkt[u].length;		totlen += isopkt[u].length;	}	kfree(isopkt);	as->ps = ps;        as->userurb = arg;	if (uurb->endpoint & USB_DIR_IN)		as->userbuffer = uurb->buffer;	else		as->userbuffer = NULL;	as->signr = uurb->signr;	as->ifnum = ifnum;	as->task = current;	if (!(uurb->endpoint & USB_DIR_IN)) {		if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) {			free_async(as);			return -EFAULT;		}	}        async_newpending(as);        if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) {		dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret);                async_removepending(as);                free_async(as);                return ret;        }        return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/46113830a18847cff8da73005e57bc49c2f95a56/devio.c/clean/drivers/usb/core/devio.c