From 3efcc3770a79988affebf6bed5beefbaf2072527 Mon Sep 17 00:00:00 2001
From: Thomas Bushnell <thomas@gnu.org>
Date: Mon, 26 Apr 1999 05:16:15 +0000
Subject: Sun Mar 14 18:53:01 1999  Thomas Bushnell, BSG  <tb@mit.edu>

	* device/ds_routines.c (ds_read_done): When touching memory to
	mark it dirty, make sure we say "volatile" so the compiler doesn't
	optimize it out.

1999-02-27  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* i386/i386at/i386at_ds_routines.c: Include
	<i386/linux/device-drivers.h> instead of <linux/device-drivers.h>.
	* device/ds_routines.c [LINUX_DEV]: Likewise.
	* i386/linux/Makefile.in (linux-gen-flags): Fix an extra slash.
	(distclean): Remove asm links.
	* linux/src/COPYING: Copied from linux-2.0.36.

1999-02-04  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* device/kmsg.c (kmsginit): Add a missing semicolon.
	(kmsggetstat): Fix typos,
	DEV_GET_DEVICE_SIZE -> DEV_GET_SIZE_DEVICE_SIZE and
	DEV_GET_RECORD_SIZE -> DEV_GET_SIZE_RECORD_SIZE.
	(kmsg_putchar): Fix a typo kmsg_done_init -> kmsg_init_done.
	* linux/dev/glue/block.c (device_get_status): Allocate a hd_geometry
	on the stack.
	* linux/dev/drivers/block/ide.c: New file.
	* linux/dev/drivers/scsi/sd_ioctl.c: New file.

1999-02-02  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* i386/i386at/kd_event.c (kbdgetstat): Fix a typo
	DEV_GET_SIZES -> DEV_GET_SIZE.
	* i386/i386at/kd_mouse.c (mousegetstat): Likewise.
	* device/kmsg.c (kmsggetstat): Likewise.

