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/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to