aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/css.c
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2006-06-29 08:57:03 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-06-29 08:57:03 -0400
commit40154b824331cd9c81c06545761338f3d80a36e2 (patch)
treeda4d06f7b09150e1c34b543d5300c3948e284a70 /drivers/s390/cio/css.c
parent887ab5992925736ab23985c35f8149739e9de354 (diff)
[S390] cio async subchannel reprobe.
Changes in the DASD driver require an asynchronous implementation of the subchannel reprobe loop. This loop was so far only used by the blacklisting mechanism but is now available to all CCW device drivers. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
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