All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ivo van Doorn <ivdoorn@gmail.com>
To: linville@tuxdriver.com
Cc: linux-wireless@vger.kernel.org, rt2400-devel@lists.sourceforge.net
Subject: [PATCH 01/14] rt2x00: Fix invalid DMA free
Date: Sun, 10 Feb 2008 22:46:52 +0100	[thread overview]
Message-ID: <200802102246.52441.IvDoorn@gmail.com> (raw)
In-Reply-To: <200802102246.04515.IvDoorn@gmail.com>

Be more strict when using the queue_entry_priv_pci_rx
and queue_entry_priv_pci_tx structures. Only use a
particular type that matches the queue type.

When freeing the DMA the priv_tx->data and priv_tx->dma
was used. This is incorrect since the start of the DMA
was in fact the priv_tx->desc pointer. Instead of
recalculating the dma_addr_t for the DMA start this
patch will swap the data and descriptor part of the
allocated memory.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00pci.c |   85 ++++++++++++++++++++++---------
 1 files changed, 60 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 275c8a1..238f1c1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -186,38 +186,44 @@ EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
 /*
  * Device initialization handlers.
  */
-#define dma_size(__queue)				\
-({							\
-	(__queue)->limit *				\
-	    ((__queue)->desc_size + (__queue)->data_size);\
+#define desc_size(__queue)			\
+({						\
+	 ((__queue)->limit * (__queue)->desc_size);\
 })
 
-#define priv_offset(__queue, __base, __i)		\
-({							\
-	(__base) + ((__i) * (__queue)->desc_size);	\
+#define data_size(__queue)			\
+({						\
+	 ((__queue)->limit * (__queue)->data_size);\
 })
 
-#define data_addr_offset(__queue, __base, __i)		\
-({							\
-	(__base) +					\
-	    ((__queue)->limit * (__queue)->desc_size) +	\
-	    ((__i) * (__queue)->data_size);		\
+#define dma_size(__queue)			\
+({						\
+	data_size(__queue) + desc_size(__queue);\
 })
 
-#define data_dma_offset(__queue, __base, __i)		\
-({							\
-	(__base) +					\
-	    ((__queue)->limit * (__queue)->desc_size) +	\
-	    ((__i) * (__queue)->data_size);		\
+#define desc_offset(__queue, __base, __i)	\
+({						\
+	(__base) + data_size(__queue) + 	\
+	    ((__i) * (__queue)->desc_size);	\
+})
+
+#define data_offset(__queue, __base, __i)	\
+({						\
+	(__base) +				\
+	    ((__i) * (__queue)->data_size);	\
 })
 
 static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
 				     struct data_queue *queue)
 {
 	struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
+	struct queue_entry_priv_pci_rx *priv_rx;
 	struct queue_entry_priv_pci_tx *priv_tx;
+	void *desc;
 	void *data_addr;
+	void *data;
 	dma_addr_t data_dma;
+	dma_addr_t dma;
 	unsigned int i;
 
 	/*
@@ -227,14 +233,27 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
 	if (!data_addr)
 		return -ENOMEM;
 
+	memset(data_addr, 0, dma_size(queue));
+
 	/*
 	 * Initialize all queue entries to contain valid addresses.
 	 */
 	for (i = 0; i < queue->limit; i++) {
-		priv_tx = queue->entries[i].priv_data;
-		priv_tx->desc = priv_offset(queue, data_addr, i);
-		priv_tx->data = data_addr_offset(queue, data_addr, i);
-		priv_tx->dma = data_dma_offset(queue, data_dma, i);
+		desc = desc_offset(queue, data_addr, i);
+		data = data_offset(queue, data_addr, i);
+		dma = data_offset(queue, data_dma, i);
+
+		if (queue->qid == QID_RX) {
+			priv_rx = queue->entries[i].priv_data;
+			priv_rx->desc = desc;
+			priv_rx->data = data;
+			priv_rx->dma = dma;
+		} else {
+			priv_tx = queue->entries[i].priv_data;
+			priv_tx->desc = desc;
+			priv_tx->data = data;
+			priv_tx->dma = dma;
+		}
 	}
 
 	return 0;
@@ -244,12 +263,28 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
 				     struct data_queue *queue)
 {
 	struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
-	struct queue_entry_priv_pci_tx *priv_tx = queue->entries[0].priv_data;
+	struct queue_entry_priv_pci_rx *priv_rx;
+	struct queue_entry_priv_pci_tx *priv_tx;
+	void *data_addr;
+	dma_addr_t data_dma;
+
+	if (queue->qid == QID_RX) {
+		priv_rx = queue->entries[0].priv_data;
+		data_addr = priv_rx->data;
+		data_dma = priv_rx->dma;
+
+		priv_rx->data = NULL;
+	} else {
+		priv_tx = queue->entries[0].priv_data;
+		data_addr = priv_tx->data;
+		data_dma = priv_tx->dma;
+
+		priv_tx->data = NULL;
+	}
 
-	if (priv_tx->data)
+	if (data_addr)
 		pci_free_consistent(pci_dev, dma_size(queue),
-				    priv_tx->data, priv_tx->dma);
-	priv_tx->data = NULL;
+				    data_addr, data_dma);
 }
 
 int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
-- 
1.5.4


  reply	other threads:[~2008-02-10 21:48 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-10 21:46 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2008-02-10 21:46 ` Ivo van Doorn [this message]
2008-02-10 21:47 ` [PATCH 02/14] rt2x00: Make rt2x00 less verbose Ivo van Doorn
2008-02-10 21:47 ` [PATCH 03/14] rt2x00: Remove MGMT ring initialization Ivo van Doorn
2008-02-10 21:48 ` [PATCH 04/14] rt2x00: correct address calc for queue private data Ivo van Doorn
2008-02-10 21:48 ` [PATCH 05/14] rt2x00: Select CONFIG_NEW_LEDS Ivo van Doorn
2008-02-10 21:49 ` [PATCH 06/14] rt2x00: make csr_cache and csr_addr an union Ivo van Doorn
2008-02-10 21:50 ` [PATCH 07/14] rt2x00: Fix scheduling while atomic errors in usb drivers Ivo van Doorn
2008-02-10 21:50 ` [PATCH 08/14] rt2x00: Add queue statistics to debugfs Ivo van Doorn
2008-02-10 21:50 ` [PATCH 09/14] rt2x00: Fix typo in debug statement Ivo van Doorn
2008-02-10 21:51 ` [PATCH 10/14] rt2x00: Fix skbdesc->data_len initialization Ivo van Doorn
2008-02-10 21:51 ` [PATCH 11/14] rt2x00: Fix queue->qid initialization Ivo van Doorn
2008-02-10 21:52 ` [PATCH 12/14] rt2x00: Cleanup Makefile Ivo van Doorn
2008-02-10 21:52 ` [PATCH 13/14] rt2x00: Kill guardian urb during disable_radio Ivo van Doorn
2008-02-10 21:52 ` [PATCH 14/14] rt2x00: Release rt2x00 2.1.1 Ivo van Doorn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200802102246.52441.IvDoorn@gmail.com \
    --to=ivdoorn@gmail.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=rt2400-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.