patch-2.4.19 linux-2.4.19/arch/ia64/sn/io/devsupport.c

Next file: linux-2.4.19/arch/ia64/sn/io/eeprom.c
Previous file: linux-2.4.19/arch/ia64/sn/io/cdl.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/ia64/sn/io/devsupport.c linux-2.4.19/arch/ia64/sn/io/devsupport.c
@@ -1,1289 +0,0 @@
-/* $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 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/iobus.h>
-#include <asm/sn/iograph.h>
-
-/* 
- * Interfaces in this file are all platform-independent AND IObus-independent.
- * Be aware that there may be macro equivalents to each of these hiding in
- * header files which supercede these functions.
- */
-
-/* =====Generic iobus support===== */
-
-/* String table to hold names of interrupts. */
-#ifdef LATER
-static struct string_table device_desc_string_table;
-#endif
-
-/* One time initialization for device descriptor support. */
-static void
-device_desc_init(void)
-{
-#ifdef LATER
-	string_table_init(&device_desc_string_table);
-#endif
-	FIXME("device_desc_init");
-}
-
-
-/* Drivers use these interfaces to manage device descriptors */
-static device_desc_t
-device_desc_alloc(void)
-{
-#ifdef LATER
-	device_desc_t device_desc;
-
-	device_desc = (device_desc_t)kmem_zalloc(sizeof(struct device_desc_s), 0);
-	device_desc->intr_target = GRAPH_VERTEX_NONE;
-
-	ASSERT(device_desc->intr_policy == 0);
-	device_desc->intr_swlevel = -1;
-	ASSERT(device_desc->intr_name == NULL);
-	ASSERT(device_desc->flags == 0);
-
-	ASSERT(!(device_desc->flags & D_IS_ASSOC));
-	return(device_desc);
-#else
-	FIXME("device_desc_alloc");
-	return((device_desc_t)0);
-#endif
-}
-
-void
-device_desc_free(device_desc_t device_desc)
-{
-#ifdef LATER
-	if (!(device_desc->flags & D_IS_ASSOC)) /* sanity */
-		kfree(device_desc);
-#endif
-	FIXME("device_desc_free");
-}
-
-device_desc_t
-device_desc_dup(devfs_handle_t dev)
-{
-#ifdef LATER
-	device_desc_t orig_device_desc, new_device_desc;
-
-
-	new_device_desc = device_desc_alloc();
-	orig_device_desc = device_desc_default_get(dev);
-	if (orig_device_desc)
-		*new_device_desc = *orig_device_desc;/* small structure copy */
-	else {
-		device_driver_t		driver;
-		ilvl_t			pri;		
-		/* 
-		 * Use the driver's thread priority in 
-		 * case the device thread priority has not
-		 * been given.
-		 */
-		if (driver = device_driver_getbydev(dev)) {
-			pri = device_driver_thread_pri_get(driver);
-			device_desc_intr_swlevel_set(new_device_desc,pri);
-		}
-	}		
-	new_device_desc->flags &= ~D_IS_ASSOC;
-	return(new_device_desc);
-#else
-	FIXME("device_desc_dup");
-	return((device_desc_t)0);
-#endif
-}
-
-device_desc_t	
-device_desc_default_get(devfs_handle_t dev)
-{
-#ifdef LATER
-	graph_error_t rc;
-	device_desc_t device_desc;
-
-	rc = hwgraph_info_get_LBL(dev, INFO_LBL_DEVICE_DESC, (arbitrary_info_t *)&device_desc);
-
-	if (rc == GRAPH_SUCCESS)
-		return(device_desc);
-	else
-		return(NULL);
-#else
-	FIXME("device_desc_default_get");
-	return((device_desc_t)0);
-#endif
-}
-
-void		
-device_desc_default_set(devfs_handle_t dev, device_desc_t new_device_desc)
-{
-#ifdef LATER
-	graph_error_t rc;
-	device_desc_t old_device_desc = NULL;
-
-	if (new_device_desc) {
-		new_device_desc->flags |= D_IS_ASSOC;
-		rc = hwgraph_info_add_LBL(dev, INFO_LBL_DEVICE_DESC, 
-						(arbitrary_info_t)new_device_desc);
-		if (rc == GRAPH_DUP) {
-			rc = hwgraph_info_replace_LBL(dev, INFO_LBL_DEVICE_DESC, 
-				(arbitrary_info_t)new_device_desc, 
-				(arbitrary_info_t *)&old_device_desc);
-
-			ASSERT(rc == GRAPH_SUCCESS);
-		}
-		hwgraph_info_export_LBL(dev, INFO_LBL_DEVICE_DESC,
-					sizeof(struct device_desc_s));
-	} else {
-		rc = hwgraph_info_remove_LBL(dev, INFO_LBL_DEVICE_DESC,
-					(arbitrary_info_t *)&old_device_desc);
-	}
-
-	if (old_device_desc) {
-		ASSERT(old_device_desc->flags & D_IS_ASSOC);
-		old_device_desc->flags &= ~D_IS_ASSOC;
-		device_desc_free(old_device_desc);
-	}
-#endif
-	FIXME("device_desc_default_set");
-}
-
-devfs_handle_t
-device_desc_intr_target_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->intr_target);
-#else
-	FIXME("device_desc_intr_target_get");
-	return((devfs_handle_t)0);
-#endif
-}
-
-int
-device_desc_intr_policy_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->intr_policy);
-#else
-	FIXME("device_desc_intr_policy_get");
-	return(0);
-#endif
-}
-
-ilvl_t
-device_desc_intr_swlevel_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->intr_swlevel);
-#else
-	FIXME("device_desc_intr_swlevel_get");
-	return((ilvl_t)0);
-#endif
-}
-
-char *
-device_desc_intr_name_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->intr_name);
-#else
-	FIXME("device_desc_intr_name_get");
-	return(NULL);
-#endif
-}
-
-int
-device_desc_flags_get(device_desc_t device_desc)
-{
-#ifdef LATER
-	return(device_desc->flags);
-#else
-	FIXME("device_desc_flags_get");
-	return(0);
-#endif
-}
-
-void
-device_desc_intr_target_set(device_desc_t device_desc, devfs_handle_t target)
-{
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->intr_target = target;
-}
-
-void
-device_desc_intr_policy_set(device_desc_t device_desc, int policy)
-{
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->intr_policy = policy;
-}
-
-void
-device_desc_intr_swlevel_set(device_desc_t device_desc, ilvl_t swlevel)
-{
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->intr_swlevel = swlevel;
-}
-
-void
-device_desc_intr_name_set(device_desc_t device_desc, char *name)
-{
-#ifdef LATER
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->intr_name = string_table_insert(&device_desc_string_table, name);
-#else
-	FIXME("device_desc_intr_name_set");
-#endif
-}
-
-void
-device_desc_flags_set(device_desc_t device_desc, int flags)
-{
-	if ( device_desc != (device_desc_t)0 )
-		device_desc->flags = flags;
-}
-
-
-
-/*============= device admin registry routines ===================== */
-
-/* Linked list of <admin-name,admin-val> pairs */
-typedef struct dev_admin_list_s {
-	struct dev_admin_list_s		*admin_next; 	/* next entry in the
-							 * list 
-							 */
-	char				*admin_name;	/* info label */
-	char				*admin_val;	/* actual info */
-} dev_admin_list_t;
-
-/* Device/Driver administration registry */
-typedef struct dev_admin_registry_s {
-	mrlock_t			reg_lock;	/* To allow
-							 * exclusive
-							 * access
-							 */
-	dev_admin_list_t		*reg_first;	/* first entry in 
-							 * the list
-							 */
-	dev_admin_list_t		**reg_last;	/* pointer to the
-							 * next to last entry
-							 * in the last which 
-							 * is also the place
-							 * where the new
-							 * entry gets
-							 * inserted
-							 */
-} dev_admin_registry_t;
-
-/*
-** device_driver_s associates a device driver prefix with device switch entries.
-*/
-struct device_driver_s {
-	struct device_driver_s	*dd_next;	/* next element on hash chain */
-	struct device_driver_s	*dd_prev;	/* previous element on hash chain */
-	char			*dd_prefix;	/* driver prefix string */
-	struct bdevsw		*dd_bdevsw;	/* driver's bdevsw */
-	struct cdevsw		*dd_cdevsw;	/* driver's cdevsw */
-	
-	/* driver administration specific data structures need to
-	 * maintain the list of <driver-paramater,value> pairs
-	 */
-	dev_admin_registry_t	dd_dev_admin_registry;
-	ilvl_t			dd_thread_pri;	/* default thread priority for
-						 *  all this driver's
-						 * threads.
-						 */
-
-};
-
-#define	NEW(_p)		(_p = kmalloc(sizeof(*_p), GFP_KERNEL))
-#define FREE(_p)	(kmem_free(_p))
-	
-/*
- * helpful lock macros
- */
-
-#define DEV_ADMIN_REGISTRY_INITLOCK(lockp,name)	mrinit(lockp,name)
-#define DEV_ADMIN_REGISTRY_RDLOCK(lockp)	mraccess(lockp)	       
-#define DEV_ADMIN_REGISTRY_WRLOCK(lockp)	mrupdate(lockp)	       
-#define DEV_ADMIN_REGISTRY_UNLOCK(lockp)	mrunlock(lockp)
-
-/* Initialize the registry 
- */
-static void
-dev_admin_registry_init(dev_admin_registry_t *registry)
-{
-#ifdef LATER
-	if ( registry != (dev_admin_registry_t *)0 )
-		DEV_ADMIN_REGISTRY_INITLOCK(&registry->reg_lock,
-				    "dev_admin_registry_lock");
-		registry->reg_first = NULL;
-		registry->reg_last = &registry->reg_first;
-	}
-#else
-	FIXME("dev_admin_registry_init");
-#endif
-}
-
-/*
- * add an <name , value > entry to the dev admin registry.
- * if the name already exists in the registry then change the
- * value iff the new value differs from the old value.
- * if the name doesn't exist a new list entry is created and put
- * at the end.
- */
-static void
-dev_admin_registry_add(dev_admin_registry_t	*registry,
-		       char			*name,
-		       char			*val)
-{
-#ifdef LATER
-	dev_admin_list_t	*reg_entry;
-	dev_admin_list_t	*scan = 0;
-
-	DEV_ADMIN_REGISTRY_WRLOCK(&registry->reg_lock);
-
-	/* check if the name already exists in the registry */
-	scan = registry->reg_first;
-
-	while (scan) {
-		if (strcmp(scan->admin_name,name) == 0) {
-			/* name is there in the registry */
-			if (strcmp(scan->admin_val,val)) {
-				/* old value != new value 
-				 * reallocate  memory and copy the new value
-				 */
-				FREE(scan->admin_val);
-				scan->admin_val = 
-					(char *)kern_calloc(1,strlen(val)+1);
-				strcpy(scan->admin_val,val);
-				goto out;
-			}
-			goto out;	/* old value == new value */
-		}
-		scan = scan->admin_next;
-	}
-
-	/* name is not there in the registry.
-	 * allocate memory for the new registry entry 
-	 */
-	NEW(reg_entry);
-	
-	reg_entry->admin_next   	= 0;
-	reg_entry->admin_name	= (char *)kern_calloc(1,strlen(name)+1);
-	strcpy(reg_entry->admin_name,name);
-	reg_entry->admin_val	= (char *)kern_calloc(1,strlen(val)+1);
-	strcpy(reg_entry->admin_val,val);
-
-	/* add the entry at the end of the registry */
-
-	*(registry->reg_last)	= reg_entry;
-	registry->reg_last	= &reg_entry->admin_next;
-
-out:	DEV_ADMIN_REGISTRY_UNLOCK(&registry->reg_lock);
-#endif
-	FIXME("dev_admin_registry_add");
-}
-/*
- * check if there is an info corr. to a particular
- * name starting from the cursor position in the 
- * registry
- */
-static char *
-dev_admin_registry_find(dev_admin_registry_t *registry,char *name)
-{
-#ifdef LATER
-	dev_admin_list_t	*scan = 0;
-	
-	DEV_ADMIN_REGISTRY_RDLOCK(&registry->reg_lock);
-	scan = registry->reg_first;
-
-	while (scan) {
-		if (strcmp(scan->admin_name,name) == 0) {
-			DEV_ADMIN_REGISTRY_UNLOCK(&registry->reg_lock);
-			return scan->admin_val;
-		}
-		scan = scan->admin_next;
-	}
-	DEV_ADMIN_REGISTRY_UNLOCK(&registry->reg_lock);
-	return 0;
-#else
-	FIXME("dev_admin_registry_find");
-	return(NULL);
-#endif
-}
-/*============= MAIN DEVICE/ DRIVER ADMINISTRATION INTERFACE================ */
-/*
- * return any labelled info associated with a device.
- * called by any kernel code including device drivers.
- */
-char *
-device_admin_info_get(devfs_handle_t	dev_vhdl,
-		      char		*info_lbl)
-{
-#ifdef LATER
-	char		*info = 0;
-
-	/* return value need not be GRAPH_SUCCESS as the labelled
-	 * info may not be present
-	 */
-	(void)hwgraph_info_get_LBL(dev_vhdl,info_lbl,
-				   (arbitrary_info_t *)&info);
-
-	
-	return info;
-#else
-	FIXME("device_admin_info_get");
-	return(NULL);
-#endif
-}
-
-/*
- * set labelled info associated with a device.
- * called by hwgraph infrastructure . may also be called
- * by device drivers etc.
- */
-int
-device_admin_info_set(devfs_handle_t	dev_vhdl,
-		      char		*dev_info_lbl,
-		      char		*dev_info_val)
-{
-#ifdef LATER
-	graph_error_t		rv;
-	arbitrary_info_t	old_info;
-
-	/* Handle the labelled info
-	 *		intr_target
-	 *		sw_level 
-	 * in a special way. These are part of device_desc_t
-	 * Right now this is the only case where we have 
-	 * a set of related device_admin attributes which 
-	 * are grouped together.
-	 * In case there is a need for another set we need to
-	 * take a more generic approach to solving this.
-	 * Basically a registry should be implemented. This
-	 * registry is initialized with the callbacks for the
-	 * attributes which need to handled in a special way
-	 * For example:
-	 * Consider
-	 * 		device_desc
-	 *			intr_target
-	 *			intr_swlevel
-	 * register "do_intr_target" for intr_target
-	 * register "do_intr_swlevel" for intr_swlevel.
-	 * When the device_admin interface layer gets an <attr,val> pair
-	 * it looks in the registry to see if there is a function registered to
-	 * handle "attr. If not follow the default path of setting the <attr,val>
-	 * as labelled information hanging off the vertex.
-	 * In the above example:
-	 * "do_intr_target" does what is being done below for the ADMIN_LBL_INTR_TARGET
-	 * case
-	 */		
-	if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_TARGET) ||
-	    !strcmp(dev_info_lbl,ADMIN_LBL_INTR_SWLEVEL)) {
-
-		device_desc_t	device_desc;
-		
-		/* Check if there is a default device descriptor
-		 * information for this vertex. If not dup one .
-		 */
-		if (!(device_desc = device_desc_default_get(dev_vhdl))) {
-			device_desc = device_desc_dup(dev_vhdl);
-			device_desc_default_set(dev_vhdl,device_desc);
-
-		}
-		if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_TARGET)) {
-			/* Check if a target cpu has been specified
-			 * for this device by a device administration
-			 * directive
-			 */
-#ifdef DEBUG	
-			printf(ADMIN_LBL_INTR_TARGET
-			       " dev = 0x%x "
-			       "dev_admin_info = %s"
-			       " target = 0x%x\n",
-			       dev_vhdl,
-			       dev_info_lbl,
-			       hwgraph_path_to_vertex(dev_info_val));
-#endif	
-
-			device_desc->intr_target = 
-				hwgraph_path_to_vertex(dev_info_val);
-		} else if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_SWLEVEL)) {
-			/* Check if the ithread priority level  has been 
-			 * specified for this device by a device administration
-			 * directive
-			 */
-#ifdef DEBUG	
-			printf(ADMIN_LBL_INTR_SWLEVEL
-			       " dev = 0x%x "
-			       "dev_admin_info = %s"
-			       " sw level = 0x%x\n",
-			       dev_vhdl,
-			       dev_info_lbl,
-			       atoi(dev_info_val));
-#endif	
-			device_desc->intr_swlevel = atoi(dev_info_val);
-		}
-
-	}
-	if (!dev_info_val)
-		rv = hwgraph_info_remove_LBL(dev_vhdl,
-					     dev_info_lbl,
-					     &old_info);
-	else {
-
-		rv = hwgraph_info_add_LBL(dev_vhdl,
-					  dev_info_lbl,
-					  (arbitrary_info_t)dev_info_val);
-	
-		if (rv == GRAPH_DUP)  {
-			rv = hwgraph_info_replace_LBL(dev_vhdl,
-					      dev_info_lbl,
-					      (arbitrary_info_t)dev_info_val,
-					      &old_info);
-		}
-	}
-	ASSERT(rv == GRAPH_SUCCESS);
-#endif
-	FIXME("device_admin_info_set");
-	return 0;
-}
-
-/*
- * return labelled info associated with a device driver
- * called by kernel code including device drivers
- */
-char *
-device_driver_admin_info_get(char		*driver_prefix,
-			     char		*driver_info_lbl)
-{
-#ifdef LATER
-	device_driver_t driver;
-
-	driver = device_driver_get(driver_prefix);
-	return (dev_admin_registry_find(&driver->dd_dev_admin_registry,
-					driver_info_lbl));
-#else
-	FIXME("device_driver_admin_info_get");
-	return(NULL);
-#endif
-}
-
-/*
- * set labelled info associated with a device driver.
- * called by hwgraph infrastructure . may also be called
- * from drivers etc.
- */
-int
-device_driver_admin_info_set(char		*driver_prefix,
-			     char		*driver_info_lbl,
-			     char		*driver_info_val)
-{
-#ifdef LATER
-	device_driver_t driver;
-
-	driver = device_driver_get(driver_prefix);
-	dev_admin_registry_add(&driver->dd_dev_admin_registry,	
-			       driver_info_lbl,
-			       driver_info_val);
-#endif
-	FIXME("device_driver_admin_info_set");
-	return 0;
-}
-/*================== device / driver  admin support routines================*/
-
-/* static tables created by lboot */
-extern dev_admin_info_t	dev_admin_table[];
-extern dev_admin_info_t	drv_admin_table[];
-extern int		dev_admin_table_size;
-extern int		drv_admin_table_size;
-
-/* Extend the device admin table to allow the kernel startup code to 
- * provide some device specific administrative hints
- */
-#define ADMIN_TABLE_CHUNK	100
-static dev_admin_info_t extended_dev_admin_table[ADMIN_TABLE_CHUNK];	
-static int		extended_dev_admin_table_size = 0;
-static mrlock_t		extended_dev_admin_table_lock;
-
-/* Initialize the extended device admin table */
-void
-device_admin_table_init(void)
-{
-#ifdef LATER
-	extended_dev_admin_table_size = 0;
-	mrinit(&extended_dev_admin_table_lock,
-	       "extended_dev_admin_table_lock");
-#endif
-	FIXME("device_admin_table_init");
-}
-/* Add <device-name , parameter-name , parameter-value> triple to
- * the extended device administration info table. This is helpful
- * for kernel startup code to put some hints before the hwgraph
- * is setup 
- */
-void
-device_admin_table_update(char *name,char *label,char *value)
-{
-#ifdef LATER
-	dev_admin_info_t	*p;
-
-	mrupdate(&extended_dev_admin_table_lock);
-
-	/* Safety check that we haven't exceeded array limits */
-	ASSERT(extended_dev_admin_table_size < ADMIN_TABLE_CHUNK);
-
-	if (extended_dev_admin_table_size == ADMIN_TABLE_CHUNK)
-		goto out;
-	
-	/* Get the pointer to the entry in the table where we are
-	 * going to put the new information 
-	 */
-	p = &extended_dev_admin_table[extended_dev_admin_table_size++];
-
-	/* Allocate memory for the strings and copy them in */
-	p->dai_name = (char *)kern_calloc(1,strlen(name)+1);
-	strcpy(p->dai_name,name);
-	p->dai_param_name = (char *)kern_calloc(1,strlen(label)+1);
-	strcpy(p->dai_param_name,label);
-	p->dai_param_val = (char *)kern_calloc(1,strlen(value)+1);
-	strcpy(p->dai_param_val,value);
-
-out:	mrunlock(&extended_dev_admin_table_lock);
-#endif
-	FIXME("device_admin_table_update");
-}
-/* Extend the device driver  admin table to allow the kernel startup code to 
- * provide some device driver specific administrative hints
- */
-
-static dev_admin_info_t extended_drv_admin_table[ADMIN_TABLE_CHUNK];	
-static int		extended_drv_admin_table_size = 0;
-mrlock_t		extended_drv_admin_table_lock;
-
-/* Initialize the extended device driver admin table */
-void
-device_driver_admin_table_init(void)
-{
-#ifdef LATER
-	extended_drv_admin_table_size = 0;
-	mrinit(&extended_drv_admin_table_lock,
-	       "extended_drv_admin_table_lock");
-#endif
-	FIXME("device_driver_admin_table_init");
-}
-/* Add <device-driver prefix , parameter-name , parameter-value> triple to
- * the extended device administration info table. This is helpful
- * for kernel startup code to put some hints before the hwgraph
- * is setup 
- */
-void
-device_driver_admin_table_update(char *name,char *label,char *value)
-{
-#ifdef LATER
-	dev_admin_info_t	*p;
-
-	mrupdate(&extended_dev_admin_table_lock);
-
-	/* Safety check that we haven't exceeded array limits */
-	ASSERT(extended_drv_admin_table_size < ADMIN_TABLE_CHUNK);
-
-	if (extended_drv_admin_table_size == ADMIN_TABLE_CHUNK)
-		goto out;
-	
-	/* Get the pointer to the entry in the table where we are
-	 * going to put the new information 
-	 */
-	p = &extended_drv_admin_table[extended_drv_admin_table_size++];
-
-	/* Allocate memory for the strings and copy them in */
-	p->dai_name = (char *)kern_calloc(1,strlen(name)+1);
-	strcpy(p->dai_name,name);
-	p->dai_param_name = (char *)kern_calloc(1,strlen(label)+1);
-	strcpy(p->dai_param_name,label);
-	p->dai_param_val = (char *)kern_calloc(1,strlen(value)+1);
-	strcpy(p->dai_param_val,value);
-
-out:	mrunlock(&extended_drv_admin_table_lock);
-#endif
-	FIXME("device_driver_admin_table_update");
-}
-/*
- * keeps on adding the labelled info for each new (lbl,value) pair
- * that it finds in the static dev admin table (  created by lboot)
- * and the extended dev admin table ( created if at all by the kernel startup
- *  code) corresponding to a device in the hardware graph.
- */
-void
-device_admin_info_update(devfs_handle_t	dev_vhdl)
-{
-#ifdef LATER
-	int			i = 0;
-	dev_admin_info_t	*scan;
-	devfs_handle_t		scan_vhdl;
-	
-	/* Check the static device administration info table */
-	scan = dev_admin_table;
-	while (i < dev_admin_table_size) {
-		
-		scan_vhdl = hwgraph_path_to_dev(scan->dai_name);
-		if (scan_vhdl == dev_vhdl) {
-			device_admin_info_set(dev_vhdl,
-					      scan->dai_param_name,
-					      scan->dai_param_val);
-		}
-		if (scan_vhdl != NODEV)
-			hwgraph_vertex_unref(scan_vhdl);
-		scan++;i++;
-
-	}
-	i = 0;
-	/* Check the extended device administration info table */
-	scan = extended_dev_admin_table;
-	while (i < extended_dev_admin_table_size) {
-		scan_vhdl = hwgraph_path_to_dev(scan->dai_name);
-		if (scan_vhdl == dev_vhdl) {
-			device_admin_info_set(dev_vhdl,
-					      scan->dai_param_name,
-					      scan->dai_param_val);
-		}
-		if (scan_vhdl != NODEV)
-			hwgraph_vertex_unref(scan_vhdl);
-		scan++;i++;
-
-	}
-
-
-#endif
-	FIXME("device_admin_info_update");
-}
-
-/* looks up the static drv admin table ( created by the lboot) and the extended
- * drv admin table (created if at all by the kernel startup code) 
- * for this driver specific administration info and adds it to the admin info 
- * associated with this device driver's object
- */
-void
-device_driver_admin_info_update(device_driver_t	driver)
-{
-#ifdef LATER
-	int			i = 0;
-	dev_admin_info_t	*scan;
-
-	/* Check the static device driver administration info table */
-	scan = drv_admin_table;
-	while (i < drv_admin_table_size) {
-
-		if (strcmp(scan->dai_name,driver->dd_prefix) == 0) {
-			dev_admin_registry_add(&driver->dd_dev_admin_registry,
-						scan->dai_param_name,
-					 	scan->dai_param_val);
-		}
-		scan++;i++;
-	}
-	i = 0;
-	/* Check the extended device driver administration info table */
-	scan = extended_drv_admin_table;
-	while (i < extended_drv_admin_table_size) {
-
-		if (strcmp(scan->dai_name,driver->dd_prefix) == 0) {
-			dev_admin_registry_add(&driver->dd_dev_admin_registry,
-						scan->dai_param_name,
-					 	scan->dai_param_val);
-		}
-		scan++;i++;
-	}
-#endif
-	FIXME("device_driver_admin_info_update");
-}
-
-/* =====Device Driver Support===== */
-
-
-
-/*
-** Generic device driver support routines for use by kernel modules that
-** deal with device drivers (but NOT for use by the drivers themselves).
-** EVERY registered driver currently in the system -- static or loadable --
-** has an entry in the device_driver_hash table.  A pointer to such an entry
-** serves as a generic device driver handle.
-*/
-
-#define DEVICE_DRIVER_HASH_SIZE 32
-#ifdef LATER
-lock_t device_driver_lock[DEVICE_DRIVER_HASH_SIZE];
-device_driver_t device_driver_hash[DEVICE_DRIVER_HASH_SIZE];
-static struct string_table driver_prefix_string_table;
-#endif
-
-/*
-** Initialize device driver infrastructure.
-*/
-void
-device_driver_init(void)
-{
-#ifdef LATER
-	int i;
-	extern void alenlist_init(void);
-	extern void hwgraph_init(void);
-	extern void device_desc_init(void);
-
-	ASSERT(DEVICE_DRIVER_NONE == NULL);
-	alenlist_init();
-	hwgraph_init();
-	device_desc_init();
-
-	string_table_init(&driver_prefix_string_table);
-
-	for (i=0; i<DEVICE_DRIVER_HASH_SIZE; i++) {
-		spin_lock_init(&device_driver_lock[i]);
-		device_driver_hash[i] = NULL;
-	}
-
-	/* Initialize static drivers from master.c table */
-	for (i=0; i<static_devsw_count; i++) {
-		device_driver_t driver;
-		static_device_driver_desc_t desc;
-		int pri;
-
-		desc = &static_device_driver_table[i];
-		driver = device_driver_get(desc->sdd_prefix);
-		if (!driver)
-			driver = device_driver_alloc(desc->sdd_prefix);
-		pri = device_driver_sysgen_thread_pri_get(desc->sdd_prefix);
-		device_driver_thread_pri_set(driver, pri);
-		device_driver_devsw_put(driver, desc->sdd_bdevsw, desc->sdd_cdevsw);
-	}
-#endif
-	FIXME("device_driver_init");
-}
-
-/*
-** Hash a prefix string into a hash table chain.
-*/
-static int
-driver_prefix_hash(char *prefix)
-{
-#ifdef LATER
-	int accum = 0;
-	char nextchar;
-
-	while (nextchar = *prefix++)
-		accum = accum ^ nextchar;
-
-	return(accum % DEVICE_DRIVER_HASH_SIZE);
-#else
-	FIXME("driver_prefix_hash");
-	return(0);
-#endif
-}
-
-
-/*
-** Allocate a driver handle.
-** Returns the driver handle, or NULL if the driver prefix 
-** already has a handle.
-** 
-** Upper layers prevent races among device_driver_alloc,
-** device_driver_free, and device_driver_get*.
-*/
-device_driver_t
-device_driver_alloc(char *prefix)
-{
-#ifdef LATER
-	int which_hash;
-	device_driver_t new_driver;
-	unsigned long s;
-		
-	which_hash = driver_prefix_hash(prefix);
-
-	new_driver = kern_calloc(1, sizeof(*new_driver));
-	ASSERT(new_driver != NULL);
-	new_driver->dd_prev = NULL;
-	new_driver->dd_prefix = string_table_insert(&driver_prefix_string_table, prefix);
-	new_driver->dd_bdevsw = NULL;
-	new_driver->dd_cdevsw = NULL;
-
-	dev_admin_registry_init(&new_driver->dd_dev_admin_registry);
-	device_driver_admin_info_update(new_driver);
-
-	s = mutex_spinlock(&device_driver_lock[which_hash]);
-
-#if DEBUG
-	{
-		device_driver_t drvscan;
-
-		/* Make sure we haven't already added a driver with this prefix */
-		drvscan = device_driver_hash[which_hash];
-		while (drvscan && 
-		        strcmp(drvscan->dd_prefix, prefix)) {
-			drvscan = drvscan->dd_next;
-		}
-
-		ASSERT(!drvscan);
-	}
-#endif /* DEBUG */
-
-
-	/* Add new_driver to front of hash chain. */
-	new_driver->dd_next = device_driver_hash[which_hash];
-	if (new_driver->dd_next)
-		new_driver->dd_next->dd_prev = new_driver;
-	device_driver_hash[which_hash] = new_driver;
-
-	mutex_spinunlock(&device_driver_lock[which_hash], s);
-
-	return(new_driver);
-#else
-	FIXME("device_driver_alloc");
-	return((device_driver_t)0);
-#endif
-}
-
-/*
-** Free a driver handle.
-**
-** Statically loaded drivers should never device_driver_free.
-** Dynamically loaded drivers device_driver_free when either an
-** unloaded driver is unregistered, or when an unregistered driver
-** is unloaded.
-*/
-void
-device_driver_free(device_driver_t driver)
-{
-#ifdef LATER
-	int which_hash;
-	unsigned long s;
-
-	if (!driver)
-		return;
-
-	which_hash = driver_prefix_hash(driver->dd_prefix);
-
-	s = mutex_spinlock(&device_driver_lock[which_hash]);
-
-#if DEBUG
-	{
-		device_driver_t drvscan;
-
-		/* Make sure we're dealing with the right list */
-		drvscan = device_driver_hash[which_hash];
-		while (drvscan && (drvscan != driver))
-			drvscan = drvscan->dd_next;
-
-		ASSERT(drvscan);
-	}
-#endif /* DEBUG */
-
-	if (driver->dd_next)
-		driver->dd_next->dd_prev = driver->dd_prev;
-
-	if (driver->dd_prev)
-		driver->dd_prev->dd_next = driver->dd_next;
-	else
-		device_driver_hash[which_hash] = driver->dd_next;
-
-	mutex_spinunlock(&device_driver_lock[which_hash], s);
-
-	driver->dd_next = NULL;		/* sanity */
-	driver->dd_prev = NULL;		/* sanity */
-	driver->dd_prefix = NULL;	/* sanity */
-
-	if (driver->dd_bdevsw) {
-		driver->dd_bdevsw->d_driver = NULL;
-		driver->dd_bdevsw = NULL;
-	}
-
-	if (driver->dd_cdevsw) {
-		if (driver->dd_cdevsw->d_str) {
-			str_free_mux_node(driver);
-		}
-		driver->dd_cdevsw->d_driver = NULL;
-		driver->dd_cdevsw = NULL;
-	}
-
-	kern_free(driver);
-#endif
-	FIXME("device_driver_free");
-}
-
-
-/*
-** Given a device driver prefix, return a handle to the caller.
-*/
-device_driver_t
-device_driver_get(char *prefix)
-{
-#ifdef LATER
-	int which_hash;
-	device_driver_t drvscan;
-	unsigned long s;
-
-	if (prefix == NULL)
-		return(NULL);
-		
-	which_hash = driver_prefix_hash(prefix);
-
-	s = mutex_spinlock(&device_driver_lock[which_hash]);
-
-	drvscan = device_driver_hash[which_hash];
-	while (drvscan && strcmp(drvscan->dd_prefix, prefix))
-		drvscan = drvscan->dd_next;
-
-	mutex_spinunlock(&device_driver_lock[which_hash], s);
-
-	return(drvscan);
-#else
-	FIXME("device_driver_get");
-	return((device_driver_t)0);
-#endif
-}
-
-
-/*
-** Given a block or char special file devfs_handle_t, find the 
-** device driver that controls it.
-*/
-device_driver_t
-device_driver_getbydev(devfs_handle_t device)
-{
-#ifdef LATER
-	struct bdevsw *my_bdevsw;
-	struct cdevsw *my_cdevsw;
-
-	my_cdevsw = get_cdevsw(device);
-	if (my_cdevsw != NULL)
-		return(my_cdevsw->d_driver);
-
-	my_bdevsw = get_bdevsw(device);
-	if (my_bdevsw != NULL)
-		return(my_bdevsw->d_driver);
-
-#endif
-	FIXME("device_driver_getbydev");
-	return((device_driver_t)0);
-}
-
-
-/*
-** Associate a driver with bdevsw/cdevsw pointers.
-**
-** Statically loaded drivers are permanently and automatically associated
-** with the proper bdevsw/cdevsw.  Dynamically loaded drivers associate
-** themselves when the driver is registered, and disassociate when the
-** driver unregisters.
-**
-** Returns 0 on success, -1 on failure (devsw already associated with driver)
-*/
-int
-device_driver_devsw_put(device_driver_t driver,
-			struct bdevsw *my_bdevsw,
-			struct cdevsw *my_cdevsw)
-{
-#ifdef LATER
-	int i;
-
-	if (!driver)
-		return(-1);
-
-	/* Trying to re-register data?  */
-	if (((my_bdevsw != NULL) && (driver->dd_bdevsw != NULL)) ||
-	    ((my_cdevsw != NULL) && (driver->dd_cdevsw != NULL)))
-		return(-1);
-
-	if (my_bdevsw != NULL) {
-		driver->dd_bdevsw = my_bdevsw;
-		my_bdevsw->d_driver = driver;
-		for (i = 0; i < bdevmax; i++) {
-			if (driver->dd_bdevsw->d_flags == bdevsw[i].d_flags) {
-				bdevsw[i].d_driver = driver;
-				break;
-			}
-		}
-	}
-
-	if (my_cdevsw != NULL) {
-		driver->dd_cdevsw = my_cdevsw;
-		my_cdevsw->d_driver = driver;
-		for (i = 0; i < cdevmax; i++) {
-			if (driver->dd_cdevsw->d_flags == cdevsw[i].d_flags) {
-				cdevsw[i].d_driver = driver;
-				break;
-			}
-		}
-	}
-#endif
-	FIXME("device_driver_devsw_put");
-	return(0);
-}
-
-
-/*
-** Given a driver, return the corresponding bdevsw and cdevsw pointers.
-*/
-void
-device_driver_devsw_get(	device_driver_t driver, 
-				struct bdevsw **bdevswp,
-				struct cdevsw **cdevswp)
-{
-	if (!driver) {
-		*bdevswp = NULL;
-		*cdevswp = NULL;
-	} else {
-		*bdevswp = driver->dd_bdevsw;
-		*cdevswp = driver->dd_cdevsw;
-	}
-}
-
-/*
- * device_driver_thread_pri_set
- *	Given a driver try to set its thread priority.
- *	Returns 0 on success , -1 on failure.
- */ 
-int
-device_driver_thread_pri_set(device_driver_t driver,ilvl_t pri)
-{
-	if (!driver)
-		return(-1);
-	driver->dd_thread_pri = pri;
-	return(0);
-}
-/*
- * device_driver_thread_pri_get
- * 	Given a driver return the driver thread priority.
- * 	If the driver is NULL return invalid driver thread
- * 	priority.
- */
-ilvl_t
-device_driver_thread_pri_get(device_driver_t driver)
-{
-	if (driver)
-		return(driver->dd_thread_pri);
-	else
-		return(DRIVER_THREAD_PRI_INVALID);
-}
-/*
-** Given a device driver, return it's handle (prefix).
-*/
-void
-device_driver_name_get(device_driver_t driver, char *buffer, int length)
-{
-	if (driver == NULL)
-		return;
-
-	strncpy(buffer, driver->dd_prefix, length);
-}
-
-
-/*
-** Associate a pointer-sized piece of information with a device.
-*/
-void 
-device_info_set(devfs_handle_t device, void *info)
-{
-#ifdef LATER
-	hwgraph_fastinfo_set(device, (arbitrary_info_t)info);
-#endif
-	FIXME("device_info_set");
-}
-
-
-/*
-** Retrieve a pointer-sized piece of information associated with a device.
-*/
-void *
-device_info_get(devfs_handle_t device)
-{
-#ifdef LATER
-	return((void *)hwgraph_fastinfo_get(device));
-#else
-	FIXME("device_info_get");
-	return(NULL);
-#endif
-}
-
-/*
- * Find the thread priority for a device, from the various
- * sysgen files.
- */
-int
-device_driver_sysgen_thread_pri_get(char *dev_prefix)
-{
-#ifdef LATER
-	int pri;
-	char *pri_s;
-	char *class;
-
-	extern default_intr_pri;
-	extern disk_intr_pri;
-	extern serial_intr_pri;
-	extern parallel_intr_pri;
-	extern tape_intr_pri;
-	extern graphics_intr_pri;
-	extern network_intr_pri;
-	extern scsi_intr_pri;
-	extern audio_intr_pri;
-	extern video_intr_pri;
-	extern external_intr_pri;
-	extern tserialio_intr_pri;
-
-	/* Check if there is a thread priority specified for
-	 * this driver's thread thru admin hints. If so 
-	 * use that value. Otherwise set it to its default
-	 * class value, otherwise set it to the default
-	 * value.
-	 */
-
-	if (pri_s = device_driver_admin_info_get(dev_prefix,
-						ADMIN_LBL_THREAD_PRI)) {
-		pri = atoi(pri_s);
-	} else if (class = device_driver_admin_info_get(dev_prefix,
-						ADMIN_LBL_THREAD_CLASS)) {
-		if (strcmp(class, "disk") == 0)
-			pri = disk_intr_pri;
-		else if (strcmp(class, "serial") == 0)
-			pri = serial_intr_pri;
-		else if (strcmp(class, "parallel") == 0)
-			pri = parallel_intr_pri;
-		else if (strcmp(class, "tape") == 0)
-			pri = tape_intr_pri;
-		else if (strcmp(class, "graphics") == 0)
-			pri = graphics_intr_pri;
-		else if (strcmp(class, "network") == 0)
-			pri = network_intr_pri;
-		else if (strcmp(class, "scsi") == 0)
-			pri = scsi_intr_pri;
-		else if (strcmp(class, "audio") == 0)
-			pri = audio_intr_pri;
-		else if (strcmp(class, "video") == 0)
-			pri = video_intr_pri;
-		else if (strcmp(class, "external") == 0)
-			pri = external_intr_pri;
-		else if (strcmp(class, "tserialio") == 0)
-			pri = tserialio_intr_pri;
-		else
-			pri = default_intr_pri;
-	} else
-		pri = default_intr_pri;
-
-	if (pri > 255)
-		pri = 255;
-	else if (pri < 0)
-		pri = 0;
-	return pri;
-#else
-	FIXME("device_driver_sysgen_thread_pri_get");
-	return(-1);
-#endif
-}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)