diff options
-rw-r--r-- | drivers/net/wimax/i2400m/sdio-tx.c | 5 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/tx.c | 18 |
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 | ||
150 | void i2400ms_tx_release(struct i2400ms *i2400ms) | 150 | void 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; | ||
645 | try_new: | 648 | try_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 | } |
698 | error_tx_new: | 701 | error_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; | ||
743 | skip: | 752 | skip: |
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; |
851 | out_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 | */ |
877 | void i2400m_tx_release(struct i2400m *i2400m) | 889 | void 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 | } |