>>Hello everyone,
>>
>>         I currently have a driver that has 1024 byte endpoint buffers 
>>(bulk
>>transfer) and it is running on the AT91RM9200. I am running 2.6.12, but
>>I looked at the kernel git tree head(2.6.20) at91_udc.c code and it has
>>the same issue. My gadget can accept data from the host and the data
>>will be any amount.
>>         If data is transmitted from the host and its length is 960 bytes 
>>lets
>>say, the read_fifo() does not call done() because the length of the last
>>transfer is 64 bytes and the 1024 byte buffer is not yet full so is_done
>>is set to zero (below).
>>code snippet, at91_udc.c::read_fifo():
>>
>>         req->req.actual += count;
>>         is_done = (count < ep->ep.maxpacket);
>>         if (count == bufferspace)
>>                 is_done = 1;
>>
>>         PACKET("%s %p out/%d%s\n", ep->ep.name, &req->req, count, is_done 
>>? "
>>(done)" : "");
>>
>>         /*
>>         * avoid extra trips through IRQ logic for packets already in
>>         * the fifo ... maybe preventing an extra (expensive) OUT-NAK
>>         */
>>         if (is_done)
>>                 done(ep, req, 0);
>>end snippet;
>>If I run "cat /proc/driver/udc", I see a request sitting with 960/1024
>>bytes used.  Upon the completion of the next transfer, the first
>>transfer will then be sent as done() will be called.
>>         So I have changed my host program to check and see if the data 
>>size
>>being sent to the gadget is divisible by 64 (size % 64 == 0).  If it is,
>>then I add a small chunk so that the driver will handle it correctly and
>>the data will be processed upon transfer completion.
>>         I hate this fix, but it is the only one I can think of, anybody 
>>have a
>>better way of fixing this issue?  I looked at the driver and could not
>>come up with an elegant solution to this.
>>
>>Regards,
>>
>>Jeff Warren
>>

Hi Jeff,

You have run into the situation that can be solved with a zero length packet 
(ZLP).

The problem is knowing when a transfer is complete. On all sizes not 
divisible by maxpacketlen the hardware knows it is a short packet and the 
transfer is done. If your host/gadget communicate and know the exact length 
of a transfer then that can also end a transfer. The problem is if you want 
random length transfers, how can the hardware know the transfer is done? 
Only if it gets a short packet. But what if the length is divisible by 
maxpacketlen? The solution is to send a ZLP.

I don't write windows minidrivers but I know someone who does. There is some 
kind of endpoint setup bit that says to send/recv ZLP. Using that solution 
will work for packets that are any size divisible by 64 (with your hardware 
having a maximum size of 1024 bytes).

Regards, Steve.

_________________________________________________________________
Mortgage rates as low as 4.625% - Refinance $150,000 loan for $579 a month. 
Intro*Terms  http://www.NexTag.com


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
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