Commit 854631be authored by Jesse Barnes's avatar Jesse Barnes Committed by David Mosberger

[PATCH] ia64: SN cleanups

Some patches from hch@infradead.org cleaning up sn2 code a bit,
including the removal of some unnecessary files.
parent a4b54490
...@@ -63,7 +63,7 @@ config IA64_GENERIC ...@@ -63,7 +63,7 @@ config IA64_GENERIC
HP-simulator For the HP simulator HP-simulator For the HP simulator
(<http://software.hp.com/ia64linux/>). (<http://software.hp.com/ia64linux/>).
HP-zx1 For HP zx1-based systems. HP-zx1 For HP zx1-based systems.
SN1-simulator For the SGI SN1 simulator. SGI-SN2 For SGI Altix systems
DIG-compliant For DIG ("Developer's Interface Guide") compliant DIG-compliant For DIG ("Developer's Interface Guide") compliant
systems. systems.
...@@ -187,8 +187,8 @@ config ITANIUM_BSTEP_SPECIFIC ...@@ -187,8 +187,8 @@ config ITANIUM_BSTEP_SPECIFIC
# align cache-sensitive data to 128 bytes # align cache-sensitive data to 128 bytes
config IA64_L1_CACHE_SHIFT config IA64_L1_CACHE_SHIFT
int int
default "7" if MCKINLEY || ITANIUM && IA64_SGI_SN1 default "7" if MCKINLEY
default "6" if ITANIUM && !IA64_SGI_SN1 default "6" if ITANIUM
# align cache-sensitive data to 64 bytes # align cache-sensitive data to 64 bytes
config MCKINLEY_ASTEP_SPECIFIC config MCKINLEY_ASTEP_SPECIFIC
...@@ -207,7 +207,7 @@ config MCKINLEY_A0_SPECIFIC ...@@ -207,7 +207,7 @@ config MCKINLEY_A0_SPECIFIC
config NUMA config NUMA
bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
default y if IA64_SGI_SN1 || IA64_SGI_SN2 default y if IA64_SGI_SN2
help help
Say Y to compile the kernel to support NUMA (Non-Uniform Memory Say Y to compile the kernel to support NUMA (Non-Uniform Memory
Access). This option is for configuring high-end multiprocessor Access). This option is for configuring high-end multiprocessor
...@@ -231,7 +231,7 @@ endchoice ...@@ -231,7 +231,7 @@ endchoice
config DISCONTIGMEM config DISCONTIGMEM
bool bool
depends on IA64_SGI_SN1 || IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA
default y default y
help help
Say Y to support efficient handling of discontiguous physical memory, Say Y to support efficient handling of discontiguous physical memory,
...@@ -256,7 +256,7 @@ config VIRTUAL_MEM_MAP ...@@ -256,7 +256,7 @@ config VIRTUAL_MEM_MAP
config IA64_MCA config IA64_MCA
bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
default y if IA64_SGI_SN1 || IA64_SGI_SN2 default y if IA64_SGI_SN2
help help
Say Y here to enable machine check support for IA-64. If you're Say Y here to enable machine check support for IA-64. If you're
unsure, answer Y. unsure, answer Y.
...@@ -290,17 +290,17 @@ config IOSAPIC ...@@ -290,17 +290,17 @@ config IOSAPIC
config IA64_SGI_SN config IA64_SGI_SN
bool bool
depends on IA64_SGI_SN1 || IA64_SGI_SN2 depends on IA64_SGI_SN2
default y default y
config HWGFS_FS config HWGFS_FS
bool bool
depends on IA64_SGI_SN1 || IA64_SGI_SN2 depends on IA64_SGI_SN2
default y default y
config IA64_SGI_SN_DEBUG config IA64_SGI_SN_DEBUG
bool "Enable extra debugging code" bool "Enable extra debugging code"
depends on IA64_SGI_SN1 || IA64_SGI_SN2 depends on IA64_SGI_SN2
help help
Turns on extra debugging code in the SGI SN (Scalable NUMA) platform Turns on extra debugging code in the SGI SN (Scalable NUMA) platform
for IA-64. Unless you are debugging problems on an SGI SN IA-64 box, for IA-64. Unless you are debugging problems on an SGI SN IA-64 box,
...@@ -308,14 +308,14 @@ config IA64_SGI_SN_DEBUG ...@@ -308,14 +308,14 @@ config IA64_SGI_SN_DEBUG
config IA64_SGI_SN_SIM config IA64_SGI_SN_SIM
bool "Enable SGI Medusa Simulator Support" bool "Enable SGI Medusa Simulator Support"
depends on IA64_SGI_SN1 || IA64_SGI_SN2 depends on IA64_SGI_SN2
help help
If you are compiling a kernel that will run under SGI's IA-64 If you are compiling a kernel that will run under SGI's IA-64
simulator (Medusa) then say Y, otherwise say N. simulator (Medusa) then say Y, otherwise say N.
config IA64_SGI_AUTOTEST config IA64_SGI_AUTOTEST
bool "Enable autotest (llsc). Option to run cache test instead of booting" bool "Enable autotest (llsc). Option to run cache test instead of booting"
depends on IA64_SGI_SN1 || IA64_SGI_SN2 depends on IA64_SGI_SN2
help help
Build a kernel used for hardware validation. If you include the Build a kernel used for hardware validation. If you include the
keyword "autotest" on the boot command line, the kernel does NOT boot. keyword "autotest" on the boot command line, the kernel does NOT boot.
...@@ -325,7 +325,7 @@ config IA64_SGI_AUTOTEST ...@@ -325,7 +325,7 @@ config IA64_SGI_AUTOTEST
config SERIAL_SGI_L1_PROTOCOL config SERIAL_SGI_L1_PROTOCOL
bool "Enable protocol mode for the L1 console" bool "Enable protocol mode for the L1 console"
depends on IA64_SGI_SN1 || IA64_SGI_SN2 depends on IA64_SGI_SN2
help help
Uses protocol mode instead of raw mode for the level 1 console on the Uses protocol mode instead of raw mode for the level 1 console on the
SGI SN (Scalable NUMA) platform for IA-64. If you are compiling for SGI SN (Scalable NUMA) platform for IA-64. If you are compiling for
...@@ -333,12 +333,12 @@ config SERIAL_SGI_L1_PROTOCOL ...@@ -333,12 +333,12 @@ config SERIAL_SGI_L1_PROTOCOL
config PERCPU_IRQ config PERCPU_IRQ
bool bool
depends on IA64_SGI_SN1 || IA64_SGI_SN2 depends on IA64_SGI_SN2
default y default y
config PCIBA config PCIBA
tristate "PCIBA support" tristate "PCIBA support"
depends on IA64_SGI_SN1 || IA64_SGI_SN2 depends on IA64_SGI_SN2
help help
IRIX PCIBA-inspired user mode PCI interface for the SGI SN (Scalable IRIX PCIBA-inspired user mode PCI interface for the SGI SN (Scalable
NUMA) platform for IA-64. Unless you are compiling a kernel for an NUMA) platform for IA-64. Unless you are compiling a kernel for an
......
...@@ -11,13 +11,5 @@ ...@@ -11,13 +11,5 @@
EXTRA_CFLAGS := -DLITTLE_ENDIAN -DSHUB_SWAP_WAR EXTRA_CFLAGS := -DLITTLE_ENDIAN -DSHUB_SWAP_WAR
obj-$(CONFIG_IA64_SGI_SN) += sgi_if.o xswitch.o sgi_io_sim.o cdl.o ate_utils.o \ obj-y += sgi_if.o xswitch.o sgi_io_sim.o cdl.o ate_utils.o \
io.o machvec/ drivers/ platform_init/ io.o machvec/ drivers/ platform_init/ sn2/ hwgfs/
\ No newline at end of file
obj-$(CONFIG_IA64_SGI_SN2) += sn2/
ifdef CONFIG_HWGFS_FS
obj-$(CONFIG_HWGFS_FS) += hwgfs/
else
obj-$(CONFIG_DEVFS_FS) += hwgdfs/
endif
...@@ -9,6 +9,6 @@ ...@@ -9,6 +9,6 @@
EXTRA_CFLAGS := -DLITTLE_ENDIAN EXTRA_CFLAGS := -DLITTLE_ENDIAN
obj-y += hubdev.o ioconfig_bus.o ifconfig_net.o obj-y += ioconfig_bus.o ifconfig_net.o
obj-$(CONFIG_PCIBA) += pciba.o obj-$(CONFIG_PCIBA) += pciba.o
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <asm/sn/sgi.h>
#include <asm/sn/io.h>
#include <asm/sn/iograph.h>
#include <asm/sn/sn_private.h>
#include <asm/sn/invent.h>
#include <asm/sn/hcl.h>
#include <asm/sn/labelcl.h>
struct hubdev_callout {
int (*attach_method)(vertex_hdl_t);
struct hubdev_callout *fp;
};
typedef struct hubdev_callout hubdev_callout_t;
mutex_t hubdev_callout_mutex;
static hubdev_callout_t *hubdev_callout_list;
void
hubdev_init(void)
{
mutex_init(&hubdev_callout_mutex);
hubdev_callout_list = NULL;
}
void
hubdev_register(int (*attach_method)(vertex_hdl_t))
{
hubdev_callout_t *callout;
ASSERT(attach_method);
callout = (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
ASSERT(callout);
mutex_lock(&hubdev_callout_mutex);
/*
* Insert at the end of the list
*/
callout->fp = hubdev_callout_list;
hubdev_callout_list = callout;
callout->attach_method = attach_method;
mutex_unlock(&hubdev_callout_mutex);
}
int
hubdev_unregister(int (*attach_method)(vertex_hdl_t))
{
hubdev_callout_t **p;
ASSERT(attach_method);
mutex_lock(&hubdev_callout_mutex);
/*
* Remove registry element containing attach_method
*/
for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) {
if ((*p)->attach_method == attach_method) {
hubdev_callout_t* victim = *p;
*p = (*p)->fp;
kfree(victim);
mutex_unlock(&hubdev_callout_mutex);
return (0);
}
}
mutex_unlock(&hubdev_callout_mutex);
return (ENOENT);
}
int
hubdev_docallouts(vertex_hdl_t hub)
{
hubdev_callout_t *p;
int errcode;
mutex_lock(&hubdev_callout_mutex);
for (p = hubdev_callout_list; p != NULL; p = p->fp) {
ASSERT(p->attach_method);
errcode = (*p->attach_method)(hub);
if (errcode != 0) {
mutex_unlock(&hubdev_callout_mutex);
return (errcode);
}
}
mutex_unlock(&hubdev_callout_mutex);
return (0);
}
...@@ -284,7 +284,7 @@ int __init init_ifconfig_net(void) ...@@ -284,7 +284,7 @@ int __init init_ifconfig_net(void)
{ {
ifconfig_net_handle = NULL; ifconfig_net_handle = NULL;
ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net", ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
0, DEVFS_FL_AUTO_DEVNUM, 0, 0,
0, 0, 0, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
&ifconfig_net_fops, NULL); &ifconfig_net_fops, NULL);
......
...@@ -361,7 +361,7 @@ int init_ioconfig_bus(void) ...@@ -361,7 +361,7 @@ int init_ioconfig_bus(void)
{ {
ioconfig_bus_handle = NULL; ioconfig_bus_handle = NULL;
ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus", ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",
0, DEVFS_FL_AUTO_DEVNUM, 0, 0,
0, 0, 0, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
&ioconfig_bus_fops, NULL); &ioconfig_bus_fops, NULL);
......
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 2002-2003 Silicon Graphics, Inc. All Rights Reserved.
#
# Makefile for the sn2 io routines.
EXTRA_CFLAGS := -DLITTLE_ENDIAN
obj-y += hcl.o labelcl.o hcl_util.o invent_stub.o
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* hcl - SGI's Hardware Graph compatibility layer.
*
* Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/types.h>
#include <linux/config.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/sn/sgi.h>
#include <linux/devfs_fs.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/io.h>
#include <asm/sn/iograph.h>
#include <asm/sn/invent.h>
#include <asm/sn/hcl.h>
#include <asm/sn/labelcl.h>
#include <asm/sn/simulator.h>
#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
#define HCL_TEMP_NAME_LEN 44
#define HCL_VERSION "1.0"
vertex_hdl_t hwgraph_root;
vertex_hdl_t linux_busnum;
extern void pci_bus_cvlink_init(void);
/*
* Debug flag definition.
*/
#define OPTION_NONE 0x00
#define HCL_DEBUG_NONE 0x00000
#define HCL_DEBUG_ALL 0x0ffff
#if defined(CONFIG_HCL_DEBUG)
static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
#endif
static unsigned int hcl_debug = HCL_DEBUG_NONE;
#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
static unsigned int boot_options = OPTION_NONE;
#endif
/*
* Some Global definitions.
*/
static vertex_hdl_t hcl_handle;
invplace_t invplace_none = {
GRAPH_VERTEX_NONE,
GRAPH_VERTEX_PLACE_NONE,
NULL
};
/*
* HCL device driver.
* The purpose of this device driver is to provide a facility
* for User Level Apps e.g. hinv, ioconfig etc. an ioctl path
* to manipulate label entries without having to implement
* system call interfaces. This methodology will enable us to
* make this feature module loadable.
*/
static int hcl_open(struct inode * inode, struct file * filp)
{
if (hcl_debug) {
printk("HCL: hcl_open called.\n");
}
return(0);
}
static int hcl_close(struct inode * inode, struct file * filp)
{
if (hcl_debug) {
printk("HCL: hcl_close called.\n");
}
return(0);
}
static int hcl_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
if (hcl_debug) {
printk("HCL: hcl_ioctl called.\n");
}
switch (cmd) {
default:
if (hcl_debug) {
printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
}
}
return(0);
}
struct file_operations hcl_fops = {
(struct module *)0,
NULL, /* lseek - default */
NULL, /* read - general block-dev read */
NULL, /* write - general block-dev write */
NULL, /* readdir - bad */
NULL, /* poll */
hcl_ioctl, /* ioctl */
NULL, /* mmap */
hcl_open, /* open */
NULL, /* flush */
hcl_close, /* release */
NULL, /* fsync */
NULL, /* fasync */
NULL, /* lock */
NULL, /* readv */
NULL, /* writev */
};
/*
* init_hcl() - Boot time initialization. Ensure that it is called
* after devfs has been initialized.
*
* For now this routine is being called out of devfs/base.c. Actually
* Not a bad place to be ..
*
*/
int __init init_hcl(void)
{
extern void string_table_init(struct string_table *);
extern struct string_table label_string_table;
extern int init_ifconfig_net(void);
extern int init_ioconfig_bus(void);
int status = 0;
int rv = 0;
if (IS_RUNNING_ON_SIMULATOR()) {
extern u64 klgraph_addr[];
klgraph_addr[0] = 0xe000003000030000;
}
/*
* Create the hwgraph_root on devfs.
*/
rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
if (rv)
printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
status = devfs_set_flags (hwgraph_root, DEVFS_FL_HIDE);
/*
* Create the hcl driver to support inventory entry manipulations.
* By default, it is expected that devfs is mounted on /dev.
*
*/
hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
0, DEVFS_FL_AUTO_DEVNUM,
0, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
&hcl_fops, NULL);
if (hcl_handle == NULL) {
panic("HCL: Unable to create HCL Driver in init_hcl().\n");
return(0);
}
/*
* Initialize the HCL string table.
*/
string_table_init(&label_string_table);
/*
* Create the directory that links Linux bus numbers to our Xwidget.
*/
rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
if (linux_busnum == NULL) {
panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
return(0);
}
pci_bus_cvlink_init();
/*
* Initialize the ifconfgi_net driver that does network devices
* Persistent Naming.
*/
init_ifconfig_net();
init_ioconfig_bus();
return(0);
}
/*
* hcl_setup() - Process boot time parameters if given.
* "hcl="
* This routine gets called only if "hcl=" is given in the
* boot line and before init_hcl().
*
* We currently do not have any boot options .. when we do,
* functionalities can be added here.
*
*/
static int __init hcl_setup(char *str)
{
while ( (*str != '\0') && !isspace (*str) )
{
#ifdef CONFIG_HCL_DEBUG
if (strncmp (str, "all", 3) == 0) {
hcl_debug_init |= HCL_DEBUG_ALL;
str += 3;
} else
return 0;
#endif
if (*str != ',') return 0;
++str;
}
return 1;
}
__setup("hcl=", hcl_setup);
/*
* Set device specific "fast information".
*
*/
void
hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo)
{
labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
}
/*
* Get device specific "fast information".
*
*/
arbitrary_info_t
hwgraph_fastinfo_get(vertex_hdl_t de)
{
arbitrary_info_t fastinfo;
int rv;
if (!de) {
printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
return(-1);
}
rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
if (rv == 0)
return(fastinfo);
return(0);
}
/*
* hwgraph_connectpt_set - Sets the connect point handle in de to the
* given connect_de handle. By default, the connect point of the
* devfs node is the parent. This effectively changes this assumption.
*/
int
hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de)
{
int rv;
if (!de)
return(-1);
rv = labelcl_info_connectpt_set(de, connect_de);
return(rv);
}
/*
* hwgraph_connectpt_get: Returns the entry's connect point in the devfs
* tree.
*/
vertex_hdl_t
hwgraph_connectpt_get(vertex_hdl_t de)
{
int rv;
arbitrary_info_t info;
vertex_hdl_t connect;
rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
if (rv != 0) {
return(NULL);
}
connect = (vertex_hdl_t)info;
return(connect);
}
/*
* hwgraph_mk_dir - Creates a directory entry with devfs.
* Note that a directory entry in devfs can have children
* but it cannot be a char|block special file.
*/
vertex_hdl_t
hwgraph_mk_dir(vertex_hdl_t de, const char *name,
unsigned int namelen, void *info)
{
int rv;
labelcl_info_t *labelcl_info = NULL;
vertex_hdl_t new_devfs_handle = NULL;
vertex_hdl_t parent = NULL;
/*
* Create the device info structure for hwgraph compatiblity support.
*/
labelcl_info = labelcl_info_create();
if (!labelcl_info)
return(NULL);
/*
* Create a devfs entry.
*/
new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info);
if (!new_devfs_handle) {
labelcl_info_destroy(labelcl_info);
return(NULL);
}
/*
* Get the parent handle.
*/
parent = devfs_get_parent (new_devfs_handle);
/*
* To provide the same semantics as the hwgraph, set the connect point.
*/
rv = hwgraph_connectpt_set(new_devfs_handle, parent);
if (!rv) {
/*
* We need to clean up!
*/
}
/*
* If the caller provides a private data pointer, save it in the
* labelcl info structure(fastinfo). This can be retrieved via
* hwgraph_fastinfo_get()
*/
if (info)
hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
return(new_devfs_handle);
}
/*
* hwgraph_path_add - Create a directory node with the given path starting
* from the given vertex_hdl_t.
*/
int
hwgraph_path_add(vertex_hdl_t fromv,
char *path,
vertex_hdl_t *new_de)
{
unsigned int namelen = strlen(path);
int rv;
/*
* We need to handle the case when fromv is NULL ..
* in this case we need to create the path from the
* hwgraph root!
*/
if (fromv == NULL)
fromv = hwgraph_root;
/*
* check the entry doesn't already exist, if it does
* then we simply want new_de to point to it (otherwise
* we'll overwrite the existing labelcl_info struct)
*/
rv = hwgraph_edge_get(fromv, path, new_de);
if (rv) { /* couldn't find entry so we create it */
*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
if (new_de == NULL)
return(-1);
else
return(0);
}
else
return(0);
}
/*
* hwgraph_register - Creates a file entry with devfs.
* Note that a file entry cannot have children .. it is like a
* char|block special vertex in hwgraph.
*/
vertex_hdl_t
hwgraph_register(vertex_hdl_t de, const char *name,
unsigned int namelen, unsigned int flags,
unsigned int major, unsigned int minor,
umode_t mode, uid_t uid, gid_t gid,
struct file_operations *fops,
void *info)
{
int rv;
void *labelcl_info = NULL;
vertex_hdl_t new_devfs_handle = NULL;
vertex_hdl_t parent = NULL;
/*
* Create the labelcl info structure for hwgraph compatiblity support.
*/
labelcl_info = labelcl_info_create();
if (!labelcl_info)
return(NULL);
/*
* Create a devfs entry.
*/
new_devfs_handle = devfs_register(de, name, flags, major,
minor, mode, fops, labelcl_info);
if (!new_devfs_handle) {
labelcl_info_destroy((labelcl_info_t *)labelcl_info);
return(NULL);
}
/*
* Get the parent handle.
*/
if (de == NULL)
parent = devfs_get_parent (new_devfs_handle);
else
parent = de;
/*
* To provide the same semantics as the hwgraph, set the connect point.
*/
rv = hwgraph_connectpt_set(new_devfs_handle, parent);
if (rv) {
/*
* We need to clean up!
*/
printk(KERN_WARNING "HCL: Unable to set the connect point to it's parent 0x%p\n",
(void *)new_devfs_handle);
}
/*
* If the caller provides a private data pointer, save it in the
* labelcl info structure(fastinfo). This can be retrieved via
* hwgraph_fastinfo_get()
*/
if (info)
hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
return(new_devfs_handle);
}
/*
* hwgraph_mk_symlink - Create a symbolic link.
*/
int
hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen,
unsigned int flags, const char *link, unsigned int linklen,
vertex_hdl_t *handle, void *info)
{
void *labelcl_info = NULL;
int status = 0;
vertex_hdl_t new_devfs_handle = NULL;
/*
* Create the labelcl info structure for hwgraph compatiblity support.
*/
labelcl_info = labelcl_info_create();
if (!labelcl_info)
return(-1);
/*
* Create a symbolic link devfs entry.
*/
status = devfs_mk_symlink(de, name, flags, link,
&new_devfs_handle, labelcl_info);
if ( (!new_devfs_handle) || (!status) ){
labelcl_info_destroy((labelcl_info_t *)labelcl_info);
return(-1);
}
/*
* If the caller provides a private data pointer, save it in the
* labelcl info structure(fastinfo). This can be retrieved via
* hwgraph_fastinfo_get()
*/
if (info)
hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
*handle = new_devfs_handle;
return(0);
}
/*
* hwgraph_vertex_destroy - Destroy the devfs entry
*/
int
hwgraph_vertex_destroy(vertex_hdl_t de)
{
void *labelcl_info = NULL;
labelcl_info = devfs_get_info(de);
devfs_unregister(de);
if (labelcl_info)
labelcl_info_destroy((labelcl_info_t *)labelcl_info);
return(0);
}
/*
* hwgraph_edge_add - This routines has changed from the original conext.
* All it does now is to create a symbolic link from "from" to "to".
*/
/* ARGSUSED */
int
hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
{
char *path;
char *s1;
char *index;
int name_start;
vertex_hdl_t handle = NULL;
int rv;
int i, count;
path = kmalloc(1024, GFP_KERNEL);
memset(path, 0x0, 1024);
name_start = devfs_generate_path (from, path, 1024);
s1 = &path[name_start];
count = 0;
while (1) {
index = strstr (s1, "/");
if (index) {
count++;
s1 = ++index;
} else {
count++;
break;
}
}
memset(path, 0x0, 1024);
name_start = devfs_generate_path (to, path, 1024);
for (i = 0; i < count; i++) {
strcat(path,"../");
}
strcat(path, &path[name_start]);
/*
* Otherwise, just create a symlink to the vertex.
* In this case the vertex was previous created with a REAL pathname.
*/
rv = devfs_mk_symlink (from, (const char *)name,
DEVFS_FL_DEFAULT, path,
&handle, NULL);
name_start = devfs_generate_path (handle, path, 1024);
return(rv);
}
/* ARGSUSED */
int
hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
{
int namelen = 0;
vertex_hdl_t target_handle = NULL;
if (name == NULL)
return(-1);
if (toptr == NULL)
return(-1);
/*
* If the name is "." just return the current devfs entry handle.
*/
if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
if (toptr) {
*toptr = from;
}
} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
/*
* Hmmm .. should we return the connect point or parent ..
* see in hwgraph, the concept of parent is the connectpt!
*
* Maybe we should see whether the connectpt is set .. if
* not just return the parent!
*/
target_handle = hwgraph_connectpt_get(from);
if (target_handle) {
/*
* Just return the connect point.
*/
*toptr = target_handle;
return(0);
}
target_handle = devfs_get_parent(from);
*toptr = target_handle;
} else {
/*
* Call devfs to get the devfs entry.
*/
namelen = (int) strlen(name);
target_handle = devfs_find_handle (from, name, 0, 0,
0, 1); /* Yes traverse symbolic links */
if (target_handle == NULL)
return(-1);
else
*toptr = target_handle;
}
return(0);
}
/*
* hwgraph_info_add_LBL - Adds a new label for the device. Mark the info_desc
* of the label as INFO_DESC_PRIVATE and store the info in the label.
*/
/* ARGSUSED */
int
hwgraph_info_add_LBL( vertex_hdl_t de,
char *name,
arbitrary_info_t info)
{
return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
}
/*
* hwgraph_info_remove_LBL - Remove the label entry for the device.
*/
/* ARGSUSED */
int
hwgraph_info_remove_LBL( vertex_hdl_t de,
char *name,
arbitrary_info_t *old_info)
{
return(labelcl_info_remove_LBL(de, name, NULL, old_info));
}
/*
* hwgraph_info_replace_LBL - replaces an existing label with
* a new label info value.
*/
/* ARGSUSED */
int
hwgraph_info_replace_LBL( vertex_hdl_t de,
char *name,
arbitrary_info_t info,
arbitrary_info_t *old_info)
{
return(labelcl_info_replace_LBL(de, name,
INFO_DESC_PRIVATE, info,
NULL, old_info));
}
/*
* hwgraph_info_get_LBL - Get and return the info value in the label of the
* device.
*/
/* ARGSUSED */
int
hwgraph_info_get_LBL( vertex_hdl_t de,
char *name,
arbitrary_info_t *infop)
{
return(labelcl_info_get_LBL(de, name, NULL, infop));
}
/*
* hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer
* of the given label for the device. The weird thing is that the label
* that matches the name is return irrespective of the info_desc value!
* Do not understand why the word "exported" is used!
*/
/* ARGSUSED */
int
hwgraph_info_get_exported_LBL( vertex_hdl_t de,
char *name,
int *export_info,
arbitrary_info_t *infop)
{
int rc;
arb_info_desc_t info_desc;
rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
if (rc == 0)
*export_info = (int)info_desc;
return(rc);
}
/*
* hwgraph_info_get_next_LBL - Returns the next label info given the
* current label entry in place.
*
* Once again this has no locking or reference count for protection.
*
*/
/* ARGSUSED */
int
hwgraph_info_get_next_LBL( vertex_hdl_t de,
char *buf,
arbitrary_info_t *infop,
labelcl_info_place_t *place)
{
return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
}
/*
* hwgraph_info_export_LBL - Retrieve the specified label entry and modify
* the info_desc field with the given value in nbytes.
*/
/* ARGSUSED */
int
hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes)
{
arbitrary_info_t info;
int rc;
if (nbytes == 0)
nbytes = INFO_DESC_EXPORT;
if (nbytes < 0)
return(-1);
rc = labelcl_info_get_LBL(de, name, NULL, &info);
if (rc != 0)
return(rc);
rc = labelcl_info_replace_LBL(de, name,
nbytes, info, NULL, NULL);
return(rc);
}
/*
* hwgraph_info_unexport_LBL - Retrieve the given label entry and change the
* label info_descr filed to INFO_DESC_PRIVATE.
*/
/* ARGSUSED */
int
hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name)
{
arbitrary_info_t info;
int rc;
rc = labelcl_info_get_LBL(de, name, NULL, &info);
if (rc != 0)
return(rc);
rc = labelcl_info_replace_LBL(de, name,
INFO_DESC_PRIVATE, info, NULL, NULL);
return(rc);
}
/*
* hwgraph_path_lookup - return the handle for the given path.
*
*/
int
hwgraph_path_lookup( vertex_hdl_t start_vertex_handle,
char *lookup_path,
vertex_hdl_t *vertex_handle_ptr,
char **remainder)
{
*vertex_handle_ptr = devfs_find_handle(start_vertex_handle, /* start dir */
lookup_path, /* path */
0, /* major */
0, /* minor */
0, /* char | block */
1); /* traverse symlinks */
if (*vertex_handle_ptr == NULL)
return(-1);
else
return(0);
}
/*
* hwgraph_traverse - Find and return the devfs handle starting from de.
*
*/
graph_error_t
hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found)
{
/*
* get the directory entry (path should end in a directory)
*/
*found = devfs_find_handle(de, /* start dir */
path, /* path */
0, /* major */
0, /* minor */
0, /* char | block */
1); /* traverse symlinks */
if (*found == NULL)
return(GRAPH_NOT_FOUND);
else
return(GRAPH_SUCCESS);
}
/*
* hwgraph_path_to_vertex - Return the devfs entry handle for the given
* pathname .. assume traverse symlinks too!.
*/
vertex_hdl_t
hwgraph_path_to_vertex(char *path)
{
return(devfs_find_handle(NULL, /* start dir */
path, /* path */
0, /* major */
0, /* minor */
0, /* char | block */
1)); /* traverse symlinks */
}
/*
* hwgraph_inventory_remove - Removes an inventory entry.
*
* Remove an inventory item associated with a vertex. It is the caller's
* responsibility to make sure that there are no races between removing
* inventory from a vertex and simultaneously removing that vertex.
*/
int
hwgraph_inventory_remove( vertex_hdl_t de,
int class,
int type,
major_t controller,
minor_t unit,
int state)
{
return(0); /* Just a Stub for IRIX code. */
}
/*
* Find the canonical name for a given vertex by walking back through
* connectpt's until we hit the hwgraph root vertex (or until we run
* out of buffer space or until something goes wrong).
*
* COMPATIBILITY FUNCTIONALITY
* Walks back through 'parents', not necessarily the same as connectpts.
*
* Need to resolve the fact that devfs does not return the path from
* "/" but rather it just stops right before /dev ..
*/
int
hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen)
{
char *locbuf;
int pos;
if (buflen < 1)
return(-1); /* XXX should be GRAPH_BAD_PARAM ? */
locbuf = kmalloc(buflen, GFP_KERNEL);
pos = devfs_generate_path(vhdl, locbuf, buflen);
if (pos < 0) {
kfree(locbuf);
return pos;
}
strcpy(buf, &locbuf[pos]);
kfree(locbuf);
return 0;
}
/*
** vertex_to_name converts a vertex into a canonical name by walking
** back through connect points until we hit the hwgraph root (or until
** we run out of buffer space).
**
** Usually returns a pointer to the original buffer, filled in as
** appropriate. If the buffer is too small to hold the entire name,
** or if anything goes wrong while determining the name, vertex_to_name
** returns "UnknownDevice".
*/
#define DEVNAME_UNKNOWN "UnknownDevice"
char *
vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen)
{
if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
return(buf);
else
return(DEVNAME_UNKNOWN);
}
graph_error_t
hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
{
printk("WARNING: hwgraph_edge_remove NOT supported.\n");
return(GRAPH_ILLEGAL_REQUEST);
}
graph_error_t
hwgraph_vertex_unref(vertex_hdl_t vhdl)
{
return(GRAPH_ILLEGAL_REQUEST);
}
EXPORT_SYMBOL(hwgraph_mk_dir);
EXPORT_SYMBOL(hwgraph_path_add);
EXPORT_SYMBOL(hwgraph_register);
EXPORT_SYMBOL(hwgraph_vertex_destroy);
EXPORT_SYMBOL(hwgraph_fastinfo_get);
EXPORT_SYMBOL(hwgraph_fastinfo_set);
EXPORT_SYMBOL(hwgraph_connectpt_set);
EXPORT_SYMBOL(hwgraph_connectpt_get);
EXPORT_SYMBOL(hwgraph_info_add_LBL);
EXPORT_SYMBOL(hwgraph_info_remove_LBL);
EXPORT_SYMBOL(hwgraph_info_replace_LBL);
EXPORT_SYMBOL(hwgraph_info_get_LBL);
EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
EXPORT_SYMBOL(hwgraph_info_export_LBL);
EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
EXPORT_SYMBOL(hwgraph_path_lookup);
EXPORT_SYMBOL(hwgraph_traverse);
EXPORT_SYMBOL(hwgraph_vertex_name_get);
/* $Id: hcl_util.c,v 1.3 2003/04/24 13:59:39 pfg Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/devfs_fs.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/sn/sgi.h>
#include <asm/io.h>
#include <asm/sn/io.h>
#include <asm/sn/iograph.h>
#include <asm/sn/invent.h>
#include <asm/sn/hcl.h>
#include <asm/sn/labelcl.h>
#include <asm/sn/hcl_util.h>
#include <asm/sn/nodepda.h>
static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
extern vertex_hdl_t hwgraph_root;
/*
** Return the "master" for a given vertex. A master vertex is a
** controller or adapter or other piece of hardware that the given
** vertex passes through on the way to the rest of the system.
*/
vertex_hdl_t
device_master_get(vertex_hdl_t vhdl)
{
graph_error_t rc;
vertex_hdl_t master;
rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
if (rc == GRAPH_SUCCESS)
return(master);
else
return(GRAPH_VERTEX_NONE);
}
/*
** Set the master for a given vertex.
** Returns 0 on success, non-0 indicates failure
*/
int
device_master_set(vertex_hdl_t vhdl, vertex_hdl_t master)
{
graph_error_t rc;
rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
return(rc != GRAPH_SUCCESS);
}
/*
** Return the compact node id of the node that ultimately "owns" the specified
** vertex. In order to do this, we walk back through masters and connect points
** until we reach a vertex that represents a node.
*/
cnodeid_t
master_node_get(vertex_hdl_t vhdl)
{
cnodeid_t cnodeid;
vertex_hdl_t master;
for (;;) {
cnodeid = nodevertex_to_cnodeid(vhdl);
if (cnodeid != CNODEID_NONE)
return(cnodeid);
master = device_master_get(vhdl);
/* Check for exceptional cases */
if (master == vhdl) {
/* Since we got a reference to the "master" thru
* device_master_get() we should decrement
* its reference count by 1
*/
return(CNODEID_NONE);
}
if (master == GRAPH_VERTEX_NONE) {
master = hwgraph_connectpt_get(vhdl);
if ((master == GRAPH_VERTEX_NONE) ||
(master == vhdl)) {
return(CNODEID_NONE);
}
}
vhdl = master;
}
}
static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
extern int maxcpus;
void
mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid)
{
if (cpuid == CPU_NONE)
return;
(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
(arbitrary_info_t)cpuid);
{
char cpuid_buffer[10];
if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
(void)hwgraph_path_add( hwgraph_root,
EDGE_LBL_CPUNUM,
&hwgraph_all_cpuids);
}
sprintf(cpuid_buffer, "%ld", cpuid);
(void)hwgraph_edge_add( hwgraph_all_cpuids,
vhdl,
cpuid_buffer);
}
}
/*
** If the specified device represents a node, return its
** compact node ID; otherwise, return CNODEID_NONE.
*/
cnodeid_t
nodevertex_to_cnodeid(vertex_hdl_t vhdl)
{
int rv = 0;
arbitrary_info_t cnodeid = CNODEID_NONE;
rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
return((cnodeid_t)cnodeid);
}
void
mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid)
{
if (cnodeid == CNODEID_NONE)
return;
cnodeid_to_vertex(cnodeid) = vhdl;
labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT,
(arbitrary_info_t)cnodeid);
{
char cnodeid_buffer[10];
if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
(void)hwgraph_path_add( hwgraph_root,
EDGE_LBL_NODENUM,
&hwgraph_all_cnodes);
}
sprintf(cnodeid_buffer, "%d", cnodeid);
(void)hwgraph_edge_add( hwgraph_all_cnodes,
vhdl,
cnodeid_buffer);
}
}
/*
** If the specified device represents a CPU, return its cpuid;
** otherwise, return CPU_NONE.
*/
cpuid_t
cpuvertex_to_cpuid(vertex_hdl_t vhdl)
{
arbitrary_info_t cpuid = CPU_NONE;
(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
return((cpuid_t)cpuid);
}
/*
** dev_to_name converts a vertex_hdl_t into a canonical name. If the vertex_hdl_t
** represents a vertex in the hardware graph, it is converted in the
** normal way for vertices. If the vertex_hdl_t is an old vertex_hdl_t (one which
** does not represent a hwgraph vertex), we synthesize a name based
** on major/minor number.
**
** Usually returns a pointer to the original buffer, filled in as
** appropriate. If the buffer is too small to hold the entire name,
** or if anything goes wrong while determining the name, dev_to_name
** returns "UnknownDevice".
*/
char *
dev_to_name(vertex_hdl_t dev, char *buf, uint buflen)
{
return(vertex_to_name(dev, buf, buflen));
}
/* $Id$
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
*/
/*
* Hardware Inventory
*
* See sys/sn/invent.h for an explanation of the hardware inventory contents.
*
*/
#include <linux/types.h>
#include <asm/sn/sgi.h>
#include <asm/sn/invent.h>
#include <asm/sn/hcl.h>
#include <asm/sn/labelcl.h>
void
inventinit(void)
{
}
/*
* For initializing/updating an inventory entry.
*/
void
replace_in_inventory(
inventory_t *pinv, int class, int type,
int controller, int unit, int state)
{
}
/*
* Inventory addition
*
* XXX NOTE: Currently must be called after dynamic memory allocator is
* initialized.
*
*/
void
add_to_inventory(int class, int type, int controller, int unit, int state)
{
}
/*
* Inventory retrieval
*
* These two routines are intended to prevent the caller from having to know
* the internal structure of the inventory table.
*
* The caller of get_next_inventory is supposed to call start_scan_invent
* before the irst call to get_next_inventory, and the caller is required
* to call end_scan_invent after the last call to get_next_inventory.
*/
inventory_t *
get_next_inventory(invplace_t *place)
{
return((inventory_t *) NULL);
}
/* ARGSUSED */
int
get_sizeof_inventory(int abi)
{
return sizeof(inventory_t);
}
/* Must be called prior to first call to get_next_inventory */
void
start_scan_inventory(invplace_t *iplace)
{
}
/* Must be called after last call to get_next_inventory */
void
end_scan_inventory(invplace_t *iplace)
{
}
/*
* Hardware inventory scanner.
*
* Calls fun() for every entry in inventory list unless fun() returns something
* other than 0.
*/
int
scaninvent(int (*fun)(inventory_t *, void *), void *arg)
{
return 0;
}
/*
* Find a particular inventory object
*
* pinv can be a pointer to an inventory entry and the search will begin from
* there, or it can be 0 in which case the search starts at the beginning.
* A -1 for any of the other arguments is a wildcard (i.e. it always matches).
*/
inventory_t *
find_inventory(inventory_t *pinv, int class, int type, int controller,
int unit, int state)
{
return((inventory_t *) NULL);
}
/*
** Retrieve inventory data associated with a device.
*/
inventory_t *
device_inventory_get_next( vertex_hdl_t device,
invplace_t *invplace)
{
return((inventory_t *) NULL);
}
/*
** Associate canonical inventory information with a device (and
** add it to the general inventory).
*/
void
device_inventory_add( vertex_hdl_t device,
int class,
int type,
major_t controller,
minor_t unit,
int state)
{
}
int
device_controller_num_get(vertex_hdl_t device)
{
return (0);
}
void
device_controller_num_set(vertex_hdl_t device, int contr_num)
{
}
/* labelcl - SGI's Hwgraph Compatibility Layer.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (c) 2001-2003 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/types.h>
#include <linux/slab.h>
#include <asm/sn/sgi.h>
#include <linux/devfs_fs.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/sn/invent.h>
#include <asm/sn/hcl.h>
#include <asm/sn/labelcl.h>
/*
** Very simple and dumb string table that supports only find/insert.
** In practice, if this table gets too large, we may need a more
** efficient data structure. Also note that currently there is no
** way to delete an item once it's added. Therefore, name collision
** will return an error.
*/
struct string_table label_string_table;
/*
* string_table_init - Initialize the given string table.
*/
void
string_table_init(struct string_table *string_table)
{
string_table->string_table_head = NULL;
string_table->string_table_generation = 0;
/*
* We nedd to initialize locks here!
*/
return;
}
/*
* string_table_destroy - Destroy the given string table.
*/
void
string_table_destroy(struct string_table *string_table)
{
struct string_table_item *item, *next_item;
item = string_table->string_table_head;
while (item) {
next_item = item->next;
STRTBL_FREE(item);
item = next_item;
}
/*
* We need to destroy whatever lock we have here
*/
return;
}
/*
* string_table_insert - Insert an entry in the string table .. duplicate
* names are not allowed.
*/
char *
string_table_insert(struct string_table *string_table, char *name)
{
struct string_table_item *item, *new_item = NULL, *last_item = NULL;
again:
/*
* Need to lock the table ..
*/
item = string_table->string_table_head;
last_item = NULL;
while (item) {
if (!strcmp(item->string, name)) {
/*
* If we allocated space for the string and the found that
* someone else already entered it into the string table,
* free the space we just allocated.
*/
if (new_item)
STRTBL_FREE(new_item);
/*
* Search optimization: move the found item to the head
* of the list.
*/
if (last_item != NULL) {
last_item->next = item->next;
item->next = string_table->string_table_head;
string_table->string_table_head = item;
}
goto out;
}
last_item = item;
item=item->next;
}
/*
* name was not found, so add it to the string table.
*/
if (new_item == NULL) {
long old_generation = string_table->string_table_generation;
new_item = STRTBL_ALLOC(strlen(name));
strcpy(new_item->string, name);
/*
* While we allocated memory for the new string, someone else
* changed the string table.
*/
if (old_generation != string_table->string_table_generation) {
goto again;
}
} else {
/* At this we only have the string table lock in access mode.
* Promote the access lock to an update lock for the string
* table insertion below.
*/
long old_generation =
string_table->string_table_generation;
/*
* After we did the unlock and wer waiting for update
* lock someone could have potentially updated
* the string table. Check the generation number
* for this case. If it is the case we have to
* try all over again.
*/
if (old_generation !=
string_table->string_table_generation) {
goto again;
}
}
/*
* At this point, we're committed to adding new_item to the string table.
*/
new_item->next = string_table->string_table_head;
item = string_table->string_table_head = new_item;
string_table->string_table_generation++;
out:
/*
* Need to unlock here.
*/
return(item->string);
}
/*
* labelcl_info_create - Creates the data structure that will hold the
* device private information asscoiated with a devfs entry.
* The pointer to this structure is what gets stored in the devfs
* (void * info).
*/
labelcl_info_t *
labelcl_info_create()
{
labelcl_info_t *new = NULL;
/* Initial allocation does not include any area for labels */
if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
return NULL;
memset (new, 0, sizeof(labelcl_info_t));
new->hwcl_magic = LABELCL_MAGIC;
return( new);
}
/*
* labelcl_info_destroy - Frees the data structure that holds the
* device private information asscoiated with a devfs entry. This
* data structure was created by device_info_create().
*
* The caller is responsible for nulling the (void *info) in the
* corresponding devfs entry.
*/
int
labelcl_info_destroy(labelcl_info_t *labelcl_info)
{
if (labelcl_info == NULL)
return(0);
/* Free the label list */
if (labelcl_info->label_list)
kfree(labelcl_info->label_list);
/* Now free the label info area */
labelcl_info->hwcl_magic = 0;
kfree(labelcl_info);
return(0);
}
/*
* labelcl_info_add_LBL - Adds a new label entry in the labelcl info
* structure.
*
* Error is returned if we find another label with the same name.
*/
int
labelcl_info_add_LBL(vertex_hdl_t de,
char *info_name,
arb_info_desc_t info_desc,
arbitrary_info_t info)
{
labelcl_info_t *labelcl_info = NULL;
int num_labels;
int new_label_list_size;
label_info_t *old_label_list, *new_label_list = NULL;
char *name;
int i;
if (de == NULL)
return(-1);
labelcl_info = devfs_get_info(de);
if (labelcl_info == NULL)
return(-1);
if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
return(-1);
if (info_name == NULL)
return(-1);
if (strlen(info_name) >= LABEL_LENGTH_MAX)
return(-1);
name = string_table_insert(&label_string_table, info_name);
num_labels = labelcl_info->num_labels;
new_label_list_size = sizeof(label_info_t) * (num_labels+1);
/*
* Create a new label info area.
*/
if (new_label_list_size != 0) {
new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
if (new_label_list == NULL)
return(-1);
}
/*
* At this point, we are committed to adding the labelled info,
* if there isn't already information there with the same name.
*/
old_label_list = labelcl_info->label_list;
/*
* Look for matching info name.
*/
for (i=0; i<num_labels; i++) {
if (!strcmp(info_name, old_label_list[i].name)) {
/* Not allowed to add duplicate labelled info names. */
kfree(new_label_list);
return(-1);
}
new_label_list[i] = old_label_list[i]; /* structure copy */
}
new_label_list[num_labels].name = name;
new_label_list[num_labels].desc = info_desc;
new_label_list[num_labels].info = info;
labelcl_info->num_labels = num_labels+1;
labelcl_info->label_list = new_label_list;
if (old_label_list != NULL)
kfree(old_label_list);
return(0);
}
/*
* labelcl_info_remove_LBL - Remove a label entry.
*/
int
labelcl_info_remove_LBL(vertex_hdl_t de,
char *info_name,
arb_info_desc_t *info_desc,
arbitrary_info_t *info)
{
labelcl_info_t *labelcl_info = NULL;
int num_labels;
int new_label_list_size;
label_info_t *old_label_list, *new_label_list = NULL;
arb_info_desc_t label_desc_found;
arbitrary_info_t label_info_found;
int i;
if (de == NULL)
return(-1);
labelcl_info = devfs_get_info(de);
if (labelcl_info == NULL)
return(-1);
if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
return(-1);
num_labels = labelcl_info->num_labels;
if (num_labels == 0) {
return(-1);
}
/*
* Create a new info area.
*/
new_label_list_size = sizeof(label_info_t) * (num_labels-1);
if (new_label_list_size) {
new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
if (new_label_list == NULL)
return(-1);
}
/*
* At this point, we are committed to removing the labelled info,
* if it still exists.
*/
old_label_list = labelcl_info->label_list;
/*
* Find matching info name.
*/
for (i=0; i<num_labels; i++) {
if (!strcmp(info_name, old_label_list[i].name)) {
label_desc_found = old_label_list[i].desc;
label_info_found = old_label_list[i].info;
goto found;
}
if (i < num_labels-1) /* avoid walking off the end of the new vertex */
new_label_list[i] = old_label_list[i]; /* structure copy */
}
/* The named info doesn't exist. */
if (new_label_list)
kfree(new_label_list);
return(-1);
found:
/* Finish up rest of labelled info */
for (i=i+1; i<num_labels; i++)
new_label_list[i-1] = old_label_list[i]; /* structure copy */
labelcl_info->num_labels = num_labels+1;
labelcl_info->label_list = new_label_list;
kfree(old_label_list);
if (info != NULL)
*info = label_info_found;
if (info_desc != NULL)
*info_desc = label_desc_found;
return(0);
}
/*
* labelcl_info_replace_LBL - Replace an existing label entry with the
* given new information.
*
* Label entry must exist.
*/
int
labelcl_info_replace_LBL(vertex_hdl_t de,
char *info_name,
arb_info_desc_t info_desc,
arbitrary_info_t info,
arb_info_desc_t *old_info_desc,
arbitrary_info_t *old_info)
{
labelcl_info_t *labelcl_info = NULL;
int num_labels;
label_info_t *label_list;
int i;
if (de == NULL)
return(-1);
labelcl_info = devfs_get_info(de);
if (labelcl_info == NULL)
return(-1);
if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
return(-1);
num_labels = labelcl_info->num_labels;
if (num_labels == 0) {
return(-1);
}
if (info_name == NULL)
return(-1);
label_list = labelcl_info->label_list;
/*
* Verify that information under info_name already exists.
*/
for (i=0; i<num_labels; i++)
if (!strcmp(info_name, label_list[i].name)) {
if (old_info != NULL)
*old_info = label_list[i].info;
if (old_info_desc != NULL)
*old_info_desc = label_list[i].desc;
label_list[i].info = info;
label_list[i].desc = info_desc;
return(0);
}
return(-1);
}
/*
* labelcl_info_get_LBL - Retrieve and return the information for the
* given label entry.
*/
int
labelcl_info_get_LBL(vertex_hdl_t de,
char *info_name,
arb_info_desc_t *info_desc,
arbitrary_info_t *info)
{
labelcl_info_t *labelcl_info = NULL;
int num_labels;
label_info_t *label_list;
int i;
if (de == NULL)
return(-1);
labelcl_info = devfs_get_info(de);
if (labelcl_info == NULL)
return(-1);
if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
return(-1);
num_labels = labelcl_info->num_labels;
if (num_labels == 0) {
return(-1);
}
label_list = labelcl_info->label_list;
/*
* Find information under info_name.
*/
for (i=0; i<num_labels; i++)
if (!strcmp(info_name, label_list[i].name)) {
if (info != NULL)
*info = label_list[i].info;
if (info_desc != NULL)
*info_desc = label_list[i].desc;
return(0);
}
return(-1);
}
/*
* labelcl_info_get_next_LBL - returns the next label entry on the list.
*/
int
labelcl_info_get_next_LBL(vertex_hdl_t de,
char *buffer,
arb_info_desc_t *info_descp,
arbitrary_info_t *infop,
labelcl_info_place_t *placeptr)
{
labelcl_info_t *labelcl_info = NULL;
uint which_info;
label_info_t *label_list;
if ((buffer == NULL) && (infop == NULL))
return(-1);
if (placeptr == NULL)
return(-1);
if (de == NULL)
return(-1);
labelcl_info = devfs_get_info(de);
if (labelcl_info == NULL)
return(-1);
if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
return(-1);
which_info = *placeptr;
if (which_info >= labelcl_info->num_labels) {
return(-1);
}
label_list = (label_info_t *) labelcl_info->label_list;
if (buffer != NULL)
strcpy(buffer, label_list[which_info].name);
if (infop)
*infop = label_list[which_info].info;
if (info_descp)
*info_descp = label_list[which_info].desc;
*placeptr = which_info + 1;
return(0);
}
int
labelcl_info_replace_IDX(vertex_hdl_t de,
int index,
arbitrary_info_t info,
arbitrary_info_t *old_info)
{
arbitrary_info_t *info_list_IDX;
labelcl_info_t *labelcl_info = NULL;
if (de == NULL) {
printk(KERN_ALERT "labelcl: NULL devfs handle given.\n");
return(-1);
}
labelcl_info = devfs_get_info(de);
if (labelcl_info == NULL) {
printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n");
return(-1);
}
if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
return(-1);
if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
return(-1);
/*
* Replace information at the appropriate index in this vertex with
* the new info.
*/
info_list_IDX = labelcl_info->IDX_list;
if (old_info != NULL)
*old_info = info_list_IDX[index];
info_list_IDX[index] = info;
return(0);
}
/*
* labelcl_info_connectpt_set - Sets the connectpt.
*/
int
labelcl_info_connectpt_set(struct devfs_entry *de,
struct devfs_entry *connect_de)
{
arbitrary_info_t old_info;
int rv;
rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT,
(arbitrary_info_t) connect_de, &old_info);
if (rv) {
return(rv);
}
return(0);
}
/*
* labelcl_info_get_IDX - Returns the information pointed at by index.
*
*/
int
labelcl_info_get_IDX(vertex_hdl_t de,
int index,
arbitrary_info_t *info)
{
arbitrary_info_t *info_list_IDX;
labelcl_info_t *labelcl_info = NULL;
if (de == NULL)
return(-1);
labelcl_info = devfs_get_info(de);
if (labelcl_info == NULL)
return(-1);
if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
return(-1);
if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
return(-1);
/*
* Return information at the appropriate index in this vertex.
*/
info_list_IDX = labelcl_info->IDX_list;
if (info != NULL)
*info = info_list_IDX[index];
return(0);
}
/*
* labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
*/
struct devfs_entry *
labelcl_info_connectpt_get(struct devfs_entry *de)
{
int rv;
arbitrary_info_t info;
rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
if (rv)
return(NULL);
return((struct devfs_entry *)info);
}
...@@ -164,7 +164,7 @@ int __init init_hcl(void) ...@@ -164,7 +164,7 @@ int __init init_hcl(void)
* *
*/ */
hcl_handle = hwgraph_register(hwgraph_root, ".hcl", hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
0, DEVFS_FL_AUTO_DEVNUM, 0, 0,
0, 0, 0, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
&hcl_fops, NULL); &hcl_fops, NULL);
......
typedef struct dentry *hwgfs_handle_t;
extern hwgfs_handle_t hwgfs_register(hwgfs_handle_t dir, const char *name,
unsigned int flags,
unsigned int major, unsigned int minor,
umode_t mode, void *ops, void *info);
extern int hwgfs_mk_symlink(hwgfs_handle_t dir, const char *name,
unsigned int flags, const char *link,
hwgfs_handle_t *handle, void *info);
extern hwgfs_handle_t hwgfs_mk_dir(hwgfs_handle_t dir, const char *name,
void *info);
extern void hwgfs_unregister(hwgfs_handle_t de);
extern hwgfs_handle_t hwgfs_find_handle(hwgfs_handle_t dir, const char *name,
unsigned int major,unsigned int minor,
char type, int traverse_symlinks);
extern hwgfs_handle_t hwgfs_get_parent(hwgfs_handle_t de);
extern int hwgfs_generate_path(hwgfs_handle_t de, char *path, int buflen);
extern void *hwgfs_get_info(hwgfs_handle_t de);
extern int hwgfs_set_info(hwgfs_handle_t de, void *info);
...@@ -216,7 +216,7 @@ klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode) ...@@ -216,7 +216,7 @@ klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode)
(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv); (void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
rc = device_master_set(myhubv, node_vertex); rc = device_master_set(myhubv, node_vertex);
hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON, hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
0, DEVFS_FL_AUTO_DEVNUM, 0, 0,
0, 0, 0, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
&shub_mon_fops, (void *)(long)cnode); &shub_mon_fops, (void *)(long)cnode);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/sn/sgi.h> #include <asm/sn/sgi.h>
#include <asm/sn/io.h> #include <asm/sn/io.h>
......
...@@ -62,9 +62,6 @@ mlreset(int slave) ...@@ -62,9 +62,6 @@ mlreset(int slave)
/* early initialization of iograph */ /* early initialization of iograph */
iograph_early_init(); iograph_early_init();
/* Initialize Hub Pseudodriver Management */
hubdev_init();
} }
......
...@@ -655,7 +655,6 @@ io_init_node(cnodeid_t cnodeid) ...@@ -655,7 +655,6 @@ io_init_node(cnodeid_t cnodeid)
struct semaphore *peer_sema = 0; struct semaphore *peer_sema = 0;
uint32_t widget_partnum; uint32_t widget_partnum;
cpu_cookie_t c = 0; cpu_cookie_t c = 0;
extern int hubdev_docallouts(vertex_hdl_t);
npdap = NODEPDA(cnodeid); npdap = NODEPDA(cnodeid);
...@@ -671,8 +670,6 @@ io_init_node(cnodeid_t cnodeid) ...@@ -671,8 +670,6 @@ io_init_node(cnodeid_t cnodeid)
ASSERT(hubv != GRAPH_VERTEX_NONE); ASSERT(hubv != GRAPH_VERTEX_NONE);
hubdev_docallouts(hubv);
/* /*
* Read mfg info on this hub * Read mfg info on this hub
*/ */
......
...@@ -11,7 +11,5 @@ ...@@ -11,7 +11,5 @@
EXTRA_CFLAGS := -DLITTLE_ENDIAN -DSHUB_SWAP_WAR EXTRA_CFLAGS := -DLITTLE_ENDIAN -DSHUB_SWAP_WAR
obj-$(CONFIG_IA64_SGI_SN2) += pcibr_ate.o pcibr_config.o \ obj-y += pcibr_ate.o pcibr_config.o pcibr_dvr.o pcibr_hints.o pcibr_intr.o pcibr_rrb.o \
pcibr_dvr.o pcibr_hints.o \ pcibr_slot.o pcibr_error.o
pcibr_intr.o pcibr_rrb.o pcibr_slot.o \
pcibr_error.o
...@@ -1215,7 +1215,7 @@ pcibr_attach2(vertex_hdl_t xconn_vhdl, bridge_t *bridge, ...@@ -1215,7 +1215,7 @@ pcibr_attach2(vertex_hdl_t xconn_vhdl, bridge_t *bridge,
ctlr_vhdl = NULL; ctlr_vhdl = NULL;
ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, 0, ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, 0,
DEVFS_FL_AUTO_DEVNUM, 0, 0, 0, 0, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
(struct file_operations *)&pcibr_fops, (void *)pcibr_vhdl); (struct file_operations *)&pcibr_fops, (void *)pcibr_vhdl);
ASSERT(ctlr_vhdl != NULL); ASSERT(ctlr_vhdl != NULL);
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
extern void hubni_eint_init(cnodeid_t cnode); extern void hubni_eint_init(cnodeid_t cnode);
extern void hubii_eint_init(cnodeid_t cnode); extern void hubii_eint_init(cnodeid_t cnode);
extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep); extern irqreturn_t hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
int hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo); int hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo);
int hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo); int hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo);
extern void bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop); extern void bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop);
...@@ -168,7 +168,7 @@ hubii_eint_init(cnodeid_t cnode) ...@@ -168,7 +168,7 @@ hubii_eint_init(cnodeid_t cnode)
/*ARGSUSED*/ /*ARGSUSED*/
void irqreturn_t
hubii_eint_handler (int irq, void *arg, struct pt_regs *ep) hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
{ {
vertex_hdl_t hub_v; vertex_hdl_t hub_v;
...@@ -263,6 +263,8 @@ hubii_eint_handler (int irq, void *arg, struct pt_regs *ep) ...@@ -263,6 +263,8 @@ hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
*/ */
(void)hubiio_crb_error_handler(hub_v, hinfo); (void)hubiio_crb_error_handler(hub_v, hinfo);
(void)hubiio_prb_error_handler(hub_v, hinfo); (void)hubiio_prb_error_handler(hub_v, hinfo);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -289,7 +289,7 @@ xbow_attach(vertex_hdl_t conn) ...@@ -289,7 +289,7 @@ xbow_attach(vertex_hdl_t conn)
*/ */
vhdl = NULL; vhdl = NULL;
vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, 0, vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, 0,
DEVFS_FL_AUTO_DEVNUM, 0, 0, 0, 0, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
(struct file_operations *)&xbow_fops, (void *)xbow); (struct file_operations *)&xbow_fops, (void *)xbow);
if (!vhdl) { if (!vhdl) {
......
...@@ -9,8 +9,7 @@ ...@@ -9,8 +9,7 @@
EXTRA_CFLAGS := -DLITTLE_ENDIAN EXTRA_CFLAGS := -DLITTLE_ENDIAN
obj-y := probe.o setup.o sv.o bte.o irq.o mca.o obj-y := probe.o setup.o sv.o bte.o irq.o mca.o sn2/
obj-$(CONFIG_IA64_SGI_SN2) += sn2/
obj-$(CONFIG_IA64_GENERIC) += machvec.o obj-$(CONFIG_IA64_GENERIC) += machvec.o
obj-$(CONFIG_MODULES) += sn_ksyms.o obj-$(CONFIG_MODULES) += sn_ksyms.o
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
* Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
*/ */
#define DEVFS_FL_AUTO_DEVNUM 0
typedef struct dentry *hwgfs_handle_t; typedef struct dentry *hwgfs_handle_t;
extern hwgfs_handle_t hwgfs_register(hwgfs_handle_t dir, const char *name, extern hwgfs_handle_t hwgfs_register(hwgfs_handle_t dir, const char *name,
......
...@@ -3629,15 +3629,6 @@ extern int kl_ioerror_handler(cnodeid_t, cnodeid_t, cpuid_t, ...@@ -3629,15 +3629,6 @@ extern int kl_ioerror_handler(cnodeid_t, cnodeid_t, cpuid_t,
extern int hub_error_devenable(vertex_hdl_t, int, int); extern int hub_error_devenable(vertex_hdl_t, int, int);
extern int hub_dma_enabled(vertex_hdl_t); extern int hub_dma_enabled(vertex_hdl_t);
/* hubdev */
extern void hubdev_init(void);
extern void hubdev_register(int (*attach_method)(vertex_hdl_t));
extern int hubdev_unregister(int (*attach_method)(vertex_hdl_t));
extern int hubdev_docallouts(vertex_hdl_t hub);
extern caddr_t hubdev_prombase_get(vertex_hdl_t hub);
extern cnodeid_t hubdev_cnodeid_get(vertex_hdl_t hub);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* _KERNEL */ #endif /* _KERNEL */
#endif /* _ASM_IA64_SN_SN2_SHUBIO_H */ #endif /* _ASM_IA64_SN_SN2_SHUBIO_H */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment