RE: USB2.0 disk format failure in windows guest

2013-04-17 Thread Gonglei (Arei)

  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



RE: USB2.0 disk format failure in windows guest

2013-04-17 Thread Gonglei (Arei)
 
  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.
 
 Worth trying:  http://www.kraxel.org/cgit/qemu/log/?h=usb.80
 
 It puts the qemu usb passthrough code upside down.  All xfers will go
 through a bounce buffer, requests are submitted via libusbx.  That
 should fix it.  Of course there is the risk of regressions in other
 areas as it is all new code.  Also make sure you have libusbx-devel
 installed, otherwise qemu will fallback to the old code which uses usbfs
 ioctls directly.


That's great! According to Gerd's patch, I format USB2.0 disk successfully in 
windows guest.
Get to log below by usbmon:

880c0e7e15c0 4071447263 S Bo:6:009:2 -115 31 = 55534243 08903b84 0002 
8a28 eebf ff01  00
880c0e7e15c0 4071447428 C Bo:6:009:2 0 31 
880c0e7e15c0 4071448094 S Bi:6:009:1 -115 512 
880c0e7e15c0 4071448302 C Bi:6:009:1 0 512 =    
    
880c0e7e15c0 4071448946 S Bi:6:009:1 -115 512 
880c0e7e15c0 4071449077 C Bi:6:009:1 -121 13 = 55534253 08903b84  00
880c0e7e15c0 4071449891 S Bo:6:009:2 -115 31 = 55534243 08109984 0100 
0a2a 0008 de80  00
880c0e7e15c0 4071450057 C Bo:6:009:2 0 31 
880c0e7e15c0 4071454013 S Bo:6:009:2 -115 16384 = f80f ff0f 
ff0f     
880c0e7e1800 4071454319 S Bo:6:009:2 -115 3584 =    
    
880c0e7e15c0 4071454940 C Bo:6:009:2 0 16384 
880c0e7e1800 4071454974 C Bo:6:009:2 0 3584 
880c0e7e1800 4071456846 S Bo:6:009:2 -115 16384 =   
     
880c0e7e1800 4071457406 C Bo:6:009:2 0 16384 
880c0e7e1800 4071458841 S Bo:6:009:2 -115 16384 =   
     
880c0e7e1800 4071460280 C Bo:6:009:2 0 16384 
880c0e7e1800 4071461412 S Bo:6:009:2 -115 12800 =   
     
880c0e7e1800 4071461905 C Bo:6:009:2 0 12800 
880c0e7e1800 4071462620 S Bi:6:009:1 -115 512 
880c0e7e1800 4071462780 C Bi:6:009:1 -121 13 = 55534253 08109984  00
880c0e7e1800 4071463486 S Bo:6:009:2 -115 31 = 55534243 08903b84 0100 
0a2a 0009 5e80  00
880c0e7e1800 4071463528 C Bo:6:009:2 0 31 

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

19968 = 16384 + 3584, and all the URBs size that is a multiple of 512. (usbfs 
places a 16kb limit on bulk URBs)
Alan  Gerd, Thanks a lot!

Best Regards!
-Gonglei





RE: USB2.0 disk format failure in windows guest

