From 22d570bb0c488c3c81106f7253928e24c7b80c8f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 3 Dec 2008 03:35:30 -0800 Subject: [PATCH] --- yaml --- r: 122529 b: refs/heads/master c: c112d0c5b89037dd618083b5fdf4bb36b0c51d77 h: refs/heads/master i: 122527: b2fdc70af087cd1f5fd7aaab90bff3ec5f98504d v: v3 --- [refs] | 2 +- trunk/drivers/net/wireless/ath9k/xmit.c | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 6edb30265b77..e2ec0c25aa6a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f8316df10c4e3bec5b4c3a5a8e026c577640c3a6 +refs/heads/master: c112d0c5b89037dd618083b5fdf4bb36b0c51d77 diff --git a/trunk/drivers/net/wireless/ath9k/xmit.c b/trunk/drivers/net/wireless/ath9k/xmit.c index 17fd05e2f247..9de27c681b86 100644 --- a/trunk/drivers/net/wireless/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath9k/xmit.c @@ -1652,7 +1652,9 @@ static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, int hdrlen; __le16 fc; - tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_KERNEL); + tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); + if (unlikely(!tx_info_priv)) + return -ENOMEM; tx_info->rate_driver_data[0] = tx_info_priv; hdrlen = ieee80211_get_hdrlen_from_skb(skb); fc = hdr->frame_control; @@ -1801,10 +1803,26 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, r = ath_tx_setup_buffer(sc, bf, skb, txctl); if (unlikely(r)) { - spin_lock_bh(&sc->sc_txbuflock); + struct ath_txq *txq = txctl->txq; + DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n"); + + /* upon ath_tx_processq() this TX queue will be resumed, we + * guarantee this will happen by knowing beforehand that + * we will at least have to run TX completionon one buffer + * on the queue */ + spin_lock_bh(&txq->axq_lock); + if (ath_txq_depth(sc, txq->axq_qnum) > 1) { + ieee80211_stop_queue(sc->hw, + skb_get_queue_mapping(skb)); + txq->stopped = 1; + } + spin_unlock_bh(&txq->axq_lock); + + spin_lock_bh(&sc->sc_txbuflock); list_add_tail(&bf->list, &sc->sc_txbuf); spin_unlock_bh(&sc->sc_txbuflock); + return r; }