Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760286AbYJGBAD (ORCPT ); Mon, 6 Oct 2008 21:00:03 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757886AbYJGApo (ORCPT ); Mon, 6 Oct 2008 20:45:44 -0400 Received: from cantor2.suse.de ([195.135.220.15]:60937 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757880AbYJGApn (ORCPT ); Mon, 6 Oct 2008 20:45:43 -0400 Date: Mon, 6 Oct 2008 17:39:53 -0700 From: Greg KH To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: Justin Forbes , Zwane Mwaikambo , "Theodore Ts'o" , Randy Dunlap , Dave Jones , Chuck Wolber , Chris Wedgwood , Michael Krufky , Chuck Ebbert , Domenico Andreoli , Willy Tarreau , Rodrigo Rubira Branco , Jake Edge , Eugene Teo , torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Santwona Behera , "David S. Miller" Subject: [patch 54/71] niu: panic on reset Message-ID: <20081007003953.GC3055@suse.de> References: <20081007002606.723632097@mini.kroah.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename="0004-niu-panic-on-reset.patch" In-Reply-To: <20081007003634.GA3055@suse.de> User-Agent: Mutt/1.5.16 (2007-06-09) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2622 Lines: 99 2.6.26-stable review patch. If anyone has any objections, please let us know. ------------------ From: Santwona Behera [ 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 Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/niu.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -5978,6 +5978,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); @@ -6000,6 +6050,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; -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/