2013-04-16 Thread Alan Stern
On Tue, 16 Apr 2013, Gonglei (Arei) wrote:

   Yes, this disk was using EHCI, since guest QEMU and Linux kernel both
   prints matching EHCI logs, such as transfer types and transfer sizes.
   There are many buck-out URBs whose sizes are 31 or 4064 that are not
   multiples of 512. Since URB size 31 does occur without guest format
   USB 2.0 disk sceneiro, did you mean that buck-out size 4064 should
   not occur? /* EHCI spec version 1.0 Section 4.10.6 */
  
  That's right; it should not occur.
  
  It's okay to have an URB size that isn't a multiple of 512 if that URB
  is the last one in a transfer.  For example, the 31-byte URBs were the
  only URBs in their transfers, so they were okay.  But the 4064-byte
  URBs occurred at the start and in the middle of their transfers, so
  they were wrong.
  
 
 Alan, the code which get the virtual machine USB packet in the Qemu is as 
 follows:
 # /qemu-1.4.0/hw/usb/hcd-ehci.c
 static int ehci_init_transfer(EHCIPacket *p)
 {
 uint32_t cpage, offset, bytes, plen;
 dma_addr_t page;
 
 cpage  = get_field(p-qtd.token, QTD_TOKEN_CPAGE);
 bytes  = get_field(p-qtd.token, QTD_TOKEN_TBYTES);
 offset = p-qtd.bufptr[0]  ~QTD_BUFPTR_MASK;
 pci_dma_sglist_init(p-sgl, p-queue-ehci-dev, 5);
 
 while (bytes  0) {
 if (cpage  4) {
 fprintf(stderr, cpage out of range (%d)\n, cpage);
 return USB_RET_PROCERR;
 }
 
 page  = p-qtd.bufptr[cpage]  QTD_BUFPTR_MASK;
 page += offset;
 plen  = bytes;
 if (plen  4096 - offset) {
 plen = 4096 - offset;
 offset = 0;
 cpage++;
 }
 
 qemu_sglist_add(p-sgl, page, plen);
 bytes -= plen;
 }
 return 0;
 }

I see.

 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?

 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.

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

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB2.0 disk format failure in windows guest

2013-04-16 Thread Gerd Hoffmann
  Hi,

 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.

Worth trying:  http://www.kraxel.org/cgit/qemu/log/?h=usb.80

It puts the qemu usb passthrough code upside down.  All xfers will go
through a bounce buffer, requests are submitted via libusbx.  That
should fix it.  Of course there is the risk of regressions in other
areas as it is all new code.  Also make sure you have libusbx-devel
installed, otherwise qemu will fallback to the old code which uses usbfs
ioctls directly.

cheers,
  Gerd

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: USB2.0 disk format failure in windows guest

2013-04-15 Thread Alan Stern
On Sun, 14 Apr 2013, Gonglei (Arei) wrote:

   Hi Alan,
   We pass-throughed USB 2.0 disk to guest using usb-host (qemu option:
  -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,hostbus=2,hostport=1) 
  on
  KVM(on linux-3.8.3 or linux-3.0.13) and qemu 1.4.0 ,
  
  Are you sure this disk was using EHCI?  The attached log shows bulk
  packet sizes that aren't multiples of 512, which isn't possible in the
  middle of a high-speed transfer.
 
 Yes, this disk was using EHCI, since guest QEMU and Linux kernel both
 prints matching EHCI logs, such as transfer types and transfer sizes.
 There are many buck-out URBs whose sizes are 31 or 4064 that are not
 multiples of 512. Since URB size 31 does occur without guest format
 USB 2.0 disk sceneiro, did you mean that buck-out size 4064 should
 not occur? /* EHCI spec version 1.0 Section 4.10.6 */

That's right; it should not occur.

It's okay to have an URB size that isn't a multiple of 512 if that URB
is the last one in a transfer.  For example, the 31-byte URBs were the
only URBs in their transfers, so they were okay.  But the 4064-byte
URBs occurred at the start and in the middle of their transfers, so
they were wrong.

  What kernel version did you use while recording this log?
 
 We tested KVM on Linux 3.8.3 and Linux 3.0.13, and the problem exists
 on both kernels.

But which kernel version did you use while recording the log that you 
posted?

Also, what type of computer is your host?

 This time we attached a usbmon USB disk format failed log and
 USBlyzer' logs for another test. Would you give us some advice,
 thanks a lot!
 
 Something look like:
 
 88180b974600 480512312 S Bo:6:009:2 -115 31 = 55534243 50599784 0100 
 0a2a 0008 de80  00
 88180b974600 480512375 C Bo:6:009:2 0 31 
 88180b974600 480513372 S Bo:6:009:2 -115 4064 = f80f ff0f 
 ff0f     

This is a lot more concise than the other log, but it still shows the 
same problem: the 4064-byte URB.

Can you post the contents of the /sys/kernel/debug/usb/devices file?

Alan Stern

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: USB2.0 disk format failure in windows guest