1999-02-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* linux/dev/glue/block.c (dev_getstat): Fix a missing `struct'.
	* device/cons.c (cninit): Don't call kmsginit.
	* kmsg.c (kmsg_buffer): Defined as static.
	(kmsg_write_offset): Likewise.
	(kmsg_read_offset): Likewise.
	(kmsg_read_queue): Likewise.
	(kmsg_in_use): Likewise.
	(kmsg_lock): Likewise.
	(kmsginit): Likewise, and call queue_init instead of setting
	PREV and NEXT manually.
	(kmsg_done_init): New variable.
	(kmsg_putchar): Call kmsginit if not initialized yet.
	(kmsggetstat): New function.
	* kmsg.h (kmsggetstat): Add the prototype.
	* i386/i386at/kd_event.c (kbdgetstat): Handle DEV_GET_SIZE.
	(kbdread): Check if the amount a user specify is a multiple
	of sizeof(kd_event).
	* i386/i386at/kd_mouse.c (mousegetstat): New function.
	(mouseread): Check if the amount a user specify is a multiple
	of sizeof(kd_event).
	* i386/i386at/conf.c (dev_name_list): Set the mouse getstat entry
	to mousegetstat and the kmsg getstat entry to kmsggetstat.
	Use MACH_COM instead of NCOM to determine if com is used.
	Use MACH_LPR instead of NLPR to determine if lpr is used.
	* configure.in (--enable-com): New option.
	(--enable-lpr): Likewise.
	* Makefile.in (enable_com): New variable.
	(enable_lpr): Likewise.
	* i386/Makefrag (i386at-files): Remove com.c.
	(objfiles): Add com.o if enable_com is yes, and lpr.o if enable_lpr
	is yes.

1999-01-26  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* device/kmsg.c (kmsgopen): Added simple_lock and simple_unlock.
	(ksmgclose): Likewise.

1999-01-24  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* device/kmsg.h (KMSGBUFSIZE): Deleted.
	* device/kmsg.c: Rewritten completely to provide stream interface.
	* linux/dev/glue/block.c (device_getstat): Added V_GETPARMS support.
	* config.guess: New version from automake-1.4.
	* config.sub: Likewise.
	* install-sh: Likewise.

1999-01-16  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* device/kmsg.c: Fixed the copyright notice.
	(MACH_KMSG): Removed.
	* Makefile.in (enable_kmsg): New variable.
	(objfiles): Add kmsg.o, if and only if enable_kmsg is yes.

1998-12-18  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* Makefile.in (objfiles): Add kmsg.o.
	* device/cons.c: Include <device/io_req.h>.
	* device/kmsg.c: Rewritten almost entirely.

1998-12-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	Add kmsg device.

	* Makefile.in (device-files): Add kmsg.c and kmsg.h.
	* configure.in (--enable-kmsg): New option.
	* device/cons.c: Include kmsg.h.
	(cninit): Call kmsginit if MACH_KMSG is defined.
	(cnputc): Call kmsg_putchar if MACH_KMSG is defined.
	* device/kmsg.c: New file.
	* device/kmsg.h: Likewise.
	* i386/i386at/conf.c (dev_name_list): Add kmsg entry.

1998-12-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* i386/i386at/i386at_ds_routines.c: Include <linux/device-drivers.h>
	only if LINUX_DEV is defined. Reported by UCHIYAMA Yasushi
	<uch@nop.or.jp>.
	* device/ds_routines.c: Likewise.
	* configure.in: AC_CONFIG_SUBDIRS(linux) instead of linuxdev.
	(--disable-linuxdev): New option.
	* linux/Makefile.in (CPPFLAGS): Remove -DLINUX_DEV, and add @DEFS@.
	(objfiles): Add linux.o only if LINUX_DEV is defined.
	* linux/Drivers.in (--disable-linuxdev): New option.
	* i386/Makefrag (DEFINES): Remove -DLINUX_DEV.

1998-11-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>

	* i386/i386at/gpl/linux: Moved to ...
	* linuxdev: ... here.
	* i386/Makefrag: Linux drivers specific code moved to ...
	* linuxdev/Makefrag: ... here.
	* i386/Files: Recreated.
	* i386/Subdirs: Likewise.
	* linuxdev/drivers: New directory.
	* linuxdev/arch: Likewise.
	* linuxdev/arch/i386: Likewise.
	* linuxdev/{block,scsi,net,pci}: Moved to ...
	* linuxdev/drivers/{block,scsi,net,pci}: ... here.
	* i386/{Drivers.in,device-drivers.h.in,driverlist.in}: Moved to ...
	* linuxdev/{Drivers.in,device-drivers.h.in,driverlist.in}: ... here.
	* linuxdev/{linux_emul.h,linux_*.c}: Moved to ...
	* linuxdev/arch/i386/{linux_emul.h,linux_*.c}: ... here.
	* linuxdev/arch/i386/linux_block.c: Include <linux_emul.h>, instead
	of <i386at/gpl/linux/linux_emul.h>.
	* linuxdev/arch/i386/linux_init.c: Likewise.
	* linuxdev/arch/i386/linux_kmem.c: Likewise.
	* linuxdev/arch/i386/linux_misc.c: Likewise.
	* linuxdev/arch/i386/linux_net.c: Likewise.
	* linuxdev/arch/i386/linux_sched.c: Likewise.
	* device/ds_routines.c: Include <linuxdev/device-drivers.h>, instead
	of <i386/device-drivers.h>.
	* linuxdev/arch/i386/linux_init.c: Likewise.
	* linuxdev/include/linux/autoconf.h: Likewise.
	* Makefile.in: Include $(srcdir)/linuxdev/Makefrag.
	* linuxdev/Drivers.in (AC_INIT): Use include/linux/autoconf.h,
	instead of i386/i386asm.sym.
---
 device/cons.c        |  11 +++
 device/ds_routines.c |   4 +-
 device/kmsg.c        | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++
 device/kmsg.h        |  15 ++++
 4 files changed, 276 insertions(+), 1 deletion(-)
 create mode 100644 device/kmsg.c
 create mode 100644 device/kmsg.h

(limited to 'device')

diff --git a/device/cons.c b/device/cons.c
index 954f527..a06fdf3 100644
--- a/device/cons.c
+++ b/device/cons.c
@@ -37,6 +37,11 @@
 #include <hpdev/cons.h>
 #endif
 
+#ifdef MACH_KMSG
+#include <device/io_req.h>
+#include <kmsg.h>
+#endif
+
 static	int cn_inited = 0;
 static	struct consdev *cn_tab = 0;	/* physical console device info */
 #ifndef MACH_KERNEL
@@ -86,6 +91,7 @@ cninit()
 		    (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
 			cn_tab = cp;
 	}
+	
 	/*
 	 * Found a console, initialize it.
 	 */
@@ -243,6 +249,11 @@ cnputc(c)
 	if (c == 0)
 		return;
 
+#ifdef MACH_KMSG
+	/* XXX: Assume that All output routines always use cnputc. */
+	kmsg_putchar (c);
+#endif
+	
 	if (cn_tab) {
 		(*cn_tab->cn_putc)(cn_tab->cn_dev, c);
 		if (c == '\n')
diff --git a/device/ds_routines.c b/device/ds_routines.c
index e370503..7b74ad5 100644
--- a/device/ds_routines.c
+++ b/device/ds_routines.c
@@ -66,7 +66,9 @@
 
 #ifdef i386
 #include <i386at/device_emul.h>
-#include <i386/device-drivers.h>
+#ifdef LINUX_DEV
+#include <i386/linux/device-drivers.h>
+#endif
 #endif
 
 #ifdef i386
diff --git a/device/kmsg.c b/device/kmsg.c
new file mode 100644
index 0000000..a887666
--- /dev/null
+++ b/device/kmsg.c
@@ -0,0 +1,247 @@
+/* GNU Mach Kernel Message Device.
+   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Written by OKUJI Yoshinori.
+
+This 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 software 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 the software; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Now kmsg provides stream interface, not random access methods.  */
+
+#include <sys/types.h>
+#include <device/conf.h>
+#include <device/io_req.h>
+#include <mach/boolean.h>
+#include <kern/lock.h>
+#include <kmsg.h>
+
+
+#define KMSGBUFSIZE	(4096)  /* XXX */
+
+/* Simple array for buffering messages */
+static char kmsg_buffer[KMSGBUFSIZE];
+/* Point to the offset to write */
+static int kmsg_write_offset;
+/* Point to the offset to read */
+static int kmsg_read_offset;
+/* I/O request queue for blocking read */
+static queue_head_t kmsg_read_queue;
+/* Used for exclusive access to the device */
+static int kmsg_in_use;
+/* Used for exclusive access to the routines */
+static simple_lock_data_t kmsg_lock;
+/* If already initialized or not  */
+static int kmsg_init_done = 0;
+
+/* Kernel Message Initializer */
+static void
+kmsginit (void)
+{
+  kmsg_write_offset = 0;
+  kmsg_read_offset = 0;
+  queue_init (&kmsg_read_queue);
+  kmsg_in_use = 0;
+  simple_lock_init (&kmsg_lock);
+}
+
+/* Kernel Message Open Handler */
+io_return_t
+kmsgopen (dev_t dev, int flag, io_req_t ior)
+{
+  simple_lock (&kmsg_lock);
+  if (kmsg_in_use)
+    {
+      simple_unlock (&kmsg_lock);
+      return D_ALREADY_OPEN;
+    }
+  
+  kmsg_in_use = 1;
+
+  simple_unlock (&kmsg_lock);
+  return D_SUCCESS;
+}
+
+/* Kernel Message Close Handler */
+io_return_t
+kmsgclose (dev_t dev, int flag)
+{
+  simple_lock (&kmsg_lock);
+  kmsg_in_use = 0;
+  
+  simple_unlock (&kmsg_lock);
+  return D_SUCCESS;
+}
+
+static boolean_t kmsg_read_done (io_req_t ior);
+
+/* Kernel Message Read Handler */
+io_return_t
+kmsgread (dev_t dev, io_req_t ior)
+{
+  int err;
+  int amt, len;
+  
+  err = device_read_alloc (ior, ior->io_count);
+  if (err != KERN_SUCCESS)
+    return err;
+
+  simple_lock (&kmsg_lock);
+  if (kmsg_read_offset == kmsg_write_offset)
+    {
+      /* The queue is empty.  */
+      if (ior->io_mode & D_NOWAIT)
+	{
+	  simple_unlock (&kmsg_lock);
+	  return D_WOULD_BLOCK;
+	}
+
+      ior->io_done = kmsg_read_done;
+      enqueue_tail (&kmsg_read_queue, ior);
+      simple_unlock (&kmsg_lock);
+      return D_IO_QUEUED;
+    }
+
+  len = kmsg_write_offset - kmsg_read_offset;
+  if (len < 0)
+    len += KMSGBUFSIZE;
+
+  amt = ior->io_count;
+  if (amt > len)
+    amt = len;
+  
+  if (kmsg_read_offset + amt <= KMSGBUFSIZE)
+    {
+      memcpy (ior->io_data, kmsg_buffer + kmsg_read_offset, amt);
+    }
+  else
+    {
+      int cnt;
+
+      cnt = KMSGBUFSIZE - kmsg_read_offset;
+      memcpy (ior->io_data, kmsg_buffer + kmsg_read_offset, cnt);
+      memcpy (ior->io_data + cnt, kmsg_buffer, amt - cnt);
+    }
+
+  kmsg_read_offset += amt;
+  if (kmsg_read_offset >= KMSGBUFSIZE)
+    kmsg_read_offset -= KMSGBUFSIZE;
+  
+  ior->io_residual = ior->io_count - amt;
+  
+  simple_unlock (&kmsg_lock);
+  return D_SUCCESS;
+}
+
+static boolean_t
+kmsg_read_done (io_req_t ior)
+{
+  int err;
+  int amt, len;
+
+  simple_lock (&kmsg_lock);
+  if (kmsg_read_offset == kmsg_write_offset)
+    {
+      /* The queue is empty.  */
+      ior->io_done = kmsg_read_done;
+      enqueue_tail (&kmsg_read_queue, ior);
+      simple_unlock (&kmsg_lock);
+      return FALSE;
+    }
+
+  len = kmsg_write_offset - kmsg_read_offset;
+  if (len < 0)
+    len += KMSGBUFSIZE;
+
+  amt = ior->io_count;
+  if (amt > len)
+    amt = len;
+  
+  if (kmsg_read_offset + amt <= KMSGBUFSIZE)
+    {
+      memcpy (ior->io_data, kmsg_buffer + kmsg_read_offset, amt);
+    }
+  else
+    {
+      int cnt;
+
+      cnt = KMSGBUFSIZE - kmsg_read_offset;
+      memcpy (ior->io_data, kmsg_buffer + kmsg_read_offset, cnt);
+      memcpy (ior->io_data + cnt, kmsg_buffer, amt - cnt);
+    }
+
+  kmsg_read_offset += amt;
+  if (kmsg_read_offset >= KMSGBUFSIZE)
+    kmsg_read_offset -= KMSGBUFSIZE;
+  
+  ior->io_residual = ior->io_count - amt;
+
+  simple_unlock (&kmsg_lock);
+  ds_read_done (ior);
+  
+  return TRUE;
+}
+
+io_return_t
+kmsggetstat (dev_t dev, int flavor, int *data, unsigned int *count)
+{
+  switch (flavor)
+    {
+    case DEV_GET_SIZE:
+      data[DEV_GET_SIZE_DEVICE_SIZE] = 0;
+      data[DEV_GET_SIZE_RECORD_SIZE] = 1;
+      *count = DEV_GET_SIZE_COUNT;
+      break;
+
+    default:
+      return D_INVALID_OPERATION;
+    }
+
+  return D_SUCCESS;
+}
+
+/* Write to Kernel Message Buffer */
+void
+kmsg_putchar (int c)
+{
+  io_req_t ior;
+  int offset;
+
+  /* XXX: cninit is not called before cnputc is used. So call kmsginit
+     here if not initialized yet.  */
+  if (!kmsg_init_done)
+    {
+      kmsginit ();
+      kmsg_init_done = 1;
+    }
+  
+  simple_lock (&kmsg_lock);
+  offset = kmsg_write_offset + 1;
+  if (offset == KMSGBUFSIZE)
+    offset = 0;
+
+  if (offset == kmsg_read_offset)
+    {
+      /* Discard C.  */
+      simple_unlock (&kmsg_lock);
+      return;
+    }
+
+  kmsg_buffer[kmsg_write_offset++] = c;
+  if (kmsg_write_offset == KMSGBUFSIZE)
+    kmsg_write_offset = 0;
+
+  while ((ior = (io_req_t) dequeue_head (&kmsg_read_queue)) != NULL)
+    iodone (ior);
+
+  simple_unlock (&kmsg_lock);
+}
diff --git a/device/kmsg.h b/device/kmsg.h
new file mode 100644
index 0000000..e0e7a67
--- /dev/null
+++ b/device/kmsg.h
@@ -0,0 +1,15 @@
+#ifndef _DEVICE_KMSG_H_
+#define _DEVICE_KMSG_H_	1
+
+#ifdef MACH_KERNEL
+
+io_return_t kmsgopen (dev_t dev, int flag, io_req_t ior);
+io_return_t kmsgclose (dev_t dev, int flag);
+io_return_t kmsgread (dev_t dev, io_req_t ior);
+io_return_t kmsggetstat (dev_t dev, int flavor,
+			 int *data, unsigned int *count);
+void kmsg_putchar (int c);
+
+#endif /* MACH_KERNEL */
+
+#endif /* !_DEVICE_KMSG_H_ */
-- 
cgit v1.2.3