aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/css.c
diff options
context:
space:
mode:
authorCornelia Huck <cohuck@de.ibm.com>2006-01-06 03:19:23 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:51 -0500
commita28c69448154a0901e8815922030c5dcd2f8e388 (patch)
tree532ac1d4abc9cb9317bdfabc09b225ef616dd07b /drivers/s390/cio/css.c
parentf97a56fb768e5fe9cd07c56ca47870136bb5530c (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.c67
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 @@
24int need_rescan = 0; 24int need_rescan = 0;
25int css_init_done = 0; 25int css_init_done = 0;
26 26
27struct pgid global_pgid; 27struct channel_subsystem *css[__MAX_CSSID + 1];
28int css_characteristics_avail = 0;
29 28
30struct device css_bus_device = { 29int css_characteristics_avail = 0;
31 .bus_id = "css0",
32};
33 30
34inline int 31inline int
35for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) 32for_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
423static void __init 420static void __init
424css_generate_pgid(void) 421css_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
439static inline void __init
440setup_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)
446static int __init 457static int __init
447init_channel_subsystem (void) 458init_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;
486out_free:
487 kfree(css[i]);
467out_bus: 488out_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);
469out: 494out:
470 return ret; 495 return ret;