[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] USB2.0 disk format failure in windows guest
From: |
Gonglei (Arei) |
Subject: |
Re: [Qemu-devel] USB2.0 disk format failure in windows guest |
Date: |
Wed, 17 Apr 2013 10:55:13 +0000 |
> > 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