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