aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wimax/i2400m/sdio-tx.c5
-rw-r--r--drivers/net/wimax/i2400m/tx.c18
2 files changed, 21 insertions, 2 deletions
diff --git a/drivers/net/wimax/i2400m/sdio-tx.c b/drivers/net/wimax/i2400m/sdio-tx.c
index 5105a5ebc44f..de66d068c9cb 100644
--- a/drivers/net/wimax/i2400m/sdio-tx.c
+++ b/drivers/net/wimax/i2400m/sdio-tx.c
@@ -149,5 +149,8 @@ int i2400ms_tx_setup(struct i2400ms *i2400ms)
149 149
150void i2400ms_tx_release(struct i2400ms *i2400ms) 150void i2400ms_tx_release(struct i2400ms *i2400ms)
151{ 151{
152 destroy_workqueue(i2400ms->tx_workqueue); 152 if (i2400ms->tx_workqueue) {
153 destroy_workqueue(i2400ms->tx_workqueue);
154 i2400ms->tx_workqueue = NULL;
155 }
153} 156}
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index 8c2080248aec..54480e8947f1 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -642,6 +642,9 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
642 * current one is out of payload slots or we have a singleton, 642 * current one is out of payload slots or we have a singleton,
643 * close it and start a new one */ 643 * close it and start a new one */
644 spin_lock_irqsave(&i2400m->tx_lock, flags); 644 spin_lock_irqsave(&i2400m->tx_lock, flags);
645 result = -ESHUTDOWN;
646 if (i2400m->tx_buf == NULL)
647 goto error_tx_new;
645try_new: 648try_new:
646 if (unlikely(i2400m->tx_msg == NULL)) 649 if (unlikely(i2400m->tx_msg == NULL))
647 i2400m_tx_new(i2400m); 650 i2400m_tx_new(i2400m);
@@ -697,7 +700,10 @@ try_new:
697 } 700 }
698error_tx_new: 701error_tx_new:
699 spin_unlock_irqrestore(&i2400m->tx_lock, flags); 702 spin_unlock_irqrestore(&i2400m->tx_lock, flags);
700 i2400m->bus_tx_kick(i2400m); /* always kick, might free up space */ 703 /* kick in most cases, except when the TX subsys is down, as
704 * it might free space */
705 if (likely(result != -ESHUTDOWN))
706 i2400m->bus_tx_kick(i2400m);
701 d_fnend(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u) = %d\n", 707 d_fnend(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u) = %d\n",
702 i2400m, buf, buf_len, pl_type, result); 708 i2400m, buf, buf_len, pl_type, result);
703 return result; 709 return result;
@@ -740,6 +746,9 @@ struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *i2400m,
740 746
741 d_fnstart(3, dev, "(i2400m %p bus_size %p)\n", i2400m, bus_size); 747 d_fnstart(3, dev, "(i2400m %p bus_size %p)\n", i2400m, bus_size);
742 spin_lock_irqsave(&i2400m->tx_lock, flags); 748 spin_lock_irqsave(&i2400m->tx_lock, flags);
749 tx_msg_moved = NULL;
750 if (i2400m->tx_buf == NULL)
751 goto out_unlock;
743skip: 752skip:
744 tx_msg_moved = NULL; 753 tx_msg_moved = NULL;
745 if (i2400m->tx_in == i2400m->tx_out) { /* Empty FIFO? */ 754 if (i2400m->tx_in == i2400m->tx_out) { /* Empty FIFO? */
@@ -829,6 +838,8 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m)
829 838
830 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 839 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
831 spin_lock_irqsave(&i2400m->tx_lock, flags); 840 spin_lock_irqsave(&i2400m->tx_lock, flags);
841 if (i2400m->tx_buf == NULL)
842 goto out_unlock;
832 i2400m->tx_out += i2400m->tx_msg_size; 843 i2400m->tx_out += i2400m->tx_msg_size;
833 d_printf(2, dev, "TX: sent %zu b\n", (size_t) i2400m->tx_msg_size); 844 d_printf(2, dev, "TX: sent %zu b\n", (size_t) i2400m->tx_msg_size);
834 i2400m->tx_msg_size = 0; 845 i2400m->tx_msg_size = 0;
@@ -837,6 +848,7 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m)
837 n = i2400m->tx_out / I2400M_TX_BUF_SIZE; 848 n = i2400m->tx_out / I2400M_TX_BUF_SIZE;
838 i2400m->tx_out %= I2400M_TX_BUF_SIZE; 849 i2400m->tx_out %= I2400M_TX_BUF_SIZE;
839 i2400m->tx_in -= n * I2400M_TX_BUF_SIZE; 850 i2400m->tx_in -= n * I2400M_TX_BUF_SIZE;
851out_unlock:
840 spin_unlock_irqrestore(&i2400m->tx_lock, flags); 852 spin_unlock_irqrestore(&i2400m->tx_lock, flags);
841 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); 853 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
842} 854}
@@ -876,5 +888,9 @@ int i2400m_tx_setup(struct i2400m *i2400m)
876 */ 888 */
877void i2400m_tx_release(struct i2400m *i2400m) 889void i2400m_tx_release(struct i2400m *i2400m)
878{ 890{
891 unsigned long flags;
892 spin_lock_irqsave(&i2400m->tx_lock, flags);
879 kfree(i2400m->tx_buf); 893 kfree(i2400m->tx_buf);
894 i2400m->tx_buf = NULL;
895 spin_unlock_irqrestore(&i2400m->tx_lock, flags);
880} 896}