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

Bug#520468: Incorporate fixes for WUSB54GS support from 2.6.33



On Sat, 2010-07-03 at 14:04 +0100, Ben Hutchings wrote:
> On Thu, 2010-07-01 at 15:07 +0100, Luís Picciochi Oliveira wrote:
> > Hi
> > This patch seems to have fixed it. Here are the results of my testing:
[...]
> Right.  So I'll need to do something a bit smarter to cover all devices.

Can you test the attached patch against the Debian package of 2.6.32?

Ben.

-- 
Ben Hutchings
Once a job is fouled up, anything done to improve it makes it worse.
From d67957b9696ed37425244ce25b2b9ed61df1de87 Mon Sep 17 00:00:00 2001
From: Ben Hutchings <ben@decadent.org.uk>
Date: Sat, 17 Jul 2010 15:49:58 +0100
Subject: [PATCH] rndis_host: Poll status and control channels concurrently

---
 drivers/net/usb/rndis_host.c |   42 +++++++++++++++++++++++++++++-------------
 1 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 52faca1..e0f1399 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -90,6 +90,11 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
 	}
 }
 
+static void rndis_notif_complete(struct urb *urb)
+{
+	/* don't care */
+}
+
 /*
  * RPC done RNDIS-style.  Caller guarantees:
  * - message is properly byteswapped
@@ -104,9 +109,9 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
 {
 	struct cdc_state	*info = (void *) &dev->data;
 	struct usb_cdc_notification notification;
+	struct urb		*notif_urb;
 	int			master_ifnum;
 	int			retval;
-	int			partial;
 	unsigned		count;
 	__le32			rsp;
 	u32			xid = 0, msg_len, request_id;
@@ -135,14 +140,19 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
 		return retval;
 
 	/* Some devices don't respond on the control channel until
-	 * polled on the status channel, so do that first. */
-	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;
+	 * polled on the status channel, so poll that as well. */
+	notif_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!notif_urb)
+		return -ENOMEM;
+	usb_fill_int_urb(notif_urb, dev->udev,
+			 usb_rcvintpipe(dev->udev,
+					dev->status->desc.bEndpointAddress),
+			 &notification, sizeof(notification),
+			 rndis_notif_complete, NULL,
+			 dev->status->desc.bInterval);
+	retval = usb_submit_urb(notif_urb, GFP_KERNEL);
+	if (retval)
+		goto out_free;
 
 	/* Poll the control channel; the request probably completed immediately */
 	rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
@@ -161,14 +171,15 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
 			if (likely(buf->msg_type == rsp)) {
 				if (likely(request_id == xid)) {
 					if (unlikely(rsp == RNDIS_MSG_RESET_C))
-						return 0;
+						goto out_kill;
 					if (likely(RNDIS_STATUS_SUCCESS
 							== buf->status))
-						return 0;
+						goto out_kill;
 					dev_dbg(&info->control->dev,
 						"rndis reply status %08x\n",
 						le32_to_cpu(buf->status));
-					return -EL3RST;
+					retval = -EL3RST;
+					goto out_kill;
 				}
 				dev_dbg(&info->control->dev,
 					"rndis reply id %d expected %d\n",
@@ -211,7 +222,12 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
 		msleep(20);
 	}
 	dev_dbg(&info->control->dev, "rndis response timeout\n");
-	return -ETIMEDOUT;
+	retval = -ETIMEDOUT;
+out_kill:
+	usb_kill_urb(notif_urb);
+out_free:
+	usb_free_urb(notif_urb);
+	return retval;
 }
 EXPORT_SYMBOL_GPL(rndis_command);
 
-- 
1.7.1

Attachment: signature.asc
Description: This is a digitally signed message part


Reply to: