Commit c17b274d authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller

rndis_host: Poll status channel before control channel

Some RNDIS devices don't respond on the control channel until polled
on the status channel.  In particular, this was reported to be the
case for the 2Wire HomePortal 1000SW.

This is roughly based on a patch by John Carr <john.carr@unrouted.co.uk>
which is reported to be needed for use with some Windows Mobile devices
and which is currently applied by Mandriva.
Reported-by: default avatarMark Glassberg <vzeeaxwl@myfairpoint.net>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
Tested-by: default avatarMark Glassberg <vzeeaxwl@myfairpoint.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 83827f6a
...@@ -104,8 +104,10 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg, ...@@ -104,8 +104,10 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
{ {
struct cdc_state *info = (void *) &dev->data; struct cdc_state *info = (void *) &dev->data;
struct usb_cdc_notification notification;
int master_ifnum; int master_ifnum;
int retval; int retval;
int partial;
unsigned count; unsigned count;
__le32 rsp; __le32 rsp;
u32 xid = 0, msg_len, request_id; u32 xid = 0, msg_len, request_id;
...@@ -133,13 +135,17 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) ...@@ -133,13 +135,17 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
if (unlikely(retval < 0 || xid == 0)) if (unlikely(retval < 0 || xid == 0))
return retval; return retval;
// FIXME Seems like some devices discard responses when /* Some devices don't respond on the control channel until
// we time out and cancel our "get response" requests... * polled on the status channel, so do that first. */
// so, this is fragile. Probably need to poll for status. retval = usb_interrupt_msg(
dev->udev,
usb_rcvintpipe(dev->udev, dev->status->desc.bEndpointAddress),
&notification, sizeof(notification), &partial,
RNDIS_CONTROL_TIMEOUT_MS);
if (unlikely(retval < 0))
return retval;
/* ignore status endpoint, just poll the control channel; /* Poll the control channel; the request probably completed immediately */
* the request probably completed immediately
*/
rsp = buf->msg_type | RNDIS_MSG_COMPLETION; rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
for (count = 0; count < 10; count++) { for (count = 0; count < 10; count++) {
memset(buf, 0, CONTROL_BUFFER_SIZE); memset(buf, 0, CONTROL_BUFFER_SIZE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment