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

Oliver Neukum <[email protected]>
Newsgroups gmane.linux.usb.devel
Organization Novell
Message-ID <[email protected]>
Am Dienstag, 24. April 2007 13:19 schrieb Wael Adel:
 
> 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);

Don't free the buffer here. You want to read from it.

> 	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;

You need to call init_completion() on that before you use it.

> 	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 */

read that would be

> 	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);

You must pass a pointer to done, not 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);

write?

> 		goto error;
> 	}
> 
> 	wait_for_completion(&done);
> 
> 	if (   copy_to_user(user_buffer, dev->bulk_in_buffer, readbytes) )
> 		retval = -EFAULT;
> 	else
> 		retval = readbytes;

1. Here you need to free the URB and the buffer
2. You must deal with your device delivering less bytes than you asked for
You can use urb->actual_length
 
> 	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
> >
> 

-- 
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.