Commit 0ad8f714 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky

s390/cio: fix early init counter usage

Via ccw_device_init_count we keep track of how many devices are in
asynchronous device recognition/initialization. For early devices this
variable was not only used prior to its initialization but used
incorrectly (incremented but never decremented). Fix this by using static
initialization for this variable (and friends), make them visible to
device.c only, and decrement the counter after recognition of early
devices is finished.
Reviewed-by: default avatarPeter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 4e5ebd51
...@@ -44,6 +44,10 @@ static DEFINE_SPINLOCK(recovery_lock); ...@@ -44,6 +44,10 @@ static DEFINE_SPINLOCK(recovery_lock);
static int recovery_phase; static int recovery_phase;
static const unsigned long recovery_delay[] = { 3, 30, 300 }; static const unsigned long recovery_delay[] = { 3, 30, 300 };
static atomic_t ccw_device_init_count = ATOMIC_INIT(0);
static DECLARE_WAIT_QUEUE_HEAD(ccw_device_init_wq);
static struct bus_type ccw_bus_type;
/******************* bus type handling ***********************/ /******************* bus type handling ***********************/
/* The Linux driver model distinguishes between a bus type and /* The Linux driver model distinguishes between a bus type and
...@@ -128,8 +132,6 @@ static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -128,8 +132,6 @@ static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env)
return ret; return ret;
} }
static struct bus_type ccw_bus_type;
static void io_subchannel_irq(struct subchannel *); static void io_subchannel_irq(struct subchannel *);
static int io_subchannel_probe(struct subchannel *); static int io_subchannel_probe(struct subchannel *);
static int io_subchannel_remove(struct subchannel *); static int io_subchannel_remove(struct subchannel *);
...@@ -138,8 +140,6 @@ static int io_subchannel_sch_event(struct subchannel *, int); ...@@ -138,8 +140,6 @@ static int io_subchannel_sch_event(struct subchannel *, int);
static int io_subchannel_chp_event(struct subchannel *, struct chp_link *, static int io_subchannel_chp_event(struct subchannel *, struct chp_link *,
int); int);
static void recovery_func(unsigned long data); static void recovery_func(unsigned long data);
wait_queue_head_t ccw_device_init_wq;
atomic_t ccw_device_init_count;
static struct css_device_id io_subchannel_ids[] = { static struct css_device_id io_subchannel_ids[] = {
{ .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, }, { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, },
...@@ -192,10 +192,7 @@ int __init io_subchannel_init(void) ...@@ -192,10 +192,7 @@ int __init io_subchannel_init(void)
{ {
int ret; int ret;
init_waitqueue_head(&ccw_device_init_wq);
atomic_set(&ccw_device_init_count, 0);
setup_timer(&recovery_timer, recovery_func, 0); setup_timer(&recovery_timer, recovery_func, 0);
ret = bus_register(&ccw_bus_type); ret = bus_register(&ccw_bus_type);
if (ret) if (ret)
return ret; return ret;
...@@ -1093,6 +1090,8 @@ static int io_subchannel_probe(struct subchannel *sch) ...@@ -1093,6 +1090,8 @@ static int io_subchannel_probe(struct subchannel *sch)
put_device(&cdev->dev); put_device(&cdev->dev);
goto out_schedule; goto out_schedule;
} }
if (atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq);
return 0; return 0;
} }
io_subchannel_init_fields(sch); io_subchannel_init_fields(sch);
......
...@@ -81,8 +81,6 @@ dev_fsm_final_state(struct ccw_device *cdev) ...@@ -81,8 +81,6 @@ dev_fsm_final_state(struct ccw_device *cdev)
cdev->private->state == DEV_STATE_BOXED); cdev->private->state == DEV_STATE_BOXED);
} }
extern wait_queue_head_t ccw_device_init_wq;
extern atomic_t ccw_device_init_count;
int __init io_subchannel_init(void); int __init io_subchannel_init(void);
void io_subchannel_recog_done(struct ccw_device *cdev); void io_subchannel_recog_done(struct ccw_device *cdev);
......
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