/* 
   Copyright (C) 1994 Free Software Foundation

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2, or (at
   your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

#include <cthreads.h>

enum device_type
{
  /* Kernel device types (or would be, if Mach exported this info) */
 DEV_TYPE_NONE,			/* no particular type */
 DEV_TYPE_AUDIO,		/* ADC devices, see audio_status.h */
 DEV_TYPE_CLOCK,		/* Clocks, see clock_status.h */
 DEV_TYPE_DISK,			/* Disks, see disk_status.h */
 DEV_TYPE_NET,			/* Net interfaces, see net_status.h */
 DEV_TYPE_TAPE,			/* Magnetic tape, see tape_status.h */
 DEV_TYPE_TTY,			/* terminal lines, see tty_status.h */
 DEV_TYPE_HIRES,		/* Hi-res graphics displays */

 /* Device types we know about but the kernel doesn't */

 DEV_TYPE_NULL,			/* data sink, EOF */
 DEV_TYPE_ZERO,			/* data sink, source of `\0' */
 DEV_TYPE_CTTY,			/* control terminal magic hook */
 DEV_TYPE_FDDIR,		/* directory for fd magic hooks */
 DEV_TYPE_FD,			/* fd magic hook */

 /* From here on down currently unimplemented */

 DEV_TYPE_PTYMASTER,		/* master side of pty */
 DEV_TYPE_PTYSLAVE,		/* slave side of pty */

 /* These three do *not* have the meanings they have in Unix;
    they exist here so that people that schlep around in /vmunix
    will get useful information. */
 DEV_TYPE_DRUM,			/* swap area */
 DEV_TYPE_KMEM,			/* kernel VM */
 DEV_TYPE_MEM,			/* physical memory */
};

/* For each Mach device which might exist we have one of these. */
struct mach_dev
{
  /* Name of the first part of the device */
  char *name;

  /* Type of device from list above */
  enum device_type type;

  /* TRUE if this device supports minor device numbers */
  int minordevices;

  /* Number of partitions supported per minor device number */
  int npartitions;
} mach_dev_list[];
int mach_dev_list_len;

/* For each device we have one of these */
struct device
{
  char *name;
  enum device_type type;
  int raw;
  struct stat st;
  mach_port_t port;
  struct lock_box flock;
  int opens;
  int setatime, setctime, setmtime;
} *devices;

/* For each open we have one of these */
struct peropen
{
  int openstate;
  struct device *dev;
  int refcnt;
  int flock_stat;
};

/* For each user port we have one of these */
struct protid 
{
  struct port_info pi;
  enum
    { DEVDIR, FDDIR, DEVICE } type;
  uid_t *uids, *gids;
  int nuids, ngids;
  struct peropen *po;
};

/* Each type of device supports these operations */
struct devoptable
{
  /* Open device DEV.  */
  error_t (*open)(struct device *dev, int nowait);

  /* Read from device DEV.  */
  error_t (*read)(struct device *dev, char **buf, u_int *buflen, int nowait);
  
  /* Write to device DEV. */
  error_t (*write)(struct device *dev, char *buf, u_int buflen, int *amount,
		   int nowait);

  /* Close device DEV> */
  error_t (*close)(struct device *dev);
};

struct devoptable devsw[];

int ndevices;
int nextdev;

device_t master_device;
mach_port_t master_host;

/* Locks the ST fields for each device */
mach_port_t config_file;

/* Locks the REFCNT field for each device and peropen */
spin_lock_t refcnt_lock;

struct mutex config_lock;
int configdirty;

struct port_info *fs_control;

/* libports port types */
#define PT_CNTL		0	/* filesystem control port */
#define PT_PROTID       1	/* user port */

/* Forward decls from config.h */
void read_config_file (FILE *);
void sync_config_file ();
