qemu-devel
[Top][All Lists]
Advanced

[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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]