Google
  Web www.spinics.net

Re: [patch 2.6.19-git] rndis_host learns ActiveSync basics

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Hi again,

Here's two patches against the latest revision.

The first patch restores the rx_urb_size, which makes my devices work
again and results in quite acceptable performance for device to host
transfers:
$ pcp ":/My Documents/nightwish - angels fall first - angels fall
first.mp3" "foo.mp3"
File copy of 5385245 bytes took 0 minutes and 8 seconds, that's 673155 bytes/s.
This is equivalent to the Windows driver, if not faster (the fastest I
got there was 625 kB/s, though that was testing against an FTP server
on the device instead of the native RPC API and thus not very
scientifically correct).

The second patch makes rndis_host work with PXA27x-based devices.
(Time to open those champagne bottles! :D)
The fix is simply not setting an alternate setting -- SET_INTERFACE
makes these devices behave strangely ("hanging" the status and bulk
endpoints), leaving this out makes it all work as it should.

Cheers,
Ole André


On 12/16/06, Ole André Vadla Ravnås <oleavr@xxxxxxxxx> wrote:
On 12/15/06, David Brownell <david-b@xxxxxxxxxxx> wrote:
> On Wednesday 13 December 2006 2:17 pm, Ole André Vadla Ravnås wrote:
(...)
> > After debugging this issue further I discovered that RNDIS_MSG_INIT's
> > MaxTransferSize, sent by the host, is the value that
> > usbnet.rx_urb_size should be set to. If this is set to something lower
> > the device will (obviously) prepare larger URB payloads than what we
> > expect, and thus we'll fetch partial ones. This results in horrible
> > performance and makes the device stop responding after attempting a
> > few transfers.
> >
> > Patch (attached): linux-2.6.19-git-rndis_host-rx_usb_size-fix.patch
>
> This patch looks wrong.  Instead, how about this theory:  the peripheral
> is using the "pad with zeroes to end of packet" option on packets it
> sends, but the rndis_host code wasn't expecting that.  The reason your
> patch worked was because it was creating HUGE rx buffers, which also
> coincidntally happened to allow that padding.
>
> I've updated the patch to allow padded RX buffers like that.

Well, I tried with the revised patch and that seems to have broken it
completely.
My theory here is that the MaxTransferSize you specify in the
RNDIS_MSG_INIT is the maximum size you're able to read (IN) in one
transfer (one URB in the USB context). My devices here (HTC Wizard,
HTC TyTN and Dell Axim X51) all batch multiple RNDIS_MSG_PACKET
messages per transfer. So, what happens if you generate sufficient
traffic from the device to the host is that the device batches
multiple packets in each transfer, typically 13-14 kB worth of
packets. When you do one read with the buffer-size set to for instance
8 kB, the device will (obviously) give you the first 8 kB, and the
rest in the next read. So, by stating 16 kB in MaxTransferSize we
oblige to have an rx buffer at least that big. And when sending URBs
to the device, we should never do bigger (OUT) transfers than what the
device reports as MaxTransferSize in the RNDIS_MSG_INIT reply.

Ole André

Index: rndis_host.c
===================================================================
--- rndis_host.c	(revision 2702)
+++ rndis_host.c	(revision 2705)
@@ -419,14 +419,12 @@
 
 	/* max transfer (in spec) is 0x4000 at full speed, but for
 	 * TX we'll stick to one Ethernet packet plus RNDIS framing.
-	 * For RX we handle drivers that zero-pad to end-of-packet.
 	 * Don't let userspace change these settings.
 	 */
 	net->hard_header_len += sizeof (struct rndis_data_hdr);
 	dev->hard_mtu = net->mtu + net->hard_header_len;
 
-	dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1);
-	dev->rx_urb_size &= ~(dev->maxpacket - 1);
+	dev->rx_urb_size = (dev->udev->speed == USB_SPEED_FULL) ? 16384 : 8192;
 	u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
 
 	net->change_mtu = NULL;
Index: rndis_host.c
===================================================================
--- rndis_host.c	(revision 2702)
+++ rndis_host.c	(revision 2705)
@@ -619,7 +617,7 @@
 
 static const struct driver_info	rndis_info = {
 	.description =	"RNDIS device",
-	.flags =	FLAG_ETHER | FLAG_FRAMING_RN,
+	.flags =	FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT,
 	.bind =		rndis_bind,
 	.unbind =	rndis_unbind,
 	.status =	rndis_status,
-------------------------------------------------------------------------
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@xxxxxxxxxxxxxxxxxxxxx
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

[Home]     [Video for Linux]     [Photo]     [Yosemite Forum]     [Yosemite Photos]    [Video Projectors]     [PDAs]     [Hacking TiVo]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Devices]     [Big List of Linux Books]     [Free Dating]

  Powered by Linux