> > After our repeated verification and debug, we found that windows > > virtual machine USB disk format will send a 64Kbits's URB packet > > which was divided into four QTD (Size: 19968,16384,16384,12800): > > That's okay. > > > The first QTD offset is 32, split into five URB > > 4064/4096/4096/4096/3616 bits ( we don't understand why the offset is > > always 32, but the linux virtual machine is always 0) > > I guess Windows uses strange offsets. Are the pages that make up the > qTD adjacent in the host's virtual memory?
I think that the pages are not adjacent in the host's virtual memory. Because the qTD was split up by function ehci_init_transfer and into 5 parts which added to p->sgl. In function usb_packet_map(qemu-1.4.0/hw/usb/libhw.c), the 5 parts make DMA mapping respectively, and finally stored in p->iov[] making up 5 URBs for transfer. > > The second QTD offset 3616, split into five URB > > 480/4096/4096/4096/3616 bits > > Third QTD offset is 3616, split into five URB 480/4096/4096/4096/3616 bits > > Fourth QTD offset is 3616, split into five URB 480/4096/4096/4096/32 bits > > Fixing this will require qemu to copy the beginning and ending parts of > these non-aligned qTDs into separate bounce buffers so that the URB > length can be divisible by 512. For example, with the first qTD above, > qemu could send one URB of length 3584 at offset 32. Then qemu would > copy the last 480 bytes from that page and the first 32 bytes from the > next page into a bounce buffer, and send a 512-byte URB for that > buffer. Then qemu would send a 3584-byte URB starting at offset 480 in > the second page, and so on. > > Of course, this can be optimized in the case where the pages happen to > be adjacent in the host's memory. It's okay to let an URB span a page > boundary. But if the pages aren't adjacent, you will have to use a > bounce buffer. > Good to know, thanks! I will have a try. > By the way, this approach has to be used for control and interrupt > transfers as well as bulk transfers. If a guest's qTD has be to split > up, all the pieces except the last must be a multiple of the > wMaxPacketSize value. > > Alan Stern Best Regards! -Gonglei