Hi, While I was trying to make my WM5/smartphone work with Linux, I stumbled on problems as described in Bug 8094 (http://bugzilla.kernel.org/show_bug.cgi?id=8094).
While studying this I think I found a problem in usbnet explaining why the synce WM5 patch (http://synce.svn.sourceforge.net/svnroot/synce/trunk/patches/linux-2.6.22-rndis_host-wm5.patch) was required to get my phone connected. The above WM5 patch is believed to be inadequate for memory constraint system (as I learned in the Bug 8094 discussion). But this patch might not be needed if the patch I am proposing here is applied to usbnet. I already proposed my patch in Bug 8094 but as I didn't receive any comment I decided to redo it on the list (Sorry if that was not the right decision) Here is the description of the problem (copy/paste form Bug 8094): When the rndis_host bind() function is called (by usbnet_probe()) the dev->maxpacket is not yet set (It will be set later in usbnet_probe()). As it is 0 the computed dev->rx_urb_size is also 0 and therefore the "max_transfer_size" sent to the device in the RNDIS_MSG_INIT message is also 0. I am not sure how the device will react to this but obviously this is a bogus value. So it seems dev->maxpacket needs to be set before calling the bind() function (it makes some sense as rndis_bind() is using it). This means we need to move up the call to usb_maxpacket() in the usbnet_probe() function. But the call to usb_maxpacket() is requiring dev->out to be set which in turn requires this computation to be moved above the call to usb_maxpacket() (by the way I am not sure dev->out is set correctly with the actual version of the driver in case of a bind() device) I am attaching a proposal for a patch to fix this problem (assuming I didn't overlook anything). With this patch the dev->rx_urb_size and the "max_transfer_size" are computed to 1600 with my device (qtek 9100) which seems reasonable enough. More importantly this works for me and I am able to communicate with the smartphone (without changing rndis_host.c with the wm5 patch). Any comment is welcome. JC Signed-off-by: Jean-Christophe Dubois <[EMAIL PROTECTED]> --- diff -ruN linux-source-2.6.24/drivers/net/usb/usbnet.c linux-source-2.6.24.new/drivers/net/usb/usbnet.c --- linux-source-2.6.24/drivers/net/usb/usbnet.c 2008-01-24 11:52:31.000000000 +0100 +++ linux-source-2.6.24.new/drivers/net/usb/usbnet.c 2008-02-05 23:02:51.000000000 +0100 @@ -90,8 +90,7 @@ /*-------------------------------------------------------------------------*/ -/* handles CDC Ethernet and many other network "bulk data" interfaces */ -int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) +static struct usb_host_interface *usbnet_get_in_out(struct usbnet *dev, struct usb_interface *intf) { int tmp; struct usb_host_interface *alt = NULL; @@ -137,7 +136,28 @@ if (in && out) break; } + if (!alt || !in || !out) + return NULL; + + dev->in = usb_rcvbulkpipe (dev->udev, + in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + dev->out = usb_sndbulkpipe (dev->udev, + out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + dev->status = status; + + return alt; +} + +/* handles CDC Ethernet and many other network "bulk data" interfaces */ +int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) +{ + int tmp; + struct usb_host_interface *alt; + + alt = usbnet_get_in_out(dev, intf); + + if (!alt) return -EINVAL; if (alt->desc.bAlternateSetting != 0 @@ -148,11 +168,6 @@ return tmp; } - dev->in = usb_rcvbulkpipe (dev->udev, - in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - dev->out = usb_sndbulkpipe (dev->udev, - out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - dev->status = status; return 0; } EXPORT_SYMBOL_GPL(usbnet_get_endpoints); @@ -1191,6 +1206,15 @@ net->tx_timeout = usbnet_tx_timeout; net->ethtool_ops = &usbnet_ethtool_ops; + if (info->out && info->in) { + dev->in = usb_rcvbulkpipe (dev->udev, info->in); + dev->out = usb_sndbulkpipe (dev->udev, info->out); + } else { + interface = usbnet_get_in_out(dev, udev); + } + + dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); + // allow device-specific bind/init procedures // NOTE net->name still not usable ... if (info->bind) { @@ -1211,8 +1235,6 @@ } else if (!info->in || !info->out) status = usbnet_get_endpoints (dev, udev); else { - dev->in = usb_rcvbulkpipe (xdev, info->in); - dev->out = usb_sndbulkpipe (xdev, info->out); if (!(info->flags & FLAG_NO_SETINT)) status = usb_set_interface (xdev, interface->desc.bInterfaceNumber, @@ -1228,7 +1250,6 @@ if (!dev->rx_urb_size) dev->rx_urb_size = dev->hard_mtu; - dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); SET_NETDEV_DEV(net, &udev->dev); status = register_netdev (net); - To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html