diff options
author | Cornelia Huck <cohuck@de.ibm.com> | 2006-01-06 03:19:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:51 -0500 |
commit | a28c69448154a0901e8815922030c5dcd2f8e388 (patch) | |
tree | 532ac1d4abc9cb9317bdfabc09b225ef616dd07b /drivers/s390/cio/css.c | |
parent | f97a56fb768e5fe9cd07c56ca47870136bb5530c (diff) |
[PATCH] s390: introduce struct channel_subsystem
struct channel_subsystem encapsulates several per channel subsystem
properties, like status of chpids or the global path group id.
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.c | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index dba632a5f71f..b6225cbbbee7 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -24,12 +24,9 @@ | |||
24 | int need_rescan = 0; | 24 | int need_rescan = 0; |
25 | int css_init_done = 0; | 25 | int css_init_done = 0; |
26 | 26 | ||
27 | struct pgid global_pgid; | 27 | struct channel_subsystem *css[__MAX_CSSID + 1]; |
28 | int css_characteristics_avail = 0; | ||
29 | 28 | ||
30 | struct device css_bus_device = { | 29 | int css_characteristics_avail = 0; |
31 | .bus_id = "css0", | ||
32 | }; | ||
33 | 30 | ||
34 | inline int | 31 | inline int |
35 | for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) | 32 | for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) |
@@ -112,7 +109,7 @@ css_register_subchannel(struct subchannel *sch) | |||
112 | int ret; | 109 | int ret; |
113 | 110 | ||
114 | /* Initialize the subchannel structure */ | 111 | /* Initialize the subchannel structure */ |
115 | sch->dev.parent = &css_bus_device; | 112 | sch->dev.parent = &css[0]->device; |
116 | sch->dev.bus = &css_bus_type; | 113 | sch->dev.bus = &css_bus_type; |
117 | sch->dev.release = &css_subchannel_release; | 114 | sch->dev.release = &css_subchannel_release; |
118 | 115 | ||
@@ -421,21 +418,35 @@ __init_channel_subsystem(struct subchannel_id schid, void *data) | |||
421 | } | 418 | } |
422 | 419 | ||
423 | static void __init | 420 | static void __init |
424 | css_generate_pgid(void) | 421 | css_generate_pgid(struct channel_subsystem *css, u32 tod_high) |
425 | { | 422 | { |
426 | /* Let's build our path group ID here. */ | 423 | if (css_characteristics_avail && css_general_characteristics.mcss) { |
427 | if (css_characteristics_avail && css_general_characteristics.mcss) | 424 | css->global_pgid.pgid_high.ext_cssid.version = 0x80; |
428 | global_pgid.cpu_addr = 0x8000; | 425 | css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid; |
429 | else { | 426 | } else { |
430 | #ifdef CONFIG_SMP | 427 | #ifdef CONFIG_SMP |
431 | global_pgid.cpu_addr = hard_smp_processor_id(); | 428 | css->global_pgid.pgid_high.cpu_addr = hard_smp_processor_id(); |
432 | #else | 429 | #else |
433 | global_pgid.cpu_addr = 0; | 430 | css->global_pgid.pgid_high.cpu_addr = 0; |
434 | #endif | 431 | #endif |
435 | } | 432 | } |
436 | global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident; | 433 | css->global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident; |
437 | global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine; | 434 | css->global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine; |
438 | global_pgid.tod_high = (__u32) (get_clock() >> 32); | 435 | css->global_pgid.tod_high = tod_high; |
436 | |||
437 | } | ||
438 | |||
439 | static inline void __init | ||
440 | setup_css(int nr) | ||
441 | { | ||
442 | u32 tod_high; | ||
443 | |||
444 | memset(css[nr], 0, sizeof(struct channel_subsystem)); | ||
445 | css[nr]->valid = 1; | ||
446 | css[nr]->cssid = nr; | ||
447 | sprintf(css[nr]->device.bus_id, "css%x", nr); | ||
448 | tod_high = (u32) (get_clock() >> 32); | ||
449 | css_generate_pgid(css[nr], tod_high); | ||
439 | } | 450 | } |
440 | 451 | ||
441 | /* | 452 | /* |
@@ -446,25 +457,39 @@ css_generate_pgid(void) | |||
446 | static int __init | 457 | static int __init |
447 | init_channel_subsystem (void) | 458 | init_channel_subsystem (void) |
448 | { | 459 | { |
449 | int ret; | 460 | int ret, i; |
450 | 461 | ||
451 | if (chsc_determine_css_characteristics() == 0) | 462 | if (chsc_determine_css_characteristics() == 0) |
452 | css_characteristics_avail = 1; | 463 | css_characteristics_avail = 1; |
453 | 464 | ||
454 | css_generate_pgid(); | ||
455 | |||
456 | if ((ret = bus_register(&css_bus_type))) | 465 | if ((ret = bus_register(&css_bus_type))) |
457 | goto out; | 466 | goto out; |
458 | if ((ret = device_register (&css_bus_device))) | ||
459 | goto out_bus; | ||
460 | 467 | ||
468 | /* Setup css structure. */ | ||
469 | for (i = 0; i <= __MAX_CSSID; i++) { | ||
470 | css[i] = kmalloc(sizeof(struct channel_subsystem), GFP_KERNEL); | ||
471 | if (!css[i]) { | ||
472 | ret = -ENOMEM; | ||
473 | goto out_bus; | ||
474 | } | ||
475 | setup_css(i); | ||
476 | ret = device_register(&css[i]->device); | ||
477 | if (ret) | ||
478 | goto out_free; | ||
479 | } | ||
461 | css_init_done = 1; | 480 | css_init_done = 1; |
462 | 481 | ||
463 | ctl_set_bit(6, 28); | 482 | ctl_set_bit(6, 28); |
464 | 483 | ||
465 | for_each_subchannel(__init_channel_subsystem, NULL); | 484 | for_each_subchannel(__init_channel_subsystem, NULL); |
466 | return 0; | 485 | return 0; |
486 | out_free: | ||
487 | kfree(css[i]); | ||
467 | out_bus: | 488 | out_bus: |
489 | while (i > 0) { | ||
490 | i--; | ||
491 | device_unregister(&css[i]->device); | ||
492 | } | ||
468 | bus_unregister(&css_bus_type); | 493 | bus_unregister(&css_bus_type); |
469 | out: | 494 | out: |
470 | return ret; | 495 | return ret; |