summaryrefslogtreecommitdiff
path: root/sys/miscfs/devfs/devfs_back.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/miscfs/devfs/devfs_back.c')
-rw-r--r--sys/miscfs/devfs/devfs_back.c467
1 files changed, 0 insertions, 467 deletions
diff --git a/sys/miscfs/devfs/devfs_back.c b/sys/miscfs/devfs/devfs_back.c
deleted file mode 100644
index 20a69e5a97d2..000000000000
--- a/sys/miscfs/devfs/devfs_back.c
+++ /dev/null
@@ -1,467 +0,0 @@
-
-/*
- * Written by Julian Elischer (julian@DIALix.oz.au)
- *
- * $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_back.c,v 1.4 1995/09/03 05:43:38 julian Exp $
- */
-
-#include "param.h"
-#include "systm.h"
-#include "types.h"
-#include "kernel.h"
-#include "file.h" /* define FWRITE ... */
-#include "conf.h"
-#include "stat.h"
-#include "mount.h"
-#include "vnode.h"
-#include "malloc.h"
-#include "dir.h" /* defines dirent structure */
-#include "devfsdefs.h"
-#include "sys/devfsext.h"
-
-
-SYSINIT(devfs, SI_SUB_DEVFS, SI_ORDER_FIRST, devfs_sinit, NULL)
-
-devnm_p dev_root; /* root of the backing tree */
-
-/*
- * Set up the root directory node in the backing plane
- * This is happenning before the vfs system has been
- * set up yet, so be careful about what we reference..
- * Notice that the ops are by indirection.. as they haven't
- * been set up yet!
- */
-void devfs_sinit() /*proto*/
-{
- int retval; /* we will discard this */
- /*
- * call the right routine at the right time with the right args....
- */
- retval = dev_add_node("root",NULL,DEV_DIR,NULL,&dev_root);
- printf("DEVFS: ready for devices\n");
-}
-
-/***********************************************************************\
-* Given a starting node (0 for root) and a pathname, return the node *
-* for the end item on the path. It MUST BE A DIRECTORY. If the 'CREATE' *
-* option is true, then create any missing nodes in the path and create *
-* and return the final node as well. *
-* Generally, this MUST be the first function called by any module *
-* as it also calls the initial setup code, in case it has never been *
-* done yet. *
-* This is used to set up a directory, before making nodes in it.. *
-* *
-* Warning: This function is RECURSIVE. *
-* char *path, find this dir (err if not dir) *
-* dn_p dirnode, starting point (0 = root) *
-* int create, create path if not found *
-* dn_p *dn_pp) where to return the node of the dir *
-\***********************************************************************/
-int dev_finddir(char *orig_path, dn_p dirnode, int create, dn_p *dn_pp) /*proto*/
-{
- devnm_p devnmp;
- char pathbuf[DEVMAXPATHSIZE];
- char *path;
- char *name;
- register char *cp;
- int retval;
-
-
- DBPRINT(("dev_finddir\n"));
- if(!dirnode) dirnode = dev_root->dnp;
- if(dirnode->type != DEV_DIR) return ENOTDIR;
- if(strlen(orig_path) > (DEVMAXPATHSIZE - 1)) return ENAMETOOLONG;
- path = pathbuf;
- strcpy(path,orig_path);
- while(*path == '/') path++; /* always absolute, skip leading / */
- /***************************************\
- * find the next segment of the name *
- \***************************************/
- cp = name = path;
- while((*cp != '/') && (*cp != 0))
- {
- cp++;
- }
- /***********************************************\
- * Check to see if it's the last component *
- \***********************************************/
- if(*cp)
- {
- path = cp + 1; /* path refers to the rest */
- *cp = 0; /* name is now a separate string */
- if(!(*path))
- {
- path = (char *)0; /* was trailing slash */
- }
- }
- else
- {
- path = (char *)0; /* no more to do */
- }
-
- /***************************************\
- * Start scanning along the linked list *
- \***************************************/
- devnmp = dirnode->by.Dir.dirlist;
- while(devnmp && strcmp(devnmp->name,name))
- {
- devnmp = devnmp->next;
- }
- if(devnmp)
- { /* check it's a directory */
- if(devnmp->dnp->type != DEV_DIR) return ENOTDIR;
- }
- else
- {
- /***************************************\
- * The required element does not exist *
- * So we will add it if asked to. *
- \***************************************/
- if(!create) return ENOENT;
-
- if(retval = dev_add_node(name, dirnode ,DEV_DIR,
- NULL, &devnmp))
- {
- return retval;
- }
- }
- if(path) /* decide whether to recurse more or return */
- {
- return (dev_finddir(path,devnmp->dnp,create,dn_pp));
- }
- else
- {
- *dn_pp = devnmp->dnp;
- return 0;
- }
-}
-
-/***********************************************************************\
-* Add a new element to the devfs backing structure. *
-* If we're creating a root node, then dirname is NULL *
-\***********************************************************************/
-int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, devnm_p *devnm_pp) /*proto*/
-{
- devnm_p devnmp;
- devnm_p realthing; /* needed to create an alias */
- dn_p dnp;
- int retval;
-
- DBPRINT(("dev_add_node\n"));
- if(dirnode ) {
- if(dirnode->type != DEV_DIR) return(ENOTDIR);
-
- retval = dev_finddir(name,dirnode,0,&dnp); /*don't create!*/
- dnp = NULL; /*just want the return code..*/
- if(retval != ENOENT) /* only acceptable answer */
- return(EEXIST);
- }
- /*
- * make sure the name is legal
- */
- if(strlen(name) > (DEVMAXNAMESIZE - 1)) return (ENAMETOOLONG);
- /*
- * Allocate and fill out a new backing node
- */
- if(!(devnmp = (devnm_p)malloc(sizeof(devnm_t),
- M_DEVFSBACK, M_NOWAIT)))
- {
- return ENOMEM;
- }
- bzero(devnmp,sizeof(devnm_t));
- if(!(dnp = (dn_p)malloc(sizeof(devnode_t),
- M_DEVFSNODE, M_NOWAIT)))
- {
- free(devnmp,M_DEVFSBACK);
- return ENOMEM;
- }
- bzero(dnp,sizeof(devnode_t));
- /*
- * Link hte two together
- * include the implicit link in the count of links to the devnode..
- * this stops it from being accidentally freed later.
- */
- devnmp->dnp = dnp;
- dnp->links = 1; /* implicit from our own name-node */
-
- /*
- * note the node type we are adding
- * and set the creation times to NOW
- * put in it's name
- */
- strcpy(devnmp->name,name);
- dnp->type = entrytype;
- TIMEVAL_TO_TIMESPEC(&time,&(dnp->ctime))
- dnp->mtime = dnp->ctime;
- dnp->atime = dnp->ctime;
-
- /*
- * And set up a new 'clones' list (empty)
- */
- devnmp->prev_frontp = &(devnmp->next_front);
-
- /*
- * Check if we are making a root node..
- * (with no parent)
- */
- if(dirnode) {
- /*
- * Put it on the END of the linked list of directory entries
- */
- devnmp->parent = dirnode;
- devnmp->prevp = dirnode->by.Dir.dirlast;
- devnmp->next = *(devnmp->prevp); /* should be NULL */ /*right?*/
- *(devnmp->prevp) = devnmp;
- dirnode->by.Dir.dirlast = &(devnmp->next);
- dirnode->by.Dir.entrycount++;
- }
- /*
- * return the answer
- */
- switch(entrytype) {
- case DEV_DIR:
- /*
- * As it's a directory, make sure it has a null entries list
- */
- dnp->by.Dir.dirlast =
- &(dnp->by.Dir.dirlist);
- dnp->by.Dir.dirlist = (devnm_p)0;
- if ( dirnode ) {
- dnp->by.Dir.parent = (dn_p)dirnode;
- } else {
- /* root loops to self */
- dnp->by.Dir.parent = dnp;
- }
- dnp->by.Dir.parent->links++; /* account for .. */
- dnp->links++; /* for .*/
- dnp->by.Dir.myname = devnmp;
- /*
- * make sure that the ops associated with it are the ops
- * that we use (by default) for directories
- */
- dnp->ops = &devfs_vnodeop_p;
- dnp->mode |= 0555; /* default perms */
- break;
- case DEV_BDEV:
- /*
- * Make sure it has DEVICE type ops
- * and device specific fields are correct
- */
- dnp->ops = &dev_spec_vnodeop_p;
- dnp->by.Bdev.bdevsw = by->Bdev.bdevsw;
- dnp->by.Bdev.dev = by->Bdev.dev;
- break;
- case DEV_CDEV:
- /*
- * Make sure it has DEVICE type ops
- * and device specific fields are correct
- */
- dnp->ops = &dev_spec_vnodeop_p;
- dnp->by.Cdev.cdevsw = by->Cdev.cdevsw;
- dnp->by.Cdev.dev = by->Cdev.dev;
- break;
- case DEV_DDEV:
- /*
- * store the address of (the address of) the ops
- * and the magic cookie to use with them
- */
- dnp->by.Ddev.arg = by->Ddev.arg;
- dnp->ops = by->Ddev.ops;
- break;
-
-
- case DEV_ALIAS:
- /*
- * point to the node we want to shadow
- * Also store the fact we exist so that aliases
- * can be deleted accuratly when the original node
- * is deleted.. (i.e. when device is removed)
- */
- realthing = by->Alias.realthing;
- dnp->by.Alias.realthing = realthing;
- dnp->by.Alias.next = realthing->as.back.aliases;
- realthing->as.back.aliases = devnmp;
- realthing->as.back.alias_count++;
- break;
- }
- /*
- * If we have a parent, then maybe we should duplicate
- * ourselves onto any plane that the parent is on...
- * Though this may be better handled elsewhere as
- * it stops this routine from being used for front nodes
- */
- if(dirnode) {
- if(retval = devfs_add_fronts(dirnode->by.Dir.myname,devnmp))
- {
- /*XXX*//* no idea what to do if it fails... */
- return retval;
- }
- }
-
- *devnm_pp = devnmp;
- return 0 ;
-}
-
-/***********************************************************************
- * remove all fronts to this dev and also it's aliases,
- * Then remove this node.
- * For now only allow DEVICE nodes to go.. XXX
- * directory nodes are more complicated and may need more work..
- */
-int dev_remove(devnm_p devnmp) /*proto*/
-{
- devnm_p alias;
-
- DBPRINT(("dev_remove\n"));
- /*
- * Check the type of the node.. for now don't allow dirs
- */
- switch(devnmp->dnp->type)
- {
- case DEV_BDEV:
- case DEV_CDEV:
- case DEV_DDEV:
- case DEV_ALIAS:
- case DEV_SLNK:
- break;
- case DEV_DIR:
- default:
- return(EINVAL);
- }
- /*
- * Free each alias
- */
- while ( devnmp->as.back.alias_count)
- {
- alias = devnmp->as.back.aliases;
- devnmp->as.back.aliases = alias->dnp->by.Alias.next;
- devnmp->as.back.alias_count--;
- devfs_dn_free(alias->dnp);
- free (alias, M_DEVFSBACK);
- }
- /*
- * Now remove front items of the Main node itself
- */
- devfs_remove_fronts(devnmp);
-
- /*
- * now we should free the main node
- */
- devfs_dn_free(devnmp->dnp);
- free (devnmp, M_DEVFSBACK);
- return 0;
-}
-
-int dev_touch(devnm_p key) /* update the node for this dev */ /*proto*/
-{
- DBPRINT(("dev_touch\n"));
- TIMEVAL_TO_TIMESPEC(&time,&(key->dnp->mtime))
- return 0; /*XXX*/
-}
-
-void devfs_dn_free(dn_p dnp) /*proto*/
-{
- if(dnp->links <= 0)
- {
- printf("devfs node reference count bogus\n");
- Debugger("devfs_dn_free");
- return;
- }
- if(--dnp->links == 0 )
- {
- devfs_dropvnode(dnp);
- free (dnp, M_DEVFSNODE);
- }
-}
-/***********************************************************************\
-* UTILITY routine: *
-* Return the major number for the cdevsw entry containing the given *
-* address. *
-\***********************************************************************/
-int get_cdev_major_num(caddr_t addr) /*proto*/
-{
- int index = 0;
-
- DBPRINT(("get_cdev_major_num\n"));
- while (index < nchrdev)
- {
- if(((caddr_t)(cdevsw[index].d_open) == addr)
- ||((caddr_t)(cdevsw[index].d_read) == addr)
- ||((caddr_t)(cdevsw[index].d_ioctl) == addr))
- {
- return index;
- }
- index++;
- }
- return -1;
-}
-
-int get_bdev_major_num(caddr_t addr) /*proto*/
-{
- int index = 0;
-
- DBPRINT(("get_bdev_major_num\n"));
- while (index < nblkdev)
- {
- if(((caddr_t)(bdevsw[index].d_open) == addr)
- ||((caddr_t)(bdevsw[index].d_strategy) == addr)
- ||((caddr_t)(bdevsw[index].d_ioctl) == addr))
- {
- return index;
- }
- index++;
- }
- return -1;
-}
-
-/***********************************************************************\
-* Add the named device entry into the given directory, and make it *
-* The appropriate type... (called (sometimes indirectly) by drivers..) *
-\***********************************************************************/
-void *dev_add(char *path,
- char *name,
- void *funct,
- int minor,
- int chrblk,
- uid_t uid,
- gid_t gid,
- int perms)
-{
- devnm_p new_dev;
- dn_p dnp; /* devnode for parent directory */
- int retval;
- int major ;
- union typeinfo by;
-
- DBPRINT(("dev_add\n"));
- retval = dev_finddir(path,NULL,1,&dnp);
- if (retval) return 0;
- switch(chrblk)
- {
- case DV_CHR:
- major = get_cdev_major_num(funct);
- by.Cdev.cdevsw = cdevsw + major;
- by.Cdev.dev = makedev(major, minor);
- if( dev_add_node(name, dnp, DEV_CDEV,
- &by,&new_dev))
- return 0;
- break;
- case DV_BLK:
- major = get_bdev_major_num(funct);
- by.Bdev.bdevsw = bdevsw + major;
- by.Bdev.dev = makedev(major, minor);
- if( dev_add_node(name, dnp, DEV_BDEV,
- &by, &new_dev))
- return 0;
- break;
- default:
- return(0);
- }
- new_dev->dnp->gid = gid;
- new_dev->dnp->uid = uid;
- new_dev->dnp->mode |= perms;
- return new_dev;
-}
-
-
-