X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fia64%2Fsn%2Fkernel%2Fsn2%2Fprominfo_proc.c;h=4dcce3d0e04ca1c9bc0e10d10cf4d7fcab6f7723;hb=refs%2Fheads%2Fvserver;hp=32db72ae751c3f33f2e79f95ebe53963a6fd605c;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c index 32db72ae7..4dcce3d0e 100644 --- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c +++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c @@ -3,20 +3,20 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1999,2001-2004, 2006 Silicon Graphics, Inc. All Rights Reserved. * * Module to export the system's Firmware Interface Tables, including * PROM revision numbers and banners, in /proc */ -#include #include #include #include +#include #include #include #include #include -#include +#include MODULE_DESCRIPTION("PROM version reporting for /proc"); MODULE_AUTHOR("Chad Talbott"); @@ -55,30 +55,29 @@ MODULE_LICENSE("GPL"); ((unsigned) ((q) >> FIT_TYPE_SHIFT) & FIT_TYPE_MASK) struct fit_type_map_t { - unsigned char type; - const char *name; + unsigned char type; + const char *name; }; static const struct fit_type_map_t fit_entry_types[] = { - { FIT_ENTRY_FIT_HEADER, "FIT Header" }, - { FIT_ENTRY_PAL_A_GEN, "Generic PAL_A" }, - { FIT_ENTRY_PAL_A_PROC, "Processor-specific PAL_A" }, - { FIT_ENTRY_PAL_A, "PAL_A" }, - { FIT_ENTRY_PAL_B, "PAL_B" }, - { FIT_ENTRY_SAL_A, "SAL_A" }, - { FIT_ENTRY_SAL_B, "SAL_B" }, - { FIT_ENTRY_SALRUNTIME, "SAL runtime" }, - { FIT_ENTRY_EFI, "EFI" }, - { FIT_ENTRY_VMLINUX, "Embedded Linux" }, - { FIT_ENTRY_FPSWA, "Embedded FPSWA" }, - { FIT_ENTRY_UNUSED, "Unused" }, - { 0xff, "Error" }, + {FIT_ENTRY_FIT_HEADER, "FIT Header"}, + {FIT_ENTRY_PAL_A_GEN, "Generic PAL_A"}, + {FIT_ENTRY_PAL_A_PROC, "Processor-specific PAL_A"}, + {FIT_ENTRY_PAL_A, "PAL_A"}, + {FIT_ENTRY_PAL_B, "PAL_B"}, + {FIT_ENTRY_SAL_A, "SAL_A"}, + {FIT_ENTRY_SAL_B, "SAL_B"}, + {FIT_ENTRY_SALRUNTIME, "SAL runtime"}, + {FIT_ENTRY_EFI, "EFI"}, + {FIT_ENTRY_VMLINUX, "Embedded Linux"}, + {FIT_ENTRY_FPSWA, "Embedded FPSWA"}, + {FIT_ENTRY_UNUSED, "Unused"}, + {0xff, "Error"}, }; -static const char * -fit_type_name(unsigned char type) +static const char *fit_type_name(unsigned char type) { - struct fit_type_map_t const*mapp; + struct fit_type_map_t const *mapp; for (mapp = fit_entry_types; mapp->type != 0xff; mapp++) if (type == mapp->type) @@ -92,132 +91,18 @@ fit_type_name(unsigned char type) return "Unknown type"; } - -/* ============ BEGIN temp til old PROMs are no longer supported ============= - * - * The OS should not make direct access to the PROM flash memory. Access to - * this region must be serialized with a PROM lock. If SAL on one cpu is - * updating the FLASH error log at the same time another cpu is accessing the - * PROM, data corruption will occur. - * - * To solve the problem, all flash PROM access has been moved to SAL. Because - * not all systems will have instant PROM updates, we need to support a new OS - * running on a system with old PROMs. - * - * This code should be deleted after 1 OS/PROM release has occurred & the OS - * no longer supports downrev PROMs. (PROM support should be in the 3.50 - * PROMs). - */ -#define SUPPORT_OLD_PROMS -#ifdef SUPPORT_OLD_PROMS - - -#define FIT_SIGNATURE 0x2020205f5449465ful - -/* Sub-regions determined by bits in Node Offset */ -#define LB_PROM_SPACE 0x0000000700000000ul /* Local LB PROM */ - -/* Offset of PROM banner pointers in SAL A and SAL B */ -#define SAL_A_BANNER_OFFSET (1 * 16) -#define SAL_B_BANNER_OFFSET (3 * 16) - -/* Architected IA64 firmware space */ -#define FW_BASE 0x00000000FF000000 -#define FW_TOP 0x0000000100000000 - -static unsigned long -convert_fw_addr(nasid_t nasid, unsigned long addr) -{ - /* snag just the node-relative offset */ - addr &= ~0ul >> (63-35); - /* the pointer to SAL A is relative to IA-64 compatibility - * space. However, the PROM is mapped at a different offset - * in MMR space (both local and global) - */ - addr += 0x700000000; - return GLOBAL_MMR_ADDR(nasid, addr); -} - -static int -valid_fw_addr(unsigned long addr) -{ - addr &= ~(1ul << 63); /* Clear cached/uncached bit */ - return (addr >= FW_BASE && addr < FW_TOP); -} - -static unsigned long * -lookup_fit(int nasid) -{ - unsigned long *fitp; - unsigned long fit_paddr; - unsigned long *fit_vaddr; - - fitp = (void *)GLOBAL_MMR_ADDR(nasid, LB_PROM_SPACE - 32); - fit_paddr = readq(fitp); - fit_vaddr = (unsigned long *) convert_fw_addr(nasid, fit_paddr); - return fit_vaddr; -} -#endif /* SUPPORT_OLD_PROMS */ -/* ============ END temp til old PROMs are no longer supported ============= */ - static int get_fit_entry(unsigned long nasid, int index, unsigned long *fentry, char *banner, int banlen) { - int ret; - - ret = ia64_sn_get_fit_compt(nasid, index, fentry, banner, banlen); - -#ifdef SUPPORT_OLD_PROMS - /* The following is hack is temporary until PROMs are updated */ - if (ret == SALRET_NOT_IMPLEMENTED) { - unsigned long *fitadr = lookup_fit(nasid); - int nentries; - - if (readq(fitadr) != FIT_SIGNATURE) { - printk(KERN_WARNING "Unrecognized FIT signature"); - return -2; - } - - nentries = (unsigned int) (readq(fitadr + 1) & 0xffffff); - if (index >= nentries) - return -2; - - fentry[0] = readq(fitadr + 2 * index); - fentry[1] = readq(fitadr + 2 * index + 1); - ret = 0; - - if (banner && FIT_TYPE(fentry[1]) == FIT_ENTRY_SAL_A) { - unsigned long i, qw, *bwp, *qwp; - - banner[0] = '\0'; - qw = fentry[0]; /* Address of SAL A */ - if (!valid_fw_addr(qw)) - return 0; - - qw += SAL_A_BANNER_OFFSET; - qw = convert_fw_addr(nasid, qw); - - qw = readq(qw); /* Address of banner */ - if (!valid_fw_addr(qw)) - return 0; - qw = convert_fw_addr(nasid, qw); - qwp = (unsigned long *) qw; - bwp = (unsigned long *) banner; - for (i=0; icount) len = count; - if (len<0) len = 0; + if (len > count) + len = count; + if (len < 0) + len = 0; return len; } @@ -301,7 +189,7 @@ static int read_version_entry(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len = 0; + int len; /* data holds the NASID of the node */ len = dump_version(page, (unsigned long)data); @@ -313,7 +201,7 @@ static int read_fit_entry(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len = 0; + int len; /* data holds the NASID of the node */ len = dump_fit(page, (unsigned long)data); @@ -334,58 +222,57 @@ static struct proc_dir_entry *sgi_prominfo_entry; #define NODE_NAME_LEN 11 -int __init -prominfo_init(void) +int __init prominfo_init(void) { struct proc_dir_entry **entp; struct proc_dir_entry *p; cnodeid_t cnodeid; unsigned long nasid; + int size; char name[NODE_NAME_LEN]; if (!ia64_platform_is("sn2")) return 0; - proc_entries = kmalloc(numnodes * sizeof(struct proc_dir_entry *), - GFP_KERNEL); + size = num_online_nodes() * sizeof(struct proc_dir_entry *); + proc_entries = kzalloc(size, GFP_KERNEL); + if (!proc_entries) + return -ENOMEM; sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL); - for (cnodeid = 0, entp = proc_entries; - cnodeid < numnodes; - cnodeid++, entp++) { + entp = proc_entries; + for_each_online_node(cnodeid) { sprintf(name, "node%d", cnodeid); *entp = proc_mkdir(name, sgi_prominfo_entry); nasid = cnodeid_to_nasid(cnodeid); - p = create_proc_read_entry( - "fit", 0, *entp, read_fit_entry, - (void *)nasid); + p = create_proc_read_entry("fit", 0, *entp, read_fit_entry, + (void *)nasid); if (p) p->owner = THIS_MODULE; - p = create_proc_read_entry( - "version", 0, *entp, read_version_entry, - (void *)nasid); + p = create_proc_read_entry("version", 0, *entp, + read_version_entry, (void *)nasid); if (p) p->owner = THIS_MODULE; + entp++; } return 0; } -void __exit -prominfo_exit(void) +void __exit prominfo_exit(void) { struct proc_dir_entry **entp; - unsigned cnodeid; + unsigned int cnodeid; char name[NODE_NAME_LEN]; - for (cnodeid = 0, entp = proc_entries; - cnodeid < numnodes; - cnodeid++, entp++) { + entp = proc_entries; + for_each_online_node(cnodeid) { remove_proc_entry("fit", *entp); remove_proc_entry("version", *entp); sprintf(name, "node%d", cnodeid); remove_proc_entry(name, sgi_prominfo_entry); + entp++; } remove_proc_entry("sgi_prominfo", NULL); kfree(proc_entries);