lkml.org 
[lkml]   [2009]   [Feb]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch/s390 09/46] move sysinfo.c from drivers/s390 to arch/s390/kernel
    From: Heiko Carstens <heiko.carstens@de.ibm.com>

    All in sysinfo.c is core kernel code and not driver code. So move it
    to arch/s390/kernel. Also includes some small cleanups.

    Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
    Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
    ---

    arch/s390/kernel/Makefile | 4
    arch/s390/kernel/sysinfo.c | 428 +++++++++++++++++++++++++++++++++++++++++
    drivers/s390/Makefile | 4
    drivers/s390/sysinfo.c | 469 ---------------------------------------------
    4 files changed, 432 insertions(+), 473 deletions(-)

    Index: quilt-2.6/arch/s390/kernel/Makefile
    ===================================================================
    --- quilt-2.6.orig/arch/s390/kernel/Makefile
    +++ quilt-2.6/arch/s390/kernel/Makefile
    @@ -17,10 +17,12 @@ CFLAGS_smp.o := -Wno-nonnull
    #
    CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'

    +CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
    +
    obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o \
    processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
    s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
    - vdso.o vtime.o
    + vdso.o vtime.o sysinfo.o

    obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
    obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
    Index: quilt-2.6/arch/s390/kernel/sysinfo.c
    ===================================================================
    --- /dev/null
    +++ quilt-2.6/arch/s390/kernel/sysinfo.c
    @@ -0,0 +1,428 @@
    +/*
    + * Copyright IBM Corp. 2001, 2009
    + * Author(s): Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
    + * Martin Schwidefsky <schwidefsky@de.ibm.com>,
    + */
    +
    +#include <linux/kernel.h>
    +#include <linux/mm.h>
    +#include <linux/proc_fs.h>
    +#include <linux/seq_file.h>
    +#include <linux/init.h>
    +#include <linux/delay.h>
    +#include <linux/module.h>
    +#include <asm/ebcdic.h>
    +#include <asm/sysinfo.h>
    +#include <asm/cpcmd.h>
    +
    +/* Sigh, math-emu. Don't ask. */
    +#include <asm/sfp-util.h>
    +#include <math-emu/soft-fp.h>
    +#include <math-emu/single.h>
    +
    +static inline int stsi_0(void)
    +{
    + int rc = stsi(NULL, 0, 0, 0);
    + return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
    +}
    +
    +static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
    +{
    + if (stsi(info, 1, 1, 1) == -ENOSYS)
    + return len;
    +
    + EBCASC(info->manufacturer, sizeof(info->manufacturer));
    + EBCASC(info->type, sizeof(info->type));
    + EBCASC(info->model, sizeof(info->model));
    + EBCASC(info->sequence, sizeof(info->sequence));
    + EBCASC(info->plant, sizeof(info->plant));
    + EBCASC(info->model_capacity, sizeof(info->model_capacity));
    + EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
    + EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
    + len += sprintf(page + len, "Manufacturer: %-16.16s\n",
    + info->manufacturer);
    + len += sprintf(page + len, "Type: %-4.4s\n",
    + info->type);
    + if (info->model[0] != '\0')
    + /*
    + * Sigh: the model field has been renamed with System z9
    + * to model_capacity and a new model field has been added
    + * after the plant field. To avoid confusing older programs
    + * the "Model:" prints "model_capacity model" or just
    + * "model_capacity" if the model string is empty .
    + */
    + len += sprintf(page + len,
    + "Model: %-16.16s %-16.16s\n",
    + info->model_capacity, info->model);
    + else
    + len += sprintf(page + len, "Model: %-16.16s\n",
    + info->model_capacity);
    + len += sprintf(page + len, "Sequence Code: %-16.16s\n",
    + info->sequence);
    + len += sprintf(page + len, "Plant: %-4.4s\n",
    + info->plant);
    + len += sprintf(page + len, "Model Capacity: %-16.16s %08u\n",
    + info->model_capacity, *(u32 *) info->model_cap_rating);
    + if (info->model_perm_cap[0] != '\0')
    + len += sprintf(page + len,
    + "Model Perm. Capacity: %-16.16s %08u\n",
    + info->model_perm_cap,
    + *(u32 *) info->model_perm_cap_rating);
    + if (info->model_temp_cap[0] != '\0')
    + len += sprintf(page + len,
    + "Model Temp. Capacity: %-16.16s %08u\n",
    + info->model_temp_cap,
    + *(u32 *) info->model_temp_cap_rating);
    + return len;
    +}
    +
    +static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
    +{
    + struct sysinfo_1_2_2_extension *ext;
    + int i;
    +
    + if (stsi(info, 1, 2, 2) == -ENOSYS)
    + return len;
    + ext = (struct sysinfo_1_2_2_extension *)
    + ((unsigned long) info + info->acc_offset);
    +
    + len += sprintf(page + len, "\n");
    + len += sprintf(page + len, "CPUs Total: %d\n",
    + info->cpus_total);
    + len += sprintf(page + len, "CPUs Configured: %d\n",
    + info->cpus_configured);
    + len += sprintf(page + len, "CPUs Standby: %d\n",
    + info->cpus_standby);
    + len += sprintf(page + len, "CPUs Reserved: %d\n",
    + info->cpus_reserved);
    +
    + if (info->format == 1) {
    + /*
    + * Sigh 2. According to the specification the alternate
    + * capability field is a 32 bit floating point number
    + * if the higher order 8 bits are not zero. Printing
    + * a floating point number in the kernel is a no-no,
    + * always print the number as 32 bit unsigned integer.
    + * The user-space needs to know about the strange
    + * encoding of the alternate cpu capability.
    + */
    + len += sprintf(page + len, "Capability: %u %u\n",
    + info->capability, ext->alt_capability);
    + for (i = 2; i <= info->cpus_total; i++)
    + len += sprintf(page + len,
    + "Adjustment %02d-way: %u %u\n",
    + i, info->adjustment[i-2],
    + ext->alt_adjustment[i-2]);
    +
    + } else {
    + len += sprintf(page + len, "Capability: %u\n",
    + info->capability);
    + for (i = 2; i <= info->cpus_total; i++)
    + len += sprintf(page + len,
    + "Adjustment %02d-way: %u\n",
    + i, info->adjustment[i-2]);
    + }
    +
    + if (info->secondary_capability != 0)
    + len += sprintf(page + len, "Secondary Capability: %d\n",
    + info->secondary_capability);
    + return len;
    +}
    +
    +static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len)
    +{
    + if (stsi(info, 2, 2, 2) == -ENOSYS)
    + return len;
    +
    + EBCASC(info->name, sizeof(info->name));
    +
    + len += sprintf(page + len, "\n");
    + len += sprintf(page + len, "LPAR Number: %d\n",
    + info->lpar_number);
    +
    + len += sprintf(page + len, "LPAR Characteristics: ");
    + if (info->characteristics & LPAR_CHAR_DEDICATED)
    + len += sprintf(page + len, "Dedicated ");
    + if (info->characteristics & LPAR_CHAR_SHARED)
    + len += sprintf(page + len, "Shared ");
    + if (info->characteristics & LPAR_CHAR_LIMITED)
    + len += sprintf(page + len, "Limited ");
    + len += sprintf(page + len, "\n");
    +
    + len += sprintf(page + len, "LPAR Name: %-8.8s\n",
    + info->name);
    +
    + len += sprintf(page + len, "LPAR Adjustment: %d\n",
    + info->caf);
    +
    + len += sprintf(page + len, "LPAR CPUs Total: %d\n",
    + info->cpus_total);
    + len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
    + info->cpus_configured);
    + len += sprintf(page + len, "LPAR CPUs Standby: %d\n",
    + info->cpus_standby);
    + len += sprintf(page + len, "LPAR CPUs Reserved: %d\n",
    + info->cpus_reserved);
    + len += sprintf(page + len, "LPAR CPUs Dedicated: %d\n",
    + info->cpus_dedicated);
    + len += sprintf(page + len, "LPAR CPUs Shared: %d\n",
    + info->cpus_shared);
    + return len;
    +}
    +
    +static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
    +{
    + int i;
    +
    + if (stsi(info, 3, 2, 2) == -ENOSYS)
    + return len;
    + for (i = 0; i < info->count; i++) {
    + EBCASC(info->vm[i].name, sizeof(info->vm[i].name));
    + EBCASC(info->vm[i].cpi, sizeof(info->vm[i].cpi));
    + len += sprintf(page + len, "\n");
    + len += sprintf(page + len, "VM%02d Name: %-8.8s\n",
    + i, info->vm[i].name);
    + len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n",
    + i, info->vm[i].cpi);
    +
    + len += sprintf(page + len, "VM%02d Adjustment: %d\n",
    + i, info->vm[i].caf);
    +
    + len += sprintf(page + len, "VM%02d CPUs Total: %d\n",
    + i, info->vm[i].cpus_total);
    + len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
    + i, info->vm[i].cpus_configured);
    + len += sprintf(page + len, "VM%02d CPUs Standby: %d\n",
    + i, info->vm[i].cpus_standby);
    + len += sprintf(page + len, "VM%02d CPUs Reserved: %d\n",
    + i, info->vm[i].cpus_reserved);
    + }
    + return len;
    +}
    +
    +static int proc_read_sysinfo(char *page, char **start,
    + off_t off, int count,
    + int *eof, void *data)
    +{
    + unsigned long info = get_zeroed_page(GFP_KERNEL);
    + int level, len;
    +
    + if (!info)
    + return 0;
    +
    + len = 0;
    + level = stsi_0();
    + if (level >= 1)
    + len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
    +
    + if (level >= 1)
    + len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
    +
    + if (level >= 2)
    + len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len);
    +
    + if (level >= 3)
    + len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
    +
    + free_page(info);
    + return len;
    +}
    +
    +static __init int create_proc_sysinfo(void)
    +{
    + create_proc_read_entry("sysinfo", 0444, NULL,
    + proc_read_sysinfo, NULL);
    + return 0;
    +}
    +device_initcall(create_proc_sysinfo);
    +
    +/*
    + * Service levels interface.
    + */
    +
    +static DECLARE_RWSEM(service_level_sem);
    +static LIST_HEAD(service_level_list);
    +
    +int register_service_level(struct service_level *slr)
    +{
    + struct service_level *ptr;
    +
    + down_write(&service_level_sem);
    + list_for_each_entry(ptr, &service_level_list, list)
    + if (ptr == slr) {
    + up_write(&service_level_sem);
    + return -EEXIST;
    + }
    + list_add_tail(&slr->list, &service_level_list);
    + up_write(&service_level_sem);
    + return 0;
    +}
    +EXPORT_SYMBOL(register_service_level);
    +
    +int unregister_service_level(struct service_level *slr)
    +{
    + struct service_level *ptr, *next;
    + int rc = -ENOENT;
    +
    + down_write(&service_level_sem);
    + list_for_each_entry_safe(ptr, next, &service_level_list, list) {
    + if (ptr != slr)
    + continue;
    + list_del(&ptr->list);
    + rc = 0;
    + break;
    + }
    + up_write(&service_level_sem);
    + return rc;
    +}
    +EXPORT_SYMBOL(unregister_service_level);
    +
    +static void *service_level_start(struct seq_file *m, loff_t *pos)
    +{
    + down_read(&service_level_sem);
    + return seq_list_start(&service_level_list, *pos);
    +}
    +
    +static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
    +{
    + return seq_list_next(p, &service_level_list, pos);
    +}
    +
    +static void service_level_stop(struct seq_file *m, void *p)
    +{
    + up_read(&service_level_sem);
    +}
    +
    +static int service_level_show(struct seq_file *m, void *p)
    +{
    + struct service_level *slr;
    +
    + slr = list_entry(p, struct service_level, list);
    + slr->seq_print(m, slr);
    + return 0;
    +}
    +
    +static const struct seq_operations service_level_seq_ops = {
    + .start = service_level_start,
    + .next = service_level_next,
    + .stop = service_level_stop,
    + .show = service_level_show
    +};
    +
    +static int service_level_open(struct inode *inode, struct file *file)
    +{
    + return seq_open(file, &service_level_seq_ops);
    +}
    +
    +static const struct file_operations service_level_ops = {
    + .open = service_level_open,
    + .read = seq_read,
    + .llseek = seq_lseek,
    + .release = seq_release
    +};
    +
    +static void service_level_vm_print(struct seq_file *m,
    + struct service_level *slr)
    +{
    + char *query_buffer, *str;
    +
    + query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
    + if (!query_buffer)
    + return;
    + cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
    + str = strchr(query_buffer, '\n');
    + if (str)
    + *str = 0;
    + seq_printf(m, "VM: %s\n", query_buffer);
    + kfree(query_buffer);
    +}
    +
    +static struct service_level service_level_vm = {
    + .seq_print = service_level_vm_print
    +};
    +
    +static __init int create_proc_service_level(void)
    +{
    + proc_create("service_levels", 0, NULL, &service_level_ops);
    + if (MACHINE_IS_VM)
    + register_service_level(&service_level_vm);
    + return 0;
    +}
    +subsys_initcall(create_proc_service_level);
    +
    +/*
    + * Bogomips calculation based on cpu capability.
    + */
    +int get_cpu_capability(unsigned int *capability)
    +{
    + struct sysinfo_1_2_2 *info;
    + int rc;
    +
    + info = (void *) get_zeroed_page(GFP_KERNEL);
    + if (!info)
    + return -ENOMEM;
    + rc = stsi(info, 1, 2, 2);
    + if (rc == -ENOSYS)
    + goto out;
    + rc = 0;
    + *capability = info->capability;
    +out:
    + free_page((unsigned long) info);
    + return rc;
    +}
    +
    +/*
    + * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
    + */
    +void s390_adjust_jiffies(void)
    +{
    + struct sysinfo_1_2_2 *info;
    + const unsigned int fmil = 0x4b189680; /* 1e7 as 32-bit float. */
    + FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
    + FP_DECL_EX;
    + unsigned int capability;
    +
    + info = (void *) get_zeroed_page(GFP_KERNEL);
    + if (!info)
    + return;
    +
    + if (stsi(info, 1, 2, 2) != -ENOSYS) {
    + /*
    + * Major sigh. The cpu capability encoding is "special".
    + * If the first 9 bits of info->capability are 0 then it
    + * is a 32 bit unsigned integer in the range 0 .. 2^23.
    + * If the first 9 bits are != 0 then it is a 32 bit float.
    + * In addition a lower value indicates a proportionally
    + * higher cpu capacity. Bogomips are the other way round.
    + * To get to a halfway suitable number we divide 1e7
    + * by the cpu capability number. Yes, that means a floating
    + * point division .. math-emu here we come :-)
    + */
    + FP_UNPACK_SP(SA, &fmil);
    + if ((info->capability >> 23) == 0)
    + FP_FROM_INT_S(SB, info->capability, 32, int);
    + else
    + FP_UNPACK_SP(SB, &info->capability);
    + FP_DIV_S(SR, SA, SB);
    + FP_TO_INT_S(capability, SR, 32, 0);
    + } else
    + /*
    + * Really old machine without stsi block for basic
    + * cpu information. Report 42.0 bogomips.
    + */
    + capability = 42;
    + loops_per_jiffy = capability * (500000/HZ);
    + free_page((unsigned long) info);
    +}
    +
    +/*
    + * calibrate the delay loop
    + */
    +void __cpuinit calibrate_delay(void)
    +{
    + s390_adjust_jiffies();
    + /* Print the good old Bogomips line .. */
    + printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
    + "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
    + (loops_per_jiffy/(5000/HZ)) % 100);
    +}
    Index: quilt-2.6/drivers/s390/Makefile
    ===================================================================
    --- quilt-2.6.orig/drivers/s390/Makefile
    +++ quilt-2.6/drivers/s390/Makefile
    @@ -2,9 +2,7 @@
    # Makefile for the S/390 specific device drivers
    #

    -CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
    -
    -obj-y += s390mach.o sysinfo.o
    +obj-y += s390mach.o
    obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/

    drivers-y += drivers/s390/built-in.o
    Index: quilt-2.6/drivers/s390/sysinfo.c
    ===================================================================
    --- quilt-2.6.orig/drivers/s390/sysinfo.c
    +++ /dev/null
    @@ -1,469 +0,0 @@
    -/*
    - * drivers/s390/sysinfo.c
    - *
    - * Copyright IBM Corp. 2001, 2008
    - * Author(s): Ulrich Weigand (Ulrich.Weigand@de.ibm.com)
    - * Martin Schwidefsky <schwidefsky@de.ibm.com>
    - */
    -
    -#include <linux/kernel.h>
    -#include <linux/mm.h>
    -#include <linux/proc_fs.h>
    -#include <linux/seq_file.h>
    -#include <linux/init.h>
    -#include <linux/delay.h>
    -#include <linux/module.h>
    -#include <asm/ebcdic.h>
    -#include <asm/sysinfo.h>
    -#include <asm/cpcmd.h>
    -
    -/* Sigh, math-emu. Don't ask. */
    -#include <asm/sfp-util.h>
    -#include <math-emu/soft-fp.h>
    -#include <math-emu/single.h>
    -
    -static inline int stsi_0(void)
    -{
    - int rc = stsi (NULL, 0, 0, 0);
    - return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
    -}
    -
    -static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
    -{
    - if (stsi(info, 1, 1, 1) == -ENOSYS)
    - return len;
    -
    - EBCASC(info->manufacturer, sizeof(info->manufacturer));
    - EBCASC(info->type, sizeof(info->type));
    - EBCASC(info->model, sizeof(info->model));
    - EBCASC(info->sequence, sizeof(info->sequence));
    - EBCASC(info->plant, sizeof(info->plant));
    - EBCASC(info->model_capacity, sizeof(info->model_capacity));
    - EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
    - EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
    - len += sprintf(page + len, "Manufacturer: %-16.16s\n",
    - info->manufacturer);
    - len += sprintf(page + len, "Type: %-4.4s\n",
    - info->type);
    - if (info->model[0] != '\0')
    - /*
    - * Sigh: the model field has been renamed with System z9
    - * to model_capacity and a new model field has been added
    - * after the plant field. To avoid confusing older programs
    - * the "Model:" prints "model_capacity model" or just
    - * "model_capacity" if the model string is empty .
    - */
    - len += sprintf(page + len,
    - "Model: %-16.16s %-16.16s\n",
    - info->model_capacity, info->model);
    - else
    - len += sprintf(page + len, "Model: %-16.16s\n",
    - info->model_capacity);
    - len += sprintf(page + len, "Sequence Code: %-16.16s\n",
    - info->sequence);
    - len += sprintf(page + len, "Plant: %-4.4s\n",
    - info->plant);
    - len += sprintf(page + len, "Model Capacity: %-16.16s %08u\n",
    - info->model_capacity, *(u32 *) info->model_cap_rating);
    - if (info->model_perm_cap[0] != '\0')
    - len += sprintf(page + len,
    - "Model Perm. Capacity: %-16.16s %08u\n",
    - info->model_perm_cap,
    - *(u32 *) info->model_perm_cap_rating);
    - if (info->model_temp_cap[0] != '\0')
    - len += sprintf(page + len,
    - "Model Temp. Capacity: %-16.16s %08u\n",
    - info->model_temp_cap,
    - *(u32 *) info->model_temp_cap_rating);
    - return len;
    -}
    -
    -#if 0 /* Currently unused */
    -static int stsi_1_2_1(struct sysinfo_1_2_1 *info, char *page, int len)
    -{
    - if (stsi(info, 1, 2, 1) == -ENOSYS)
    - return len;
    -
    - len += sprintf(page + len, "\n");
    - EBCASC(info->sequence, sizeof(info->sequence));
    - EBCASC(info->plant, sizeof(info->plant));
    - len += sprintf(page + len, "Sequence Code of CPU: %-16.16s\n",
    - info->sequence);
    - len += sprintf(page + len, "Plant of CPU: %-16.16s\n",
    - info->plant);
    - return len;
    -}
    -#endif
    -
    -static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
    -{
    - struct sysinfo_1_2_2_extension *ext;
    - int i;
    -
    - if (stsi(info, 1, 2, 2) == -ENOSYS)
    - return len;
    - ext = (struct sysinfo_1_2_2_extension *)
    - ((unsigned long) info + info->acc_offset);
    -
    - len += sprintf(page + len, "\n");
    - len += sprintf(page + len, "CPUs Total: %d\n",
    - info->cpus_total);
    - len += sprintf(page + len, "CPUs Configured: %d\n",
    - info->cpus_configured);
    - len += sprintf(page + len, "CPUs Standby: %d\n",
    - info->cpus_standby);
    - len += sprintf(page + len, "CPUs Reserved: %d\n",
    - info->cpus_reserved);
    -
    - if (info->format == 1) {
    - /*
    - * Sigh 2. According to the specification the alternate
    - * capability field is a 32 bit floating point number
    - * if the higher order 8 bits are not zero. Printing
    - * a floating point number in the kernel is a no-no,
    - * always print the number as 32 bit unsigned integer.
    - * The user-space needs to know about the strange
    - * encoding of the alternate cpu capability.
    - */
    - len += sprintf(page + len, "Capability: %u %u\n",
    - info->capability, ext->alt_capability);
    - for (i = 2; i <= info->cpus_total; i++)
    - len += sprintf(page + len,
    - "Adjustment %02d-way: %u %u\n",
    - i, info->adjustment[i-2],
    - ext->alt_adjustment[i-2]);
    -
    - } else {
    - len += sprintf(page + len, "Capability: %u\n",
    - info->capability);
    - for (i = 2; i <= info->cpus_total; i++)
    - len += sprintf(page + len,
    - "Adjustment %02d-way: %u\n",
    - i, info->adjustment[i-2]);
    - }
    -
    - if (info->secondary_capability != 0)
    - len += sprintf(page + len, "Secondary Capability: %d\n",
    - info->secondary_capability);
    -
    - return len;
    -}
    -
    -#if 0 /* Currently unused */
    -static int stsi_2_2_1(struct sysinfo_2_2_1 *info, char *page, int len)
    -{
    - if (stsi(info, 2, 2, 1) == -ENOSYS)
    - return len;
    -
    - len += sprintf(page + len, "\n");
    - EBCASC (info->sequence, sizeof(info->sequence));
    - EBCASC (info->plant, sizeof(info->plant));
    - len += sprintf(page + len, "Sequence Code of logical CPU: %-16.16s\n",
    - info->sequence);
    - len += sprintf(page + len, "Plant of logical CPU: %-16.16s\n",
    - info->plant);
    - return len;
    -}
    -#endif
    -
    -static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len)
    -{
    - if (stsi(info, 2, 2, 2) == -ENOSYS)
    - return len;
    -
    - EBCASC (info->name, sizeof(info->name));
    -
    - len += sprintf(page + len, "\n");
    - len += sprintf(page + len, "LPAR Number: %d\n",
    - info->lpar_number);
    -
    - len += sprintf(page + len, "LPAR Characteristics: ");
    - if (info->characteristics & LPAR_CHAR_DEDICATED)
    - len += sprintf(page + len, "Dedicated ");
    - if (info->characteristics & LPAR_CHAR_SHARED)
    - len += sprintf(page + len, "Shared ");
    - if (info->characteristics & LPAR_CHAR_LIMITED)
    - len += sprintf(page + len, "Limited ");
    - len += sprintf(page + len, "\n");
    -
    - len += sprintf(page + len, "LPAR Name: %-8.8s\n",
    - info->name);
    -
    - len += sprintf(page + len, "LPAR Adjustment: %d\n",
    - info->caf);
    -
    - len += sprintf(page + len, "LPAR CPUs Total: %d\n",
    - info->cpus_total);
    - len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
    - info->cpus_configured);
    - len += sprintf(page + len, "LPAR CPUs Standby: %d\n",
    - info->cpus_standby);
    - len += sprintf(page + len, "LPAR CPUs Reserved: %d\n",
    - info->cpus_reserved);
    - len += sprintf(page + len, "LPAR CPUs Dedicated: %d\n",
    - info->cpus_dedicated);
    - len += sprintf(page + len, "LPAR CPUs Shared: %d\n",
    - info->cpus_shared);
    - return len;
    -}
    -
    -static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
    -{
    - int i;
    -
    - if (stsi(info, 3, 2, 2) == -ENOSYS)
    - return len;
    - for (i = 0; i < info->count; i++) {
    - EBCASC (info->vm[i].name, sizeof(info->vm[i].name));
    - EBCASC (info->vm[i].cpi, sizeof(info->vm[i].cpi));
    - len += sprintf(page + len, "\n");
    - len += sprintf(page + len, "VM%02d Name: %-8.8s\n",
    - i, info->vm[i].name);
    - len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n",
    - i, info->vm[i].cpi);
    -
    - len += sprintf(page + len, "VM%02d Adjustment: %d\n",
    - i, info->vm[i].caf);
    -
    - len += sprintf(page + len, "VM%02d CPUs Total: %d\n",
    - i, info->vm[i].cpus_total);
    - len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
    - i, info->vm[i].cpus_configured);
    - len += sprintf(page + len, "VM%02d CPUs Standby: %d\n",
    - i, info->vm[i].cpus_standby);
    - len += sprintf(page + len, "VM%02d CPUs Reserved: %d\n",
    - i, info->vm[i].cpus_reserved);
    - }
    - return len;
    -}
    -
    -
    -static int proc_read_sysinfo(char *page, char **start,
    - off_t off, int count,
    - int *eof, void *data)
    -{
    - unsigned long info = get_zeroed_page (GFP_KERNEL);
    - int level, len;
    -
    - if (!info)
    - return 0;
    -
    - len = 0;
    - level = stsi_0();
    - if (level >= 1)
    - len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
    -
    - if (level >= 1)
    - len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
    -
    - if (level >= 2)
    - len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len);
    -
    - if (level >= 3)
    - len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
    -
    - free_page (info);
    - return len;
    -}
    -
    -static __init int create_proc_sysinfo(void)
    -{
    - create_proc_read_entry("sysinfo", 0444, NULL,
    - proc_read_sysinfo, NULL);
    - return 0;
    -}
    -
    -__initcall(create_proc_sysinfo);
    -
    -/*
    - * Service levels interface.
    - */
    -
    -static DECLARE_RWSEM(service_level_sem);
    -static LIST_HEAD(service_level_list);
    -
    -int register_service_level(struct service_level *slr)
    -{
    - struct service_level *ptr;
    -
    - down_write(&service_level_sem);
    - list_for_each_entry(ptr, &service_level_list, list)
    - if (ptr == slr) {
    - up_write(&service_level_sem);
    - return -EEXIST;
    - }
    - list_add_tail(&slr->list, &service_level_list);
    - up_write(&service_level_sem);
    - return 0;
    -}
    -EXPORT_SYMBOL(register_service_level);
    -
    -int unregister_service_level(struct service_level *slr)
    -{
    - struct service_level *ptr, *next;
    - int rc = -ENOENT;
    -
    - down_write(&service_level_sem);
    - list_for_each_entry_safe(ptr, next, &service_level_list, list) {
    - if (ptr != slr)
    - continue;
    - list_del(&ptr->list);
    - rc = 0;
    - break;
    - }
    - up_write(&service_level_sem);
    - return rc;
    -}
    -EXPORT_SYMBOL(unregister_service_level);
    -
    -static void *service_level_start(struct seq_file *m, loff_t *pos)
    -{
    - down_read(&service_level_sem);
    - return seq_list_start(&service_level_list, *pos);
    -}
    -
    -static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
    -{
    - return seq_list_next(p, &service_level_list, pos);
    -}
    -
    -static void service_level_stop(struct seq_file *m, void *p)
    -{
    - up_read(&service_level_sem);
    -}
    -
    -static int service_level_show(struct seq_file *m, void *p)
    -{
    - struct service_level *slr;
    -
    - slr = list_entry(p, struct service_level, list);
    - slr->seq_print(m, slr);
    - return 0;
    -}
    -
    -static const struct seq_operations service_level_seq_ops = {
    - .start = service_level_start,
    - .next = service_level_next,
    - .stop = service_level_stop,
    - .show = service_level_show
    -};
    -
    -static int service_level_open(struct inode *inode, struct file *file)
    -{
    - return seq_open(file, &service_level_seq_ops);
    -}
    -
    -static const struct file_operations service_level_ops = {
    - .open = service_level_open,
    - .read = seq_read,
    - .llseek = seq_lseek,
    - .release = seq_release
    -};
    -
    -static void service_level_vm_print(struct seq_file *m,
    - struct service_level *slr)
    -{
    - char *query_buffer, *str;
    -
    - query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
    - if (!query_buffer)
    - return;
    - cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
    - str = strchr(query_buffer, '\n');
    - if (str)
    - *str = 0;
    - seq_printf(m, "VM: %s\n", query_buffer);
    - kfree(query_buffer);
    -}
    -
    -static struct service_level service_level_vm = {
    - .seq_print = service_level_vm_print
    -};
    -
    -static __init int create_proc_service_level(void)
    -{
    - proc_create("service_levels", 0, NULL, &service_level_ops);
    - if (MACHINE_IS_VM)
    - register_service_level(&service_level_vm);
    - return 0;
    -}
    -
    -subsys_initcall(create_proc_service_level);
    -
    -/*
    - * Bogomips calculation based on cpu capability.
    - */
    -
    -int get_cpu_capability(unsigned int *capability)
    -{
    - struct sysinfo_1_2_2 *info;
    - int rc;
    -
    - info = (void *) get_zeroed_page(GFP_KERNEL);
    - if (!info)
    - return -ENOMEM;
    - rc = stsi(info, 1, 2, 2);
    - if (rc == -ENOSYS)
    - goto out;
    - rc = 0;
    - *capability = info->capability;
    -out:
    - free_page((unsigned long) info);
    - return rc;
    -}
    -
    -/*
    - * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
    - */
    -void s390_adjust_jiffies(void)
    -{
    - struct sysinfo_1_2_2 *info;
    - const unsigned int fmil = 0x4b189680; /* 1e7 as 32-bit float. */
    - FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
    - FP_DECL_EX;
    - unsigned int capability;
    -
    - info = (void *) get_zeroed_page(GFP_KERNEL);
    - if (!info)
    - return;
    -
    - if (stsi(info, 1, 2, 2) != -ENOSYS) {
    - /*
    - * Major sigh. The cpu capability encoding is "special".
    - * If the first 9 bits of info->capability are 0 then it
    - * is a 32 bit unsigned integer in the range 0 .. 2^23.
    - * If the first 9 bits are != 0 then it is a 32 bit float.
    - * In addition a lower value indicates a proportionally
    - * higher cpu capacity. Bogomips are the other way round.
    - * To get to a halfway suitable number we divide 1e7
    - * by the cpu capability number. Yes, that means a floating
    - * point division .. math-emu here we come :-)
    - */
    - FP_UNPACK_SP(SA, &fmil);
    - if ((info->capability >> 23) == 0)
    - FP_FROM_INT_S(SB, info->capability, 32, int);
    - else
    - FP_UNPACK_SP(SB, &info->capability);
    - FP_DIV_S(SR, SA, SB);
    - FP_TO_INT_S(capability, SR, 32, 0);
    - } else
    - /*
    - * Really old machine without stsi block for basic
    - * cpu information. Report 42.0 bogomips.
    - */
    - capability = 42;
    - loops_per_jiffy = capability * (500000/HZ);
    - free_page((unsigned long) info);
    -}
    -
    -/*
    - * calibrate the delay loop
    - */
    -void __cpuinit calibrate_delay(void)
    -{
    - s390_adjust_jiffies();
    - /* Print the good old Bogomips line .. */
    - printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
    - "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
    - (loops_per_jiffy/(5000/HZ)) % 100);
    -}
    --
    blue skies,
    Martin.

    "Reality continues to ruin my life." - Calvin.



    \
     
     \ /
      Last update: 2009-02-25 16:25    [W:0.077 / U:30.232 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site