|
@@ -533,6 +533,17 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static void reprobe_after_idle(struct work_struct *unused)
|
|
|
+{
|
|
|
+ /* Make sure initial subchannel scan is done. */
|
|
|
+ wait_event(ccw_device_init_wq,
|
|
|
+ atomic_read(&ccw_device_init_count) == 0);
|
|
|
+ if (need_reprobe)
|
|
|
+ css_schedule_reprobe();
|
|
|
+}
|
|
|
+
|
|
|
+static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle);
|
|
|
+
|
|
|
/* Work function used to reprobe all unregistered subchannels. */
|
|
|
static void reprobe_all(struct work_struct *unused)
|
|
|
{
|
|
@@ -540,10 +551,12 @@ static void reprobe_all(struct work_struct *unused)
|
|
|
|
|
|
CIO_MSG_EVENT(4, "reprobe start\n");
|
|
|
|
|
|
- need_reprobe = 0;
|
|
|
/* Make sure initial subchannel scan is done. */
|
|
|
- wait_event(ccw_device_init_wq,
|
|
|
- atomic_read(&ccw_device_init_count) == 0);
|
|
|
+ if (atomic_read(&ccw_device_init_count) != 0) {
|
|
|
+ queue_work(ccw_device_work, &reprobe_idle_work);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ need_reprobe = 0;
|
|
|
ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
|
|
|
|
|
|
CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
|