On 4/23/07, Alan Stern <[EMAIL PROTECTED]> wrote:
> On Mon, 23 Apr 2007, nesta wrote:
>
> > hi all,
> > i have 2 questions:
> >
> > 1) i make simple while loop,at the host side, in which i m receiving the
> data
> > using the read function of usb-skeleton module,it is as follows:
> >
> ***************************************************************************
> > do
> >     {
> >             insize =read (fd,(char*)inbuff, sizeof (inbuff) );
> >             printf("insize is %d\n",insize);
> >             printf(" %s\n",inbuff);
> >     }while (strcmp(inbuff,"end"));
> >
> ****************************************************************************
> > my aim is : when the gadget has something to send to the host this while
> loop
> > will print what the hosts receives from the gadget.
> >
> > but this does not happen when i use the skel_read function,it is in
> > usb-skeleton.c,as when the gadget does not have anything to send to the
> host,i
> > found that the read function is non-blocking and it prints the following
> > forever:
> > insize is -1
> > black line //i think this is because inbuff is empty
>
> The read function _is_ blocking, but it times out after 10 seconds.
>
> > anyway i found that there is a function in skel_read function, named by
> > usb_bulk_msg and the last argument of it, is the timeout and if i set this
> > timeout to zero it will stop printing insize is -1 and thus it becomes a
> > blocking function.
>
> Because you removed the timeout.
>
> > so now if the gadget is not sending anything to the host, the while loop
> stops
> > printing
> > insize is -1
> > bu when the gadget really sends a word like "hello host" for example, the
> host
> > really receives it but still printing the phrase of insize is 64 i.e the
> output
> > is as follows:
> >
> > insize is 64
> > hello host
> > insize is 64
> > insize is 64 and it prints this phrase forever
> > so why it just receives 64B while i was really sending 2KB buffer?
>
> You are contradicting yourself.  Above you said the gadget sends the words
> "hello host", which is 10 bytes, but now you say the gadget sends a
> 2048-byte buffer.  Which is it?
>
> > actually what i want exactly is when the gadget sends "hello host" the
> while
> > looop output is :
> >
> > insize is 2048 // 2KB=2048
> > hello host
>
> Why do you want your program to print that insize is 2048 when it received
> only 10 bytes from the gadget?
>
> Any funny behavior you encounter is probably caused by the gadget.  If you
> know what it is really sending, then you should also know why the host
> behaves the way it does.
>
> > and doesnt print anything else?
> >
> > 2) can i make the following steps in reading instead of usb_bulk_msg:
> > 1.urb = usb_alloc_urb(0, GFP_KERNEL);
> > 2.buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL,
> &urb->transfer_dma);
>
> If buf is for reading, shouldn't you use readsize instead of writesize?
>
> > 3.copy_to_user(buf, user_buffer, readsize
> > 4.usb_fill_bulk_urb( urb, dev->udev,
> >                   usb_rcvctrlpipe(dev->udev, dev->bulk_in_endpointAddr),
> >                  buf, readsize, skel_read_bulk_callback, dev);
> > 5.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
> > 6.usb_submit_urb
> >
> > the location of copy_to_user is correct?or it should be put after
> > usb_submit_urb?
>
> It definitely should go after usb_submit_urb.  In fact, it shouldn't
> execute until after the URB has completed.  Otherwise the data you hand
> back to the user won't be the data coming from the gadget; it will be
> whatever old data was sitting in buf.


i have made the skel_read and its callback as follows:
**********************************************************************************************************
static void skel_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
{
        struct usb_skel *dev;

        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 usb_skel *dev;
        int retval = 0;
        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;
        }

        if (buf != NULL)
        {
                if (copy_to_user(user_buffer, buf , readsize))
                {
                        retval = -EFAULT;
                        goto error;
                }
        }



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

when i run my application that reads data from the gadget by previous code:
i got  the following output while the gadget was not really sending
any data to the host:
insize is 2048

insize is 2048

insize is 2048

insize is 2048

insize is 2048

insize is 2048

insize is 2048

insize is 2048

Afterwords when the gadget really sends data ,like "hello1", to the
host it already receives it right.
but when i terminated my application then run my application again i
got the following output when the gadget is sending nothing to the
host. Have a look at the last line of the output it contains the old
data that the gadget sends to the host which was "hello1"

insize is 2048

insize is 2048

insize is 2048

insize is 2048

insize is 2048

insize is 2048

insize is 2048

insize is 2048

hello1

also i have another problem that when the host sends data to the
gadget, the function skel_write is no longer work.  i dont know why?


>
> > this is the same algorithm for skel_write.so can i make the same algorithm
> with
> > skel_read?or not?
>
> Of course not.  Reads are different from writes.  A write takes data from
> the user and then sends it to the device.  A read takes data from the
> device and then sends it to the user.
>
> Alan Stern
>
>

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