unsigned long indicators2;
        struct vq_config_block *config_block;
        bool is_thinint;
+       bool going_away;
        void *airq_info;
 };
 
 
        spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
        vcdev = dev_get_drvdata(&cdev->dev);
-       if (!vcdev) {
+       if (!vcdev || vcdev->going_away) {
                spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
                return NULL;
        }
-       dev_set_drvdata(&cdev->dev, NULL);
+       vcdev->going_away = true;
        spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
        return vcdev;
 }
 
 static void virtio_ccw_remove(struct ccw_device *cdev)
 {
+       unsigned long flags;
        struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev);
 
        if (vcdev && cdev->online)
                unregister_virtio_device(&vcdev->vdev);
+       spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
+       dev_set_drvdata(&cdev->dev, NULL);
+       spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
        cdev->handler = NULL;
 }
 
 static int virtio_ccw_offline(struct ccw_device *cdev)
 {
+       unsigned long flags;
        struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev);
 
-       if (vcdev)
+       if (vcdev) {
                unregister_virtio_device(&vcdev->vdev);
+               spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
+               dev_set_drvdata(&cdev->dev, NULL);
+               spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
+       }
        return 0;
 }