[patch 24/28] niu: panic on reset

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Greg KH
Date: Monday, October 6, 2008 - 4:17 pm

2.6.25-stable review patch.  If anyone has any objections, please let us
know.

------------------
From: Santwona Behera <santwona.behera@sun.com>

[ Upstream commit cff502a38394fd33693f6233e03fca363dfa956d ]

The reset_task function in the niu driver does not reset the tx and rx
buffers properly. This leads to panic on reset. This patch is a
modified implementation of the previously posted fix.

Signed-off-by: Santwona Behera <santwona.behera@sun.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/net/niu.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -5230,6 +5230,56 @@ static void niu_netif_start(struct niu *
 	niu_enable_interrupts(np, 1);
 }
 
+static void niu_reset_buffers(struct niu *np)
+{
+	int i, j, k, err;
+
+	if (np->rx_rings) {
+		for (i = 0; i < np->num_rx_rings; i++) {
+			struct rx_ring_info *rp = &np->rx_rings[i];
+
+			for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) {
+				struct page *page;
+
+				page = rp->rxhash[j];
+				while (page) {
+					struct page *next =
+						(struct page *) page->mapping;
+					u64 base = page->index;
+					base = base >> RBR_DESCR_ADDR_SHIFT;
+					rp->rbr[k++] = cpu_to_le32(base);
+					page = next;
+				}
+			}
+			for (; k < MAX_RBR_RING_SIZE; k++) {
+				err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k);
+				if (unlikely(err))
+					break;
+			}
+
+			rp->rbr_index = rp->rbr_table_size - 1;
+			rp->rcr_index = 0;
+			rp->rbr_pending = 0;
+			rp->rbr_refill_pending = 0;
+		}
+	}
+	if (np->tx_rings) {
+		for (i = 0; i < np->num_tx_rings; i++) {
+			struct tx_ring_info *rp = &np->tx_rings[i];
+
+			for (j = 0; j < MAX_TX_RING_SIZE; j++) {
+				if (rp->tx_buffs[j].skb)
+					(void) release_tx_packet(np, rp, j);
+			}
+
+			rp->pending = MAX_TX_RING_SIZE;
+			rp->prod = 0;
+			rp->cons = 0;
+			rp->wrap_bit = 0;
+		}
+	}
+}
+
 static void niu_reset_task(struct work_struct *work)
 {
 	struct niu *np = container_of(work, struct niu, reset_task);
@@ -5252,6 +5302,12 @@ static void niu_reset_task(struct work_s
 
 	niu_stop_hw(np);
 
+	spin_unlock_irqrestore(&np->lock, flags);
+
+	niu_reset_buffers(np);
+
+	spin_lock_irqsave(&np->lock, flags);
+
 	err = niu_init_hw(np);
 	if (!err) {
 		np->timer.expires = jiffies + HZ;

-- 
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[patch 00/28] 2.6.25-stable review, Greg KH, (Mon Oct 6, 4:16 pm)
[patch 01/28] USB: fix hcd interrupt disabling, Greg KH, (Mon Oct 6, 4:16 pm)
[patch 02/28] pxa2xx_spi: dma bugfixes, Greg KH, (Mon Oct 6, 4:17 pm)
[patch 03/28] pxa2xx_spi: chipselect bugfixes, Greg KH, (Mon Oct 6, 4:17 pm)
[patch 07/28] ACPI: Fix thermal shutdowns, Greg KH, (Mon Oct 6, 4:17 pm)
[patch 09/28] rtc: fix deadlock, Greg KH, (Mon Oct 6, 4:17 pm)
[patch 24/28] niu: panic on reset, Greg KH, (Mon Oct 6, 4:17 pm)
[patch 28/28] udp: Fix rcv socket locking, Greg KH, (Mon Oct 6, 4:18 pm)
Re: [patch 02/28] pxa2xx_spi: dma bugfixes, Ned Forrester, (Mon Oct 6, 5:15 pm)