diff options
author | Thomas Bushnell <thomas@gnu.org> | 1999-04-26 05:16:15 +0000 |
---|---|---|
committer | Thomas Bushnell <thomas@gnu.org> | 1999-04-26 05:16:15 +0000 |
commit | 3efcc3770a79988affebf6bed5beefbaf2072527 (patch) | |
tree | 95ded791e3bd1de0dd448fc223b9ee32774956e9 /device | |
parent | 129475fe1c546bd7db86e8410ca48f3612e0a80e (diff) |
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.
Diffstat (limited to 'device')
-rw-r--r-- | device/cons.c | 11 | ||||
-rw-r--r-- | device/ds_routines.c | 4 | ||||
-rw-r--r-- | device/kmsg.c | 247 | ||||
-rw-r--r-- | device/kmsg.h | 15 |
4 files changed, 276 insertions, 1 deletions
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_ */ |