aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/css.c
diff options
context:
space:
mode:
authorCornelia Huck <cohuck@de.ibm.com>2006-01-06 03:19:22 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:51 -0500
commitf97a56fb768e5fe9cd07c56ca47870136bb5530c (patch)
tree05108317a0cca7aa04cd68f4fcb7b7d3a295ddfa /drivers/s390/cio/css.c
parenta8237fc4108060402d904bea5e1062e22e731969 (diff)
[PATCH] s390: introduce for_each_subchannel
for_each_subchannel() is an iterator calling a function for every possible subchannel id until non-zero is returned. Convert the current iterating functions to it. Signed-off-by: Cornelia Huck <cohuck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390/cio/css.c')
-rw-r--r--drivers/s390/cio/css.c110
1 files changed, 58 insertions, 52 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 5137dafd1e8d..dba632a5f71f 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -21,7 +21,6 @@
21#include "ioasm.h" 21#include "ioasm.h"
22#include "chsc.h" 22#include "chsc.h"
23 23
24unsigned int highest_subchannel;
25int need_rescan = 0; 24int need_rescan = 0;
26int css_init_done = 0; 25int css_init_done = 0;
27 26
@@ -32,6 +31,22 @@ struct device css_bus_device = {
32 .bus_id = "css0", 31 .bus_id = "css0",
33}; 32};
34 33
34inline int
35for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
36{
37 struct subchannel_id schid;
38 int ret;
39
40 init_subchannel_id(&schid);
41 ret = -ENODEV;
42 do {
43 ret = fn(schid, data);
44 if (ret)
45 break;
46 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
47 return ret;
48}
49
35static struct subchannel * 50static struct subchannel *
36css_alloc_subchannel(struct subchannel_id schid) 51css_alloc_subchannel(struct subchannel_id schid)
37{ 52{
@@ -280,25 +295,10 @@ css_evaluate_subchannel(struct subchannel_id schid, int slow)
280 return ret; 295 return ret;
281} 296}
282 297
283static void 298static int
284css_rescan_devices(void) 299css_rescan_devices(struct subchannel_id schid, void *data)
285{ 300{
286 int ret; 301 return css_evaluate_subchannel(schid, 1);
287 struct subchannel_id schid;
288
289 init_subchannel_id(&schid);
290 do {
291 ret = css_evaluate_subchannel(schid, 1);
292 /* No more memory. It doesn't make sense to continue. No
293 * panic because this can happen in midflight and just
294 * because we can't use a new device is no reason to crash
295 * the system. */
296 if (ret == -ENOMEM)
297 break;
298 /* -ENXIO indicates that there are no more subchannels. */
299 if (ret == -ENXIO)
300 break;
301 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
302} 302}
303 303
304struct slow_subchannel { 304struct slow_subchannel {
@@ -316,7 +316,7 @@ css_trigger_slow_path(void)
316 316
317 if (need_rescan) { 317 if (need_rescan) {
318 need_rescan = 0; 318 need_rescan = 0;
319 css_rescan_devices(); 319 for_each_subchannel(css_rescan_devices, NULL);
320 return; 320 return;
321 } 321 }
322 322
@@ -383,6 +383,43 @@ css_process_crw(int irq)
383 return ret; 383 return ret;
384} 384}
385 385
386static int __init
387__init_channel_subsystem(struct subchannel_id schid, void *data)
388{
389 struct subchannel *sch;
390 int ret;
391
392 if (cio_is_console(schid))
393 sch = cio_get_console_subchannel();
394 else {
395 sch = css_alloc_subchannel(schid);
396 if (IS_ERR(sch))
397 ret = PTR_ERR(sch);
398 else
399 ret = 0;
400 switch (ret) {
401 case 0:
402 break;
403 case -ENOMEM:
404 panic("Out of memory in init_channel_subsystem\n");
405 /* -ENXIO: no more subchannels. */
406 case -ENXIO:
407 return ret;
408 default:
409 return 0;
410 }
411 }
412 /*
413 * We register ALL valid subchannels in ioinfo, even those
414 * that have been present before init_channel_subsystem.
415 * These subchannels can't have been registered yet (kmalloc
416 * not working) so we do it now. This is true e.g. for the
417 * console subchannel.
418 */
419 css_register_subchannel(sch);
420 return 0;
421}
422
386static void __init 423static void __init
387css_generate_pgid(void) 424css_generate_pgid(void)
388{ 425{
@@ -410,7 +447,6 @@ static int __init
410init_channel_subsystem (void) 447init_channel_subsystem (void)
411{ 448{
412 int ret; 449 int ret;
413 struct subchannel_id schid;
414 450
415 if (chsc_determine_css_characteristics() == 0) 451 if (chsc_determine_css_characteristics() == 0)
416 css_characteristics_avail = 1; 452 css_characteristics_avail = 1;
@@ -426,38 +462,8 @@ init_channel_subsystem (void)
426 462
427 ctl_set_bit(6, 28); 463 ctl_set_bit(6, 28);
428 464
429 init_subchannel_id(&schid); 465 for_each_subchannel(__init_channel_subsystem, NULL);
430 do {
431 struct subchannel *sch;
432
433 if (cio_is_console(schid))
434 sch = cio_get_console_subchannel();
435 else {
436 sch = css_alloc_subchannel(schid);
437 if (IS_ERR(sch))
438 ret = PTR_ERR(sch);
439 else
440 ret = 0;
441 if (ret == -ENOMEM)
442 panic("Out of memory in "
443 "init_channel_subsystem\n");
444 /* -ENXIO: no more subchannels. */
445 if (ret == -ENXIO)
446 break;
447 if (ret)
448 continue;
449 }
450 /*
451 * We register ALL valid subchannels in ioinfo, even those
452 * that have been present before init_channel_subsystem.
453 * These subchannels can't have been registered yet (kmalloc
454 * not working) so we do it now. This is true e.g. for the
455 * console subchannel.
456 */
457 css_register_subchannel(sch);
458 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
459 return 0; 466 return 0;
460
461out_bus: 467out_bus:
462 bus_unregister(&css_bus_type); 468 bus_unregister(&css_bus_type);
463out: 469out: