spin_unlock_irqrestore(&q->lock, flags);
 
-       if (queue_type(q) == QDIO_ZFCP_QFMT) {
+       if (queue_type(q) == QDIO_ZFCP_QFMT)
                if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
-                       tasklet_schedule(&q->tasklet);
-               return;
-       }
+                       goto sched;
 
        /* bail out for HiperSockets unicast queues */
        if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
                return;
 
        if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
-           (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) {
-               tasklet_schedule(&q->tasklet);
-               return;
-       }
+           (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
+               goto sched;
 
        if (q->u.out.pci_out_enabled)
                return;
                        qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
                }
        }
+       return;
+
+sched:
+       if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+               return;
+       tasklet_schedule(&q->tasklet);
 }
 
 /* outbound tasklet */
 void qdio_outbound_timer(unsigned long data)
 {
        struct qdio_q *q = (struct qdio_q *)data;
+
+       if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+               return;
        tasklet_schedule(&q->tasklet);
 }
 
        int i;
        struct qdio_q *q;
 
+       if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+               return;
+
        qdio_perf_stat_inc(&perf_stats.pci_int);
 
        for_each_input_queue(irq_ptr, q, i)
        int i;
 
        for_each_input_queue(irq_ptr, q, i)
-               tasklet_disable(&q->tasklet);
+               tasklet_kill(&q->tasklet);
 
        for_each_output_queue(irq_ptr, q, i) {
-               tasklet_disable(&q->tasklet);
                del_timer(&q->u.out.timer);
+               tasklet_kill(&q->tasklet);
        }
 }
 
                return 0;
        }
 
+       /*
+        * Indicate that the device is going down. Scheduling the queue
+        * tasklets is forbidden from here on.
+        */
+       qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
+
        tiqdio_remove_input_queues(irq_ptr);
        qdio_shutdown_queues(cdev);
        qdio_shutdown_debug_entries(irq_ptr, cdev);
                qdio_perf_stat_inc(&perf_stats.fast_requeue);
        }
 out:
-       /* Fixme: could wait forever if called from process context */
        tasklet_schedule(&q->tasklet);
 }
 
 
                list_add_rcu(&q->entry, &tiq_list);
        mutex_unlock(&tiq_list_lock);
        xchg(irq_ptr->dsci, 1);
-       tasklet_schedule(&tiqdio_tasklet);
 }
 
 /*
         */
        qdio_check_outbound_after_thinint(q);
 
-again:
        if (!qdio_inbound_q_moved(q))
                return;
 
 
        if (!tiqdio_inbound_q_done(q)) {
                qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
-               goto again;
+               if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+                       tasklet_schedule(&q->tasklet);
        }
 
        qdio_stop_polling(q);
         */
        if (!tiqdio_inbound_q_done(q)) {
                qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
-               goto again;
+               if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+                       tasklet_schedule(&q->tasklet);
        }
 }