2013-04-15 Thread Gonglei (Arei)

 -Original Message-
 From: Alan Stern [mailto:st...@rowland.harvard.edu]
 Sent: Tuesday, April 16, 2013 1:44 AM
 To: Gonglei (Arei)
 Cc: linux-usb@vger.kernel.org; Yanqiangjun; Hanweidong; Luonengjun;
 kra...@redhat.com; hdego...@redhat.com; qemu-de...@nongnu.org
 Subject: RE: USB2.0 disk format failure in windows guest
 
 On Sun, 14 Apr 2013, Gonglei (Arei) wrote:
 
Hi Alan,
We pass-throughed USB 2.0 disk to guest using usb-host (qemu option:
   -device usb-ehci,id=ehci -device usb-host,bus=ehci.0,hostbus=2,hostport=1)
 on
   KVM(on linux-3.8.3 or linux-3.0.13) and qemu 1.4.0 ,
  
   Are you sure this disk was using EHCI?  The attached log shows bulk
   packet sizes that aren't multiples of 512, which isn't possible in the
   middle of a high-speed transfer.
 
  Yes, this disk was using EHCI, since guest QEMU and Linux kernel both
  prints matching EHCI logs, such as transfer types and transfer sizes.
  There are many buck-out URBs whose sizes are 31 or 4064 that are not
  multiples of 512. Since URB size 31 does occur without guest format
  USB 2.0 disk sceneiro, did you mean that buck-out size 4064 should
  not occur? /* EHCI spec version 1.0 Section 4.10.6 */
 
 That's right; it should not occur.
 
 It's okay to have an URB size that isn't a multiple of 512 if that URB
 is the last one in a transfer.  For example, the 31-byte URBs were the
 only URBs in their transfers, so they were okay.  But the 4064-byte
 URBs occurred at the start and in the middle of their transfers, so
 they were wrong.
 

Alan, the code which get the virtual machine USB packet in the Qemu is as 
follows:
# /qemu-1.4.0/hw/usb/hcd-ehci.c
static int ehci_init_transfer(EHCIPacket *p)
{
uint32_t cpage, offset, bytes, plen;
dma_addr_t page;

cpage  = get_field(p-qtd.token, QTD_TOKEN_CPAGE);
bytes  = get_field(p-qtd.token, QTD_TOKEN_TBYTES);
offset = p-qtd.bufptr[0]  ~QTD_BUFPTR_MASK;
pci_dma_sglist_init(p-sgl, p-queue-ehci-dev, 5);

while (bytes  0) {
if (cpage  4) {
fprintf(stderr, cpage out of range (%d)\n, cpage);
return USB_RET_PROCERR;
}

page  = p-qtd.bufptr[cpage]  QTD_BUFPTR_MASK;
page += offset;
plen  = bytes;
if (plen  4096 - offset) {
plen = 4096 - offset;
offset = 0;
cpage++;
}

qemu_sglist_add(p-sgl, page, plen);
bytes -= plen;
}
return 0;
}

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

   What kernel version did you use while recording this log?
 
  We tested KVM on Linux 3.8.3 and Linux 3.0.13, and the problem exists
  on both kernels.
 
 But which kernel version did you use while recording the log that you
 posted?

Sorry, the kernel version is Linux-3.8.3 while recording the log.

 
 Also, what type of computer is your host?

The host's system Information:
Manufacturer: Huawei Technologies Co., Ltd.
Product Name: Tecal RH2285
BTW, we tested on the IBM Server (IBM System X iDataPlex dx360 M4 Server 
-[7912FT1]-), and got the same results.

 
  This time we attached a usbmon USB disk format failed log and
  USBlyzer' logs for another test. Would you give us some advice,
  thanks a lot!
 
  Something look like:
 
  88180b974600 480512312 S Bo:6:009:2 -115 31 = 55534243 50599784
 0100 0a2a 0008 de80  00
  88180b974600 480512375 C Bo:6:009:2 0 31 
  88180b974600 480513372 S Bo:6:009:2 -115 4064 = f80f ff0f 
  ff0f
     
 
 This is a lot more concise than the other log, but it still shows the
 same problem: the 4064-byte URB.
 
 Can you post the contents of the /sys/kernel/debug/usb/devices file?
 
OK, it looks like

$ cat /sys/kernel/debug/usb/devices 

