aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/css.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/css.c')
-rw-r--r--drivers/s390/cio/css.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 74ea8aac4b7d..1d3be80797f8 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -19,9 +19,11 @@
19#include "cio_debug.h" 19#include "cio_debug.h"
20#include "ioasm.h" 20#include "ioasm.h"
21#include "chsc.h" 21#include "chsc.h"
22#include "device.h"
22 23
23int need_rescan = 0; 24int need_rescan = 0;
24int css_init_done = 0; 25int css_init_done = 0;
26static int need_reprobe = 0;
25static int max_ssid = 0; 27static int max_ssid = 0;
26 28
27struct channel_subsystem *css[__MAX_CSSID + 1]; 29struct channel_subsystem *css[__MAX_CSSID + 1];
@@ -339,6 +341,67 @@ typedef void (*workfunc)(void *);
339DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); 341DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL);
340struct workqueue_struct *slow_path_wq; 342struct workqueue_struct *slow_path_wq;
341 343
344/* Reprobe subchannel if unregistered. */
345static int reprobe_subchannel(struct subchannel_id schid, void *data)
346{
347 struct subchannel *sch;
348 int ret;
349
350 CIO_DEBUG(KERN_INFO, 6, "cio: reprobe 0.%x.%04x\n",
351 schid.ssid, schid.sch_no);
352 if (need_reprobe)
353 return -EAGAIN;
354
355 sch = get_subchannel_by_schid(schid);
356 if (sch) {
357 /* Already known. */
358 put_device(&sch->dev);
359 return 0;
360 }
361
362 ret = css_probe_device(schid);
363 switch (ret) {
364 case 0:
365 break;
366 case -ENXIO:
367 case -ENOMEM:
368 /* These should abort looping */
369 break;
370 default:
371 ret = 0;
372 }
373
374 return ret;
375}
376
377/* Work function used to reprobe all unregistered subchannels. */
378static void reprobe_all(void *data)
379{
380 int ret;
381
382 CIO_MSG_EVENT(2, "reprobe start\n");
383
384 need_reprobe = 0;
385 /* Make sure initial subchannel scan is done. */
386 wait_event(ccw_device_init_wq,
387 atomic_read(&ccw_device_init_count) == 0);
388 ret = for_each_subchannel(reprobe_subchannel, NULL);
389
390 CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
391 need_reprobe);
392}
393
394DECLARE_WORK(css_reprobe_work, reprobe_all, NULL);
395
396/* Schedule reprobing of all unregistered subchannels. */
397void css_schedule_reprobe(void)
398{
399 need_reprobe = 1;
400 queue_work(ccw_device_work, &css_reprobe_work);
401}
402
403EXPORT_SYMBOL_GPL(css_schedule_reprobe);
404
342/* 405/*
343 * Rescan for new devices. FIXME: This is slow. 406 * Rescan for new devices. FIXME: This is slow.
344 * This function is called when we have lost CRWs due to overflows and we have 407 * This function is called when we have lost CRWs due to overflows and we have