Re: how can i make the skeleton read function blocking function?

"Wael Adel" <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
On 4/24/07, Oliver Neukum <[email protected]> wrote:
> Am Dienstag, 24. April 2007 12:06 schrieb Wael Adel:
> > On 4/24/07, Oliver Neukum <[email protected]> wrote:
> > > Am Dienstag, 24. April 2007 11:46 schrieb Wael Adel:
> > > >         retval = usb_submit_urb(urb, GFP_KERNEL);
> > > >         if (retval) {
> > > >                 err("%s - failed submitting write urb, error %d",
> > > __FUNCTION__, retval);
> > > >                 goto error;
> > > >         }
> > > >
> > > >         if (buf != NULL)
> > > >         {
> > > >                 if (copy_to_user(user_buffer, buf , readsize))
> > > >                 {
> > > >                         retval = -EFAULT;
> > > >                         goto error;
> > > >                 }
> > > >         }
> > >
> > > You are copying the the buffer to user space without waiting for the
> > > URB to be executed. That cannot work.
> >
> > so how can i wait for the urb to be executed then copying the data to
> > the user space?
> > is there a flag that i should loop on it or what?
>
> - init an instance of "struct completion"
> - submit the URB, passing a pointer to the struct completion
> - use wait_for_completion()
>
> - in the completion handler call complete()


so these are the required modifications required to wait until the urb
is finished then i can transfer the read data to the user-space

***********************************************************************************************************************
static void skel_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
{
	struct usb_skel *dev;
	complete((struct completion *)urb->context);
	dev = (struct usb_skel *)urb->context;


	/* sync/async unlink faults aren't errors */
	if (urb->status &&
	    !(urb->status == -ENOENT ||
	      urb->status == -ECONNRESET ||
	      urb->status == -ESHUTDOWN)) {
		dbg("%s - nonzero write bulk status received: %d",
		    __FUNCTION__, urb->status);
	}

	/* free up our allocated buffer */
	usb_buffer_free(urb->dev, urb->transfer_buffer_length,
			urb->transfer_buffer, urb->transfer_dma);
	up(&dev->limit_sem);
}

static ssize_t skel_read(struct file *file, const char *user_buffer,
size_t count, loff_t *ppos)
{
	struct completion done;
	struct usb_skel *dev;
	int retval = 0,readbytes;
	struct urb *urb = NULL;
	char *buf = NULL;
	size_t readsize = min(count, (size_t)MAX_TRANSFER);

	dev = (struct usb_skel *)file->private_data;

	/* verify that we actually have some data to write */
	if (count == 0)
		goto exit;

	/* limit the number of URBs in flight to stop a user from using up all RAM */
	if (down_interruptible(&dev->limit_sem)) {
		retval = -ERESTARTSYS;
		goto exit;
	}

	/* create a urb, and a buffer for it, and copy the data to the urb */
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb) {
		retval = -ENOMEM;
		goto error;
	}

	buf = usb_buffer_alloc(dev->udev, readsize, GFP_KERNEL, &urb->transfer_dma);
	if (!buf) {
		retval = -ENOMEM;
		goto error;
	}

	/* initialize the urb properly */
	usb_fill_bulk_urb(urb, dev->udev,
			  usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
			  buf, readsize, skel_read_bulk_callback, dev);
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	/* send the data out the bulk port */
	retval = usb_submit_urb(urb, GFP_KERNEL);
	if (retval) {
		err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
		goto error;
	}

	wait_for_completion(&done);

	if (   copy_to_user(user_buffer, dev->bulk_in_buffer, readbytes) )
		retval = -EFAULT;
	else
		retval = readbytes;


	return retval;

	/* release our reference to this urb, the USB core will eventually
free it entirely */
	usb_free_urb(urb);

exit:
	return readsize;

error:
	usb_buffer_free(dev->udev, readsize, buf, urb->transfer_dma);
	usb_free_urb(urb);
	up(&dev->limit_sem);
	return retval;
}
*********************************************************************************************************************
is it right? or there is something else i should adjust.
thanks in advance.

>
> 	HTH
> 		Oliver
> --
> SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
> This signature is a legal requirement
>

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.