aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/rndis_host.c
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2010-05-16 02:03:29 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-16 02:03:29 -0400
commitc17b274dc2aa538b68c1f02b01a3c4e124b435ba (patch)
treeadba02f37f287b01daedbe8d5399fc2cc065fde0 /drivers/net/usb/rndis_host.c
parent83827f6a891e20de7468b1181f2ae8a3cc72587b (diff)
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: Mark Glassberg <vzeeaxwl@myfairpoint.net> Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Tested-by: Mark Glassberg <vzeeaxwl@myfairpoint.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb/rndis_host.c')
-rw-r--r--drivers/net/usb/rndis_host.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index dd8a4adf48ca..28d3ee175e7b 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -104,8 +104,10 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
104int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) 104int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
105{ 105{
106 struct cdc_state *info = (void *) &dev->data; 106 struct cdc_state *info = (void *) &dev->data;
107 struct usb_cdc_notification notification;
107 int master_ifnum; 108 int master_ifnum;
108 int retval; 109 int retval;
110 int partial;
109 unsigned count; 111 unsigned count;
110 __le32 rsp; 112 __le32 rsp;
111 u32 xid = 0, msg_len, request_id; 113 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 if (unlikely(retval < 0 || xid == 0)) 135 if (unlikely(retval < 0 || xid == 0))
134 return retval; 136 return retval;
135 137
136 // FIXME Seems like some devices discard responses when 138 /* Some devices don't respond on the control channel until
137 // we time out and cancel our "get response" requests... 139 * polled on the status channel, so do that first. */
138 // so, this is fragile. Probably need to poll for status. 140 retval = usb_interrupt_msg(
141 dev->udev,
142 usb_rcvintpipe(dev->udev, dev->status->desc.bEndpointAddress),
143 &notification, sizeof(notification), &partial,
144 RNDIS_CONTROL_TIMEOUT_MS);
145 if (unlikely(retval < 0))
146 return retval;
139 147
140 /* ignore status endpoint, just poll the control channel; 148 /* Poll the control channel; the request probably completed immediately */
141 * the request probably completed immediately
142 */
143 rsp = buf->msg_type | RNDIS_MSG_COMPLETION; 149 rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
144 for (count = 0; count < 10; count++) { 150 for (count = 0; count < 10; count++) {
145 memset(buf, 0, CONTROL_BUFFER_SIZE); 151 memset(buf, 0, CONTROL_BUFFER_SIZE);