T:  Bus=06 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 6
B:  Alloc=  0/800 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 3.08
S:  Manufacturer=Linux 3.8.3-0.27-gonglei ehci_hcd
S:  Product=EHCI Host Controller
S:  SerialNumber=:00:1d.7
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

T:  Bus=06 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  9 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=136b ProdID=0003 Rev= 1.00
S

Re: USB2.0 disk format failure in windows guest

2013-04-11 Thread Alan Stern
On Wed, 10 Apr 2013, Gonglei (Arei) wrote:

 Hi Alan,
 We pass-throughed USB 2.0 disk to guest using usb-host (qemu option: -device 
 usb-ehci,id=ehci -device usb-host,bus=ehci.0,hostbus=2,hostport=1) on KVM(on 
 linux-3.8.3 or linux-3.0.13) and qemu 1.4.0 ,

Are you sure this disk was using EHCI?  The attached log shows bulk
packet sizes that aren't multiples of 512, which isn't possible in the
middle of a high-speed transfer.

Also, the log doesn't show data for the IN transfers.  Did you remove 
it?

  it worked fine for reading and writing data, but failed when format it in a 
 windows Guest OS such as winXP,win7,win2003. We captured usb operations on 
 Dom0, found below logs:
   ...
 Feb  1 11:17:50 linux-bLKBXy kernel: [66642.325169] usb 6-1: usbdev_do_ioctl: 
 REAPURBNDELAY
 Feb  1 11:17:50 linux-bLKBXy kernel: [66642.325172] usb 6-1: usbdev_do_ioctl: 
 REAPURBNDELAY
 Feb  1 11:17:50 linux-bLKBXy kernel: [66642.325176] usb 6-1: usbdev_do_ioctl: 
 REAPURBNDELAY
 Feb  1 11:17:50 linux-bLKBXy kernel: [66642.326757] usb 6-1: urb complete
 Feb  1 11:17:50 linux-bLKBXy kernel: [66642.326761] usb 6-1: userurb 
 7fa196d04b10, ep2 bulk-out, actual_length 4096 status 0
 Feb  1 11:17:50 linux-bLKBXy kernel: [66642.326780] usb 6-1: usbdev_do_ioctl: 
 REAPURBNDELAY
 Feb  1 11:17:50 linux-bLKBXy kernel: [66642.326787] usb 6-1: usbdev_do_ioctl: 
 REAPURBNDELAY--- stuck here about one minute or 10 seconds
 Feb  1 11:18:50 linux-bLKBXy kernel: [66702.289239] usb 6-1: usbdev_do_ioctl: 
 DISCARDURB --- received a DISCARD instruction
 Feb  1 11:18:50 linux-bLKBXy kernel: [66702.289398] usb 6-1: urb complete
 Feb  1 11:18:50 linux-bLKBXy kernel: [66702.289403] usb 6-1: userurb 
 7fa196d04d00, ep2 bulk-out, actual_length 512 status -2  
 Feb  1 11:18:50 linux-bLKBXy kernel: [66702.289437] usb 6-1: usbdev_do_ioctl: 
 REAPURBNDELAY
 Feb  1 11:18:50 linux-bLKBXy kernel: [66702.289450] usb 6-1: usbdev_do_ioctl: 
 REAPURBNDELAY
 Feb  1 11:18:50 linux-bLKBXy kernel: [66702.428985] usb 6-1: usbdev_do_ioctl: 
 RESET --- received a reset instruction to retry
 
 We are wondering why the usb operation will be stuck one minute and then 
 DISCARD instruction was issued. Was DISCARD instruction triggered by a time 
 out in format software? Any ideas? Thanks.
 
 BTW, We attached usb operation logs:  windows format log (failure)  

What kernel version did you use while recording this log?

This looks like a hardware problem in the disk drive's USB interface or
in the computer's USB controller.  Either the drive stopped accepting
data or else the controller stopped sending data.  After 10 seconds (or
one minute), the command timed out and the URB was cancelled.

To find out exactly what is going wrong, you would need to use a USB 
bus analyzer to monitor the packets as they go across the USB cable.

Alan Stern

P.S.: For recording USB data transfers, it's generally better to use 
usbmon rather than usbfs_snoop.

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html