From patchwork Wed Jun 13 12:50:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: huajun li X-Patchwork-Id: 164660 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 72D78B6FFD for ; Wed, 13 Jun 2012 22:50:49 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753005Ab2FMMuf (ORCPT ); Wed, 13 Jun 2012 08:50:35 -0400 Received: from mail-wi0-f172.google.com ([209.85.212.172]:60697 "EHLO mail-wi0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752718Ab2FMMud (ORCPT ); Wed, 13 Jun 2012 08:50:33 -0400 Received: by wibhj8 with SMTP id hj8so5242243wib.1 for ; Wed, 13 Jun 2012 05:50:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc:content-type; bh=5FlSPpDDE+eZbdnRtL0M2Se8cuCng158f+ocKOW+XxI=; b=ItJVsYu1fT8ycAqA0zP8kjTVQgEESWJLoIS8Ik+xKV0HTLCN4fRg8LNkLbYVMr/M5/ FqwZjryJx79APoyzWpK1n0ol22gCyhyj+yo5Idvl7+LiYyy8RvlaeHu/CPv+mj/3JZ1y w67d6GS6MaOMKNwnLsX00UB/NxZOuZk/1KNvC3XBWAjkUxfbh7MIniFlbzKZ/uh3uXYe PskY5xXBcrdFFVqdkuPwebJONumDx8/azE+/ihREQ2C4vmTvbMeVOVQVXzhczyALFdP6 dGSXuSwEohQ/msbm/UD/n8xd20LeaDp+KpV4W5IBxIqa6hGLCiyGIjAS8FfIZqd0YoHu UaCA== MIME-Version: 1.0 Received: by 10.216.215.154 with SMTP id e26mr11558311wep.224.1339591831245; Wed, 13 Jun 2012 05:50:31 -0700 (PDT) Received: by 10.223.74.74 with HTTP; Wed, 13 Jun 2012 05:50:31 -0700 (PDT) Date: Wed, 13 Jun 2012 20:50:31 +0800 Message-ID: Subject: [PATCH] usbnet: Activate halt interrupt endpoint before re-submit URB From: Huajun Li To: David Miller Cc: Ming Lei , Alan Stern , lud , netdev , Huajun Li Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org intr_complete() submits URB even the interrupt endpoint stalls. This patch will try to activate the endpoint once the exception occurs, and then re-submit the URB if the endpoint works again. Signed-off-by: Huajun Li --- drivers/net/usb/usbnet.c | 31 +++++++++++++++++++++++++++++++ include/linux/usb/usbnet.h | 13 +++++++------ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ac2e493..314aaea 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -198,6 +198,10 @@ static void intr_complete (struct urb *urb) "intr shutdown, code %d\n", status); return; + case -EPIPE: + usbnet_defer_kevent(dev, EVENT_STS_HALT); + return; + /* NOTE: not throttling like RX/TX, since this endpoint * already polls infrequently */ @@ -964,6 +968,33 @@ fail_halt: } } + if (test_bit(EVENT_STS_HALT, &dev->flags)) { + unsigned pipe; + struct usb_endpoint_descriptor *desc; + + desc = &dev->status->desc; + pipe = usb_rcvintpipe(dev->udev, + desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + status = usb_autopm_get_interface(dev->intf); + if (status < 0) + goto fail_sts; + status = usb_clear_halt(dev->udev, pipe); + if (status < 0) { + usb_autopm_put_interface(dev->intf); +fail_sts: + netdev_err(dev->net, + "can't clear intr halt, status %d\n", status); + } else { + clear_bit(EVENT_STS_HALT, &dev->flags); + status = usb_submit_urb(dev->interrupt, GFP_KERNEL); + if (status != 0) + netif_err(dev, timer, dev->net, + "intr resubmit --> %d\n", status); + + usb_autopm_put_interface(dev->intf); + } + } + /* tasklet could resubmit itself forever if memory is tight */ if (test_bit (EVENT_RX_MEMORY, &dev->flags)) { struct urb *urb = NULL; diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index f87cf62..81b4473 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -62,12 +62,13 @@ struct usbnet { unsigned long flags; # define EVENT_TX_HALT 0 # define EVENT_RX_HALT 1 -# define EVENT_RX_MEMORY 2 -# define EVENT_STS_SPLIT 3 -# define EVENT_LINK_RESET 4 -# define EVENT_RX_PAUSED 5 -# define EVENT_DEV_ASLEEP 6 -# define EVENT_DEV_OPEN 7 +# define EVENT_STS_HALT 2 +# define EVENT_RX_MEMORY 3 +# define EVENT_STS_SPLIT 4 +# define EVENT_LINK_RESET 5 +# define EVENT_RX_PAUSED 6 +# define EVENT_DEV_ASLEEP 7 +# define EVENT_DEV_OPEN 8 }; static inline struct usb_driver *driver_of(struct usb_interface *intf)