From patchwork Tue Dec 6 17:25:05 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: sjur.brandeland@stericsson.com X-Patchwork-Id: 129751 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 6CA581007D5 for ; Wed, 7 Dec 2011 04:25:27 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751687Ab1LFRZW (ORCPT ); Tue, 6 Dec 2011 12:25:22 -0500 Received: from mail-lpp01m010-f46.google.com ([209.85.215.46]:45702 "EHLO mail-lpp01m010-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751340Ab1LFRZV (ORCPT ); Tue, 6 Dec 2011 12:25:21 -0500 Received: by lagp5 with SMTP id p5so1725399lag.19 for ; Tue, 06 Dec 2011 09:25:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:mime-version :content-type:content-transfer-encoding; bh=TxrvDPx629RsN9yo8dIF8Okske92tJQ6oaG+ctBv5wE=; b=oYosHH7PDIWQJ7sc7uBYeETflEnCQMl6mE9e1CAX1mvqPQoyZUP+fA4fWW36KfR3bo KZz31kWmxWgrszcFskEPelCAQjz2D1D7MQ0rLOXXAxVfHGk/uUjS5sEypuZz0+gKLha0 5DjVhhfaNcN5WvaG56bO+QyyLEpx+HDIltddI= Received: by 10.152.135.179 with SMTP id pt19mr9480152lab.47.1323192319248; Tue, 06 Dec 2011 09:25:19 -0800 (PST) Received: from localhost.localdomain (cm-188.126.205.77.customer.telag.net. [188.126.205.77]) by mx.google.com with ESMTPS id iy5sm21563626lab.16.2011.12.06.09.25.15 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 06 Dec 2011 09:25:18 -0800 (PST) From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= To: netdev@vger.kernel.org, David Miller Cc: Erwan Bracq , =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Subject: [PATCH net-next] caif-spi: Bugfix for dump upon device removal Date: Tue, 6 Dec 2011 18:25:05 +0100 Message-Id: <1323192305-10843-1-git-send-email-sjur.brandeland@stericsson.com> X-Mailer: git-send-email 1.7.0.4 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Erwan Bracq Fix dump upon device removal, by moving deinitialization from platform-device-remove to network-interface-uninit. Signed-off-by: Sjur Brændeland --- drivers/net/caif/caif_spi.c | 176 ++++++++++++++++++++++--------------------- include/net/caif/caif_spi.h | 4 +- 2 files changed, 92 insertions(+), 88 deletions(-) diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 05e791f..761057b 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -226,7 +226,7 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, "Tx data (Len: %d):\n", cfspi->tx_cpck_len); len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len), - cfspi->xfer.va_tx, + cfspi->xfer.va_tx[0], (cfspi->tx_cpck_len + SPI_CMD_SZ), 100); len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), @@ -599,48 +599,11 @@ static int cfspi_close(struct net_device *dev) netif_stop_queue(dev); return 0; } -static const struct net_device_ops cfspi_ops = { - .ndo_open = cfspi_open, - .ndo_stop = cfspi_close, - .ndo_start_xmit = cfspi_xmit -}; -static void cfspi_setup(struct net_device *dev) +static int cfspi_init(struct net_device *dev) { + int res = 0; struct cfspi *cfspi = netdev_priv(dev); - dev->features = 0; - dev->netdev_ops = &cfspi_ops; - dev->type = ARPHRD_CAIF; - dev->flags = IFF_NOARP | IFF_POINTOPOINT; - dev->tx_queue_len = 0; - dev->mtu = SPI_MAX_PAYLOAD_SIZE; - dev->destructor = free_netdev; - skb_queue_head_init(&cfspi->qhead); - skb_queue_head_init(&cfspi->chead); - cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW; - cfspi->cfdev.use_frag = false; - cfspi->cfdev.use_stx = false; - cfspi->cfdev.use_fcs = false; - cfspi->ndev = dev; -} - -int cfspi_spi_probe(struct platform_device *pdev) -{ - struct cfspi *cfspi = NULL; - struct net_device *ndev; - struct cfspi_dev *dev; - int res; - dev = (struct cfspi_dev *)pdev->dev.platform_data; - - ndev = alloc_netdev(sizeof(struct cfspi), - "cfspi%d", cfspi_setup); - if (!ndev) - return -ENOMEM; - - cfspi = netdev_priv(ndev); - netif_stop_queue(ndev); - cfspi->ndev = ndev; - cfspi->pdev = pdev; /* Set flow info. */ cfspi->flow_off_sent = 0; @@ -656,16 +619,11 @@ int cfspi_spi_probe(struct platform_device *pdev) cfspi->slave_talked = false; } - /* Assign the SPI device. */ - cfspi->dev = dev; - /* Assign the device ifc to this SPI interface. */ - dev->ifc = &cfspi->ifc; - /* Allocate DMA buffers. */ - cfspi->xfer.va_tx = dma_alloc(&cfspi->xfer.pa_tx); - if (!cfspi->xfer.va_tx) { + cfspi->xfer.va_tx[0] = dma_alloc(&cfspi->xfer.pa_tx[0]); + if (!cfspi->xfer.va_tx[0]) { res = -ENODEV; - goto err_dma_alloc_tx; + goto err_dma_alloc_tx_0; } cfspi->xfer.va_rx = dma_alloc(&cfspi->xfer.pa_rx); @@ -714,6 +672,87 @@ int cfspi_spi_probe(struct platform_device *pdev) /* Schedule the work queue. */ queue_work(cfspi->wq, &cfspi->work); + return 0; + + err_create_wq: + dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx); + err_dma_alloc_rx: + dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]); + err_dma_alloc_tx_0: + return res; +} + +static void cfspi_uninit(struct net_device *dev) +{ + struct cfspi *cfspi = netdev_priv(dev); + + /* Remove from list. */ + spin_lock(&cfspi_list_lock); + list_del(&cfspi->list); + spin_unlock(&cfspi_list_lock); + + cfspi->ndev = NULL; + /* Free DMA buffers. */ + dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx); + dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]); + set_bit(SPI_TERMINATE, &cfspi->state); + wake_up_interruptible(&cfspi->wait); + destroy_workqueue(cfspi->wq); + /* Destroy debugfs directory and files. */ + dev_debugfs_rem(cfspi); + return; +} + +static const struct net_device_ops cfspi_ops = { + .ndo_open = cfspi_open, + .ndo_stop = cfspi_close, + .ndo_init = cfspi_init, + .ndo_uninit = cfspi_uninit, + .ndo_start_xmit = cfspi_xmit +}; + +static void cfspi_setup(struct net_device *dev) +{ + struct cfspi *cfspi = netdev_priv(dev); + dev->features = 0; + dev->netdev_ops = &cfspi_ops; + dev->type = ARPHRD_CAIF; + dev->flags = IFF_NOARP | IFF_POINTOPOINT; + dev->tx_queue_len = 0; + dev->mtu = SPI_MAX_PAYLOAD_SIZE; + dev->destructor = free_netdev; + skb_queue_head_init(&cfspi->qhead); + skb_queue_head_init(&cfspi->chead); + cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW; + cfspi->cfdev.use_frag = false; + cfspi->cfdev.use_stx = false; + cfspi->cfdev.use_fcs = false; + cfspi->ndev = dev; +} + +int cfspi_spi_probe(struct platform_device *pdev) +{ + struct cfspi *cfspi = NULL; + struct net_device *ndev; + struct cfspi_dev *dev; + int res; + dev = (struct cfspi_dev *)pdev->dev.platform_data; + + ndev = alloc_netdev(sizeof(struct cfspi), + "cfspi%d", cfspi_setup); + if (!dev) + return -ENODEV; + + cfspi = netdev_priv(ndev); + netif_stop_queue(ndev); + cfspi->ndev = ndev; + cfspi->pdev = pdev; + + /* Assign the SPI device. */ + cfspi->dev = dev; + /* Assign the device ifc to this SPI interface. */ + dev->ifc = &cfspi->ifc; + /* Register network device. */ res = register_netdev(ndev); if (res) { @@ -723,15 +762,6 @@ int cfspi_spi_probe(struct platform_device *pdev) return res; err_net_reg: - dev_debugfs_rem(cfspi); - set_bit(SPI_TERMINATE, &cfspi->state); - wake_up_interruptible(&cfspi->wait); - destroy_workqueue(cfspi->wq); - err_create_wq: - dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx); - err_dma_alloc_rx: - dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx); - err_dma_alloc_tx: free_netdev(ndev); return res; @@ -739,34 +769,8 @@ int cfspi_spi_probe(struct platform_device *pdev) int cfspi_spi_remove(struct platform_device *pdev) { - struct list_head *list_node; - struct list_head *n; - struct cfspi *cfspi = NULL; - struct cfspi_dev *dev; - - dev = (struct cfspi_dev *)pdev->dev.platform_data; - spin_lock(&cfspi_list_lock); - list_for_each_safe(list_node, n, &cfspi_list) { - cfspi = list_entry(list_node, struct cfspi, list); - /* Find the corresponding device. */ - if (cfspi->dev == dev) { - /* Remove from list. */ - list_del(list_node); - /* Free DMA buffers. */ - dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx); - dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx); - set_bit(SPI_TERMINATE, &cfspi->state); - wake_up_interruptible(&cfspi->wait); - destroy_workqueue(cfspi->wq); - /* Destroy debugfs directory and files. */ - dev_debugfs_rem(cfspi); - unregister_netdev(cfspi->ndev); - spin_unlock(&cfspi_list_lock); - return 0; - } - } - spin_unlock(&cfspi_list_lock); - return -ENODEV; + /* Everything is done in cfspi_uninit(). */ + return 0; } static void __exit cfspi_exit_module(void) @@ -777,7 +781,7 @@ static void __exit cfspi_exit_module(void) list_for_each_safe(list_node, n, &cfspi_list) { cfspi = list_entry(list_node, struct cfspi, list); - platform_device_unregister(cfspi->pdev); + unregister_netdev(cfspi->ndev); } /* Destroy sysfs files. */ diff --git a/include/net/caif/caif_spi.h b/include/net/caif/caif_spi.h index 87c3d11..aa6a485 100644 --- a/include/net/caif/caif_spi.h +++ b/include/net/caif/caif_spi.h @@ -55,8 +55,8 @@ struct cfspi_xfer { u16 tx_dma_len; u16 rx_dma_len; - void *va_tx; - dma_addr_t pa_tx; + void *va_tx[2]; + dma_addr_t pa_tx[2]; void *va_rx; dma_addr_t pa_rx; };