Subject: Re: switch table changes
To: None <friedl@informatik.uni-kl.de>
From: John Brezak <brezak@apollo.hp.com>
List: tech-kern
Date: 12/14/1994 14:45:16
> 
> I suggest some more changes to the device switch tables:
> 
> 1. Add a field for the name of the device driver.  Currently, there
> are some places in the kernel, where tables with device names are used
> for block devices.  The device name should be added to both block and
> character devices, in case they are needed somewhere.
> 
> 2. The switch table entries for a device driver should be included in
> the device driver.  The [cb]devsw tables should only contain pointers
> to these entries.  This way, all information about the driver, like
> the names of function (fdopen/Fdopen), is contained in the driver
> itself.  The 'fd' driver would define 'fd_bdevsw' and 'fd_cdevsw', and
> the device switch tables in config.c only references these entries and
> not all the functions in the driver.  It would also be possible to
> make all the driver functions static, to prevent possible name
> conflicts.
> 
> This would be similar to other configuration tables, like the table of
> VFS filesystem types or VM pagers, where only pointers to structures
> are used.
> 
> This also makes it easier to use loadable device drivers.  Since the
> driver contains the complete entry, only a pointer to this entry must
> be added to the switch table.
> 
> 3. Currently, a fixed table is used to map block device numbers to
> character device numbers.  It would be possible to include pointers in
> the {b,c}devsw entry to point to the other type of entry.  In entries
> for character devices, this pointer would be NULL.
> 
> -- 

OSF/1's device sub-system looked much like this. Here is a driver template for
OSF/1 that shows some of the structure you describe.

--------------
#include "sa.h"
#if SA > 0

#include <sys/types.h>

#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/buf.h>
#include <sys/user.h>
#include <sys/mode.h>
#include <sys/systm.h>
#include <sys/reboot.h>
#include <sys/vmparam.h>
#include <sys/uio.h>
#include <vm/vm_kern.h>
#include <sys/proc.h>
#include <sys/conf.h>
#include <sys/sysconfig.h>

/*ARGSUSED*/
saopen(dev, flags, fmt, cred)
        dev_t dev;
        int flags, fmt;
        struct ucred *cred;
{
        return(ENODEV);
}

/*ARGSUSED*/
int
saclose(dev, flag, mode, cred, private)
	dev_t		dev;			/* major, minor numbers */
	int		flag;			/* not used */
	int		mode;			/* character or block flag */
	struct ucred	*cred;			/* not used */
	void		*private;		/* not used */
{
        return(ENODEV);
}

/*ARGSUSED*/
sawrite(dev, uio)
        dev_t	 	dev;
        struct uio	*uio;
{
        return(ENODEV);
}

/*ARGSUSED*/
int
saioctl(dev, cmd, addr, mode)		/* Non-streams ioctl */
        int	dev;
        int	cmd;
        caddr_t	addr;
        int	mode;
{
        return(ENOTTY);
}

extern int seltrue();

dev_t sa_cdev;

static struct cdevsw sa_cdeventry = {
	saopen,		saclose,	nodev,		sawrite,
	saioctl,	nodev,		nulldev,	0,
	seltrue,	nodev		DEV_FUNNEL_NULL
};

int
sa_configure(
	 sysconfig_op_t	op,
	 caddr_t	indata,
	 size_t		indatalen,
	 caddr_t	outdata,
	 size_t		outdatalen
	     )
{
	int		i, configured, error = 0;
	dev_t		dev;
	struct subsystem_info	info;

	strcpy(info.subsystem_name, "sa");
	configured = ((!subsys_reg(SUBSYS_GET_INFO, &info)) &&
		      info.config_flag);
	if ((configured && op == SYSCONFIG_CONFIGURE) ||
	    (!configured &&  op != SYSCONFIG_CONFIGURE))
		return (EALREADY);

	switch (op) {
	case SYSCONFIG_CONFIGURE:
		if ((sa_cdev = cdevsw_add(NODEV, &sa_cdeventry)) == NODEV) {
			printf("sa: found cdev 0x%x in use\n", sa_cdev);
			error = ENODEV;
			break;
		}
                printf("sa: PC speaker audio driver configured. (major=%d)\n",
                       major(sa_cdev));
		break;

	case SYSCONFIG_UNCONFIGURE:
		if (cdevsw_del(sa_cdev) < 0) {
			printf("sa: cdev not found cdev 0x%x\n", sa_cdev);
			error = ENODEV;
			break;
		}
                printf("sa: PC speaker audio driver unconfigured.\n");
                break;
                
	case SYSCONFIG_RECONFIGURE:
	case SYSCONFIG_QUERYSIZE:
	case SYSCONFIG_QUERY:
		error = EINVAL;
		break;
	default:
		error = EINVAL;
		break;
	}
	return (error);
}

#endif	/* NSA > 0 */


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 John Brezak                    UUCP:     uunet!apollo.hp!brezak
 Hewlett Packard/Apollo         Internet: brezak@ch.hp.com
 300 Apollo Drive               Phone:    (508) 436-4915
 Chelmsford, Massachusetts      Fax:      (508) 436-5140



=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 John Brezak                    UUCP:     uunet!apollo.hp!brezak
 Hewlett Packard/Apollo         Internet: brezak@ch.hp.com
 300 Apollo Drive               Phone:    (508) 436-4915
 Chelmsford, Massachusetts      Fax:      (508) 436-5140