struct subchannel_id *schid,
                        struct qdio_ssqd_desc *data);
 int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data);
+void qdio_shutdown_irq(struct qdio_irq *irq);
 void qdio_print_subchannel_info(struct qdio_irq *irq_ptr);
 void qdio_release_memory(struct qdio_irq *irq_ptr);
 int qdio_setup_init(void);
 
 
        /* cleanup subchannel */
        spin_lock_irq(get_ccwdev_lock(cdev));
-
+       qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP);
        if (how & QDIO_FLAG_CLEANUP_USING_CLEAR)
                rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP);
        else
                /* default behaviour is halt */
                rc = ccw_device_halt(cdev, QDIO_DOING_CLEANUP);
+       spin_unlock_irq(get_ccwdev_lock(cdev));
        if (rc) {
                DBF_ERROR("%4x SHUTD ERR", irq_ptr->schid.sch_no);
                DBF_ERROR("rc:%4d", rc);
                goto no_cleanup;
        }
 
-       qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP);
-       spin_unlock_irq(get_ccwdev_lock(cdev));
        wait_event_interruptible_timeout(cdev->private->wait_q,
                irq_ptr->state == QDIO_IRQ_STATE_INACTIVE ||
                irq_ptr->state == QDIO_IRQ_STATE_ERR,
                10 * HZ);
-       spin_lock_irq(get_ccwdev_lock(cdev));
 
 no_cleanup:
        qdio_shutdown_thinint(irq_ptr);
-
-       /* restore interrupt handler */
-       if ((void *)cdev->handler == (void *)qdio_int_handler) {
-               cdev->handler = irq_ptr->orig_handler;
-               cdev->private->intparm = 0;
-       }
-       spin_unlock_irq(get_ccwdev_lock(cdev));
+       qdio_shutdown_irq(irq_ptr);
 
        qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
        mutex_unlock(&irq_ptr->setup_mutex);
 
        rc = qdio_establish_thinint(irq_ptr);
        if (rc) {
+               qdio_shutdown_irq(irq_ptr);
                mutex_unlock(&irq_ptr->setup_mutex);
-               qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
                return rc;
        }
 
        if (rc) {
                DBF_ERROR("%4x est IO ERR", irq_ptr->schid.sch_no);
                DBF_ERROR("rc:%4x", rc);
+               qdio_shutdown_irq(irq_ptr);
                mutex_unlock(&irq_ptr->setup_mutex);
-               qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
                return rc;
        }
 
 
 
        /* qdr, qib, sls, slsbs, slibs, sbales are filled now */
 
+       /* set our IRQ handler */
+       spin_lock_irq(get_ccwdev_lock(cdev));
+       irq_ptr->orig_handler = cdev->handler;
+       cdev->handler = qdio_int_handler;
+       spin_unlock_irq(get_ccwdev_lock(cdev));
+
        /* get qdio commands */
        ciw = ccw_device_get_ciw(cdev, CIW_TYPE_EQUEUE);
        if (!ciw) {
        }
        irq_ptr->aqueue = *ciw;
 
-       /* set new interrupt handler */
+       return 0;
+}
+
+void qdio_shutdown_irq(struct qdio_irq *irq)
+{
+       struct ccw_device *cdev = irq->cdev;
+
+       /* restore IRQ handler */
        spin_lock_irq(get_ccwdev_lock(cdev));
-       irq_ptr->orig_handler = cdev->handler;
-       cdev->handler = qdio_int_handler;
+       cdev->handler = irq->orig_handler;
+       cdev->private->intparm = 0;
        spin_unlock_irq(get_ccwdev_lock(cdev));
-       return 0;
 }
 
 void qdio_print_subchannel_info(struct qdio_irq *irq_ptr)