From patchwork Tue May 24 15:26:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Orishko X-Patchwork-Id: 97173 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 CEBF6B6F9E for ; Wed, 25 May 2011 01:26:36 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755719Ab1EXP0b (ORCPT ); Tue, 24 May 2011 11:26:31 -0400 Received: from mail-ey0-f174.google.com ([209.85.215.174]:54517 "EHLO mail-ey0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752082Ab1EXP0a (ORCPT ); Tue, 24 May 2011 11:26:30 -0400 Received: by eyx24 with SMTP id 24so2225662eyx.19 for ; Tue, 24 May 2011 08:26:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer; bh=70rQgFLZEgykjOSYFbtsIqWwlN/IFp2VCcM+WYr6Bu0=; b=my2dqxsrLCWg69DfpbhmdAHiJsjaMmvaTC11SBTjyeUm1MtL/WvoHoZ6aY6d9AsOP+ 0NQ1EO2YZmaHETj2l9hDiKlVwkobyc1T7tnMCqURhcMMwhpXfDUCmILt2p/qSs5qL9cW PlMZ4m/pv46jwp0qS5ixiMWq/OhObznglZNAs= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=al144LbKecjkjjM3QXR2pLhHi5y3FtgNRjJsKb2XKSug8A2R9BkkHHirwcvy6TESQe uBME855194rlJ55k2yx9kCwIHuEFZXBc5GpDvTzV6QHN3AxK7sS4RN7xnMLyFfwWe4i8 RNM99gUzNCxC48rZZ4+p9Y5VvFXYsoCt+ZWE4= Received: by 10.213.21.8 with SMTP id h8mr1547182ebb.111.1306250788779; Tue, 24 May 2011 08:26:28 -0700 (PDT) Received: from localhost.localdomain ([212.4.57.94]) by mx.google.com with ESMTPS id y18sm5424657eeh.10.2011.05.24.08.26.24 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 24 May 2011 08:26:25 -0700 (PDT) From: Alexey Orishko To: netdev@vger.kernel.org, davem@davemloft.net, oliver@neukum.org Cc: linux-usb@vger.kernel.org, gregkh@suse.de, Alexey Orishko Subject: [PATCH v4] CDC NCM: release interfaces fix in unbind() Date: Tue, 24 May 2011 17:26:13 +0200 Message-Id: <1306250773-9177-1-git-send-email-alexey.orishko@stericsson.com> X-Mailer: git-send-email 1.7.4.3 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Changes: - claim slave/data interface during bind() and release interfaces in unbind() unconditionally - in case of error during bind(), release claimed data interface in the same function - remove obsolited "*_claimed" entries from driver context Signed-off-by: Alexey Orishko --- drivers/net/usb/cdc_ncm.c | 73 +++++++++++++++----------------------------- 1 files changed, 25 insertions(+), 48 deletions(-) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4ab557d..cdd3ae4 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -54,7 +54,7 @@ #include #include -#define DRIVER_VERSION "06-May-2011" +#define DRIVER_VERSION "24-May-2011" /* CDC NCM subclass 3.2.1 */ #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 @@ -134,8 +134,6 @@ struct cdc_ncm_ctx { u16 tx_ndp_modulus; u16 tx_seq; u16 connected; - u8 data_claimed; - u8 control_claimed; }; static void cdc_ncm_tx_timeout(unsigned long arg); @@ -460,17 +458,6 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx) del_timer_sync(&ctx->tx_timer); - if (ctx->data_claimed) { - usb_set_intfdata(ctx->data, NULL); - usb_driver_release_interface(driver_of(ctx->intf), ctx->data); - } - - if (ctx->control_claimed) { - usb_set_intfdata(ctx->control, NULL); - usb_driver_release_interface(driver_of(ctx->intf), - ctx->control); - } - if (ctx->tx_rem_skb != NULL) { dev_kfree_skb_any(ctx->tx_rem_skb); ctx->tx_rem_skb = NULL; @@ -495,7 +482,7 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); if (ctx == NULL) - goto error; + return -ENODEV; memset(ctx, 0, sizeof(*ctx)); @@ -568,46 +555,36 @@ advance: /* check if we got everything */ if ((ctx->control == NULL) || (ctx->data == NULL) || - (ctx->ether_desc == NULL)) + (ctx->ether_desc == NULL) || (ctx->control != intf)) goto error; /* claim interfaces, if any */ - if (ctx->data != intf) { - temp = usb_driver_claim_interface(driver, ctx->data, dev); - if (temp) - goto error; - ctx->data_claimed = 1; - } - - if (ctx->control != intf) { - temp = usb_driver_claim_interface(driver, ctx->control, dev); - if (temp) - goto error; - ctx->control_claimed = 1; - } + temp = usb_driver_claim_interface(driver, ctx->data, dev); + if (temp) + goto error; iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; /* reset data interface */ temp = usb_set_interface(dev->udev, iface_no, 0); if (temp) - goto error; + goto error2; /* initialize data interface */ if (cdc_ncm_setup(ctx)) - goto error; + goto error2; /* configure data interface */ temp = usb_set_interface(dev->udev, iface_no, 1); if (temp) - goto error; + goto error2; cdc_ncm_find_endpoints(ctx, ctx->data); cdc_ncm_find_endpoints(ctx, ctx->control); if ((ctx->in_ep == NULL) || (ctx->out_ep == NULL) || (ctx->status_ep == NULL)) - goto error; + goto error2; dev->net->ethtool_ops = &cdc_ncm_ethtool_ops; @@ -617,7 +594,7 @@ advance: temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress); if (temp) - goto error; + goto error2; dev_info(&dev->udev->dev, "MAC-Address: " "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", @@ -642,38 +619,38 @@ advance: ctx->tx_speed = ctx->rx_speed = 0; return 0; +error2: + usb_set_intfdata(ctx->control, NULL); + usb_set_intfdata(ctx->data, NULL); + usb_driver_release_interface(driver, ctx->data); error: cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]); dev->data[0] = 0; - dev_info(&dev->udev->dev, "Descriptor failure\n"); + dev_info(&dev->udev->dev, "bind() failure\n"); return -ENODEV; } static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) { struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; - struct usb_driver *driver; + struct usb_driver *driver = driver_of(intf); if (ctx == NULL) return; /* no setup */ - driver = driver_of(intf); - - usb_set_intfdata(ctx->data, NULL); - usb_set_intfdata(ctx->control, NULL); - usb_set_intfdata(ctx->intf, NULL); - - /* release interfaces, if any */ - if (ctx->data_claimed) { + /* disconnect master --> disconnect slave */ + if (intf == ctx->control && ctx->data) { + usb_set_intfdata(ctx->data, NULL); usb_driver_release_interface(driver, ctx->data); - ctx->data_claimed = 0; - } + ctx->data = NULL; - if (ctx->control_claimed) { + } else if (intf == ctx->data && ctx->control) { + usb_set_intfdata(ctx->control, NULL); usb_driver_release_interface(driver, ctx->control); - ctx->control_claimed = 0; + ctx->control = NULL; } + usb_set_intfdata(ctx->intf, NULL); cdc_ncm_free(ctx); }