@@ -61,6 +61,7 @@ struct virtio_ccw_device {
61
61
unsigned long indicators2 ;
62
62
struct vq_config_block * config_block ;
63
63
bool is_thinint ;
64
+ bool going_away ;
64
65
void * airq_info ;
65
66
};
66
67
@@ -995,30 +996,39 @@ static struct virtio_ccw_device *virtio_grab_drvdata(struct ccw_device *cdev)
995
996
996
997
spin_lock_irqsave (get_ccwdev_lock (cdev ), flags );
997
998
vcdev = dev_get_drvdata (& cdev -> dev );
998
- if (!vcdev ) {
999
+ if (!vcdev || vcdev -> going_away ) {
999
1000
spin_unlock_irqrestore (get_ccwdev_lock (cdev ), flags );
1000
1001
return NULL ;
1001
1002
}
1002
- dev_set_drvdata ( & cdev -> dev , NULL ) ;
1003
+ vcdev -> going_away = true ;
1003
1004
spin_unlock_irqrestore (get_ccwdev_lock (cdev ), flags );
1004
1005
return vcdev ;
1005
1006
}
1006
1007
1007
1008
static void virtio_ccw_remove (struct ccw_device * cdev )
1008
1009
{
1010
+ unsigned long flags ;
1009
1011
struct virtio_ccw_device * vcdev = virtio_grab_drvdata (cdev );
1010
1012
1011
1013
if (vcdev && cdev -> online )
1012
1014
unregister_virtio_device (& vcdev -> vdev );
1015
+ spin_lock_irqsave (get_ccwdev_lock (cdev ), flags );
1016
+ dev_set_drvdata (& cdev -> dev , NULL );
1017
+ spin_unlock_irqrestore (get_ccwdev_lock (cdev ), flags );
1013
1018
cdev -> handler = NULL ;
1014
1019
}
1015
1020
1016
1021
static int virtio_ccw_offline (struct ccw_device * cdev )
1017
1022
{
1023
+ unsigned long flags ;
1018
1024
struct virtio_ccw_device * vcdev = virtio_grab_drvdata (cdev );
1019
1025
1020
- if (vcdev )
1026
+ if (vcdev ) {
1021
1027
unregister_virtio_device (& vcdev -> vdev );
1028
+ spin_lock_irqsave (get_ccwdev_lock (cdev ), flags );
1029
+ dev_set_drvdata (& cdev -> dev , NULL );
1030
+ spin_unlock_irqrestore (get_ccwdev_lock (cdev ), flags );
1031
+ }
1022
1032
return 0 ;
1023
1033
}
1024
1034
0 commit comments