Commit a17409e7 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by David S. Miller

net: cxgb3: Cleanup in_interrupt() usage

t3_sge_stop() is called from task context and from error handlers in
interrupt context. It relies on in_interrupt() to differentiate the
contexts.

in_interrupt() is deprecated as it is ill defined and does not provide what
it suggests.

Instead of replacing it with some other construct, simply split the
function into t3_sge_stop_dma(), which can be called from any context, and
t3_sge_stop() which can be only called from task context.

This has the advantage that any bogus invocation of t3_sge_stop() from
wrong contexts can be caught by debug kernels instead of being papered over
by the conditional.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 453590a8
...@@ -313,6 +313,7 @@ void t3_os_link_fault(struct adapter *adapter, int port_id, int state); ...@@ -313,6 +313,7 @@ void t3_os_link_fault(struct adapter *adapter, int port_id, int state);
void t3_os_link_fault_handler(struct adapter *adapter, int port_id); void t3_os_link_fault_handler(struct adapter *adapter, int port_id);
void t3_sge_start(struct adapter *adap); void t3_sge_start(struct adapter *adap);
void t3_sge_stop_dma(struct adapter *adap);
void t3_sge_stop(struct adapter *adap); void t3_sge_stop(struct adapter *adap);
void t3_start_sge_timers(struct adapter *adap); void t3_start_sge_timers(struct adapter *adap);
void t3_stop_sge_timers(struct adapter *adap); void t3_stop_sge_timers(struct adapter *adap);
......
...@@ -2996,7 +2996,7 @@ void t3_fatal_err(struct adapter *adapter) ...@@ -2996,7 +2996,7 @@ void t3_fatal_err(struct adapter *adapter)
unsigned int fw_status[4]; unsigned int fw_status[4];
if (adapter->flags & FULL_INIT_DONE) { if (adapter->flags & FULL_INIT_DONE) {
t3_sge_stop(adapter); t3_sge_stop_dma(adapter);
t3_write_reg(adapter, A_XGM_TX_CTRL, 0); t3_write_reg(adapter, A_XGM_TX_CTRL, 0);
t3_write_reg(adapter, A_XGM_RX_CTRL, 0); t3_write_reg(adapter, A_XGM_RX_CTRL, 0);
t3_write_reg(adapter, XGM_REG(A_XGM_TX_CTRL, 1), 0); t3_write_reg(adapter, XGM_REG(A_XGM_TX_CTRL, 1), 0);
......
...@@ -3270,31 +3270,41 @@ void t3_sge_start(struct adapter *adap) ...@@ -3270,31 +3270,41 @@ void t3_sge_start(struct adapter *adap)
} }
/** /**
* t3_sge_stop - disable SGE operation * t3_sge_stop_dma - Disable SGE DMA engine operation
* @adap: the adapter * @adap: the adapter
* *
* Disables the DMA engine. This can be called in emeregencies (e.g., * Can be invoked from interrupt context e.g. error handler.
* from error interrupts) or from normal process context. In the latter *
* case it also disables any pending queue restart tasklets. Note that * Note that this function cannot disable the restart of tasklets as
* if it is called in interrupt context it cannot disable the restart * it cannot wait if called from interrupt context, however the
* tasklets as it cannot wait, however the tasklets will have no effect * tasklets will have no effect since the doorbells are disabled. The
* since the doorbells are disabled and the driver will call this again * driver will call tg3_sge_stop() later from process context, at
* later from process context, at which time the tasklets will be stopped * which time the tasklets will be stopped if they are still running.
* if they are still running.
*/ */
void t3_sge_stop(struct adapter *adap) void t3_sge_stop_dma(struct adapter *adap)
{ {
t3_set_reg_field(adap, A_SG_CONTROL, F_GLOBALENABLE, 0); t3_set_reg_field(adap, A_SG_CONTROL, F_GLOBALENABLE, 0);
if (!in_interrupt()) { }
/**
* t3_sge_stop - disable SGE operation completly
* @adap: the adapter
*
* Called from process context. Disables the DMA engine and any
* pending queue restart tasklets.
*/
void t3_sge_stop(struct adapter *adap)
{
int i; int i;
t3_sge_stop_dma(adap);
for (i = 0; i < SGE_QSETS; ++i) { for (i = 0; i < SGE_QSETS; ++i) {
struct sge_qset *qs = &adap->sge.qs[i]; struct sge_qset *qs = &adap->sge.qs[i];
tasklet_kill(&qs->txq[TXQ_OFLD].qresume_tsk); tasklet_kill(&qs->txq[TXQ_OFLD].qresume_tsk);
tasklet_kill(&qs->txq[TXQ_CTRL].qresume_tsk); tasklet_kill(&qs->txq[TXQ_CTRL].qresume_tsk);
} }
}
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment