From 6b3060331448d3873bdd60566ff977cf2aaee798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 23 Sep 2004 13:54:20 +0000 Subject: [PATCH] Added the beginnings of our TTY layer. After having had a look at our own Terminal code (former MuTerm), I even copied the original mess in /dev/tt/ and /dev/pt/. The /dev/tt/ entries could be created and removed on demand, though, but that can't be done yet. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9041 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/drivers/Jamfile | 1 + src/add-ons/kernel/drivers/tty/Jamfile | 10 ++ src/add-ons/kernel/drivers/tty/driver.cpp | 104 ++++++++++++++++ src/add-ons/kernel/drivers/tty/master.cpp | 119 +++++++++++++++++++ src/add-ons/kernel/drivers/tty/slave.cpp | 119 +++++++++++++++++++ src/add-ons/kernel/drivers/tty/tty.cpp | 30 +++++ src/add-ons/kernel/drivers/tty/tty_private.h | 30 +++++ 7 files changed, 413 insertions(+) create mode 100644 src/add-ons/kernel/drivers/tty/Jamfile create mode 100644 src/add-ons/kernel/drivers/tty/driver.cpp create mode 100644 src/add-ons/kernel/drivers/tty/master.cpp create mode 100644 src/add-ons/kernel/drivers/tty/slave.cpp create mode 100644 src/add-ons/kernel/drivers/tty/tty.cpp create mode 100644 src/add-ons/kernel/drivers/tty/tty_private.h diff --git a/src/add-ons/kernel/drivers/Jamfile b/src/add-ons/kernel/drivers/Jamfile index 8511247a8d..a9ba3668c3 100644 --- a/src/add-ons/kernel/drivers/Jamfile +++ b/src/add-ons/kernel/drivers/Jamfile @@ -10,3 +10,4 @@ SubInclude OBOS_TOP src add-ons kernel drivers graphics ; SubInclude OBOS_TOP src add-ons kernel drivers misc ; SubInclude OBOS_TOP src add-ons kernel drivers network ; SubInclude OBOS_TOP src add-ons kernel drivers random ; +SubInclude OBOS_TOP src add-ons kernel drivers tty ; diff --git a/src/add-ons/kernel/drivers/tty/Jamfile b/src/add-ons/kernel/drivers/tty/Jamfile new file mode 100644 index 0000000000..8219227094 --- /dev/null +++ b/src/add-ons/kernel/drivers/tty/Jamfile @@ -0,0 +1,10 @@ +SubDir OBOS_TOP src add-ons kernel drivers tty ; + +UsePrivateHeaders kernel ; + +KernelAddon tty : kernel drivers dev : + driver.cpp + tty.cpp + master.cpp + slave.cpp + ; diff --git a/src/add-ons/kernel/drivers/tty/driver.cpp b/src/add-ons/kernel/drivers/tty/driver.cpp new file mode 100644 index 0000000000..640c5dae3d --- /dev/null +++ b/src/add-ons/kernel/drivers/tty/driver.cpp @@ -0,0 +1,104 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the Haiku License. +*/ + + +#include "tty_private.h" + +#include +#include +#include + + +#define TTY_TRACE +#ifdef TTY_TRACE +# define TRACE(x) dprintf x +#else +# define TRACE(x) +#endif + +#define DRIVER_NAME "tty" + + +int32 api_version = B_CUR_DRIVER_API_VERSION; + +static char *sDeviceNames[kNumTTYs * 2 + 1]; + // reserve space for "pt/" and "tt/" entries and the terminating NULL + + +status_t +init_hardware(void) +{ + TRACE((DRIVER_NAME ": init_hardware()\n")); + return B_OK; +} + + +status_t +init_driver(void) +{ + TRACE((DRIVER_NAME ": init_driver()\n")); + + // create driver name array + + char letter = 'p'; + int8 digit = 0; + + for (uint32 i = 0; i < kNumTTYs; i++) { + // For compatibility, we have to create the same mess in /dev/pt and /dev/tt + // as BeOS does: we publish devices p0, p1, ..., pf, r1, ..., sf. + // It would be nice if we could drop compatibility and create something better. + char buffer[64]; + + snprintf(buffer, sizeof(buffer), "pt/%c%x", letter, digit); + sDeviceNames[i] = strdup(buffer); + + snprintf(buffer, sizeof(buffer), "tt/%c%x", letter, digit); + sDeviceNames[i + kNumTTYs] = strdup(buffer); + + if (++digit > 15) + digit = 0, letter++; + } + + sDeviceNames[kNumTTYs * 2] = NULL; + + // initialize TTY structures + + memset(gMasterTTYs, 0, kNumTTYs * sizeof(struct tty)); + memset(gSlaveTTYs, 0, kNumTTYs * sizeof(struct tty)); + + return B_OK; +} + + +void +uninit_driver(void) +{ + TRACE((DRIVER_NAME ": uninit_driver()\n")); + + for (int32 i = 0; sDeviceNames[i] != NULL; i++) + free(sDeviceNames[i]); +} + + +const char ** +publish_devices(void) +{ + TRACE((DRIVER_NAME ": publish_devices()\n")); + return const_cast(sDeviceNames); +} + + +device_hooks * +find_device(const char *name) +{ + TRACE((DRIVER_NAME ": find_device(\"%s\")\n", name)); + + for (uint32 i = 0; sDeviceNames[i] != NULL; i++) + if (!strcmp(name, sDeviceNames[i])) + return i < kNumTTYs ? &gMasterTTYHooks : &gSlaveTTYHooks; + + return NULL; +} + diff --git a/src/add-ons/kernel/drivers/tty/master.cpp b/src/add-ons/kernel/drivers/tty/master.cpp new file mode 100644 index 0000000000..6c3924c8f8 --- /dev/null +++ b/src/add-ons/kernel/drivers/tty/master.cpp @@ -0,0 +1,119 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the Haiku License. +*/ + + +#include "tty_private.h" + +#include + + +#define MASTER_TRACE +#ifdef MASTER_TRACE +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +struct master_cookie { + struct tty *tty; + uint32 open_mode; +}; + + +struct tty gMasterTTYs[kNumTTYs]; + + +static status_t +master_open(const char *name, uint32 flags, void **_cookie) +{ + int32 index = get_tty_index(name); + + if (atomic_or(&gMasterTTYs[index].open_count, 1) != 0) { + // we're already open! + return B_BUSY; + } + + master_cookie *cookie = (master_cookie *)malloc(sizeof(struct master_cookie)); + if (cookie == NULL) + return B_NO_MEMORY; + + cookie->tty = &gMasterTTYs[index]; + *_cookie = cookie; + + return B_OK; +} + + +static status_t +master_close(void *_cookie) +{ + master_cookie *cookie = (master_cookie *)_cookie; + + TRACE(("master_close: cookie %p\n", _cookie)); + + atomic_and(&cookie->tty->open_count, 0); + return B_OK; +} + + +static status_t +master_free_cookie(void *_cookie) +{ + free(_cookie); + return B_OK; +} + + +static status_t +master_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) +{ + TRACE(("master_ioctl: cookie %p, op %lu, buffer %p, length %lu\n", _cookie, op, buffer, length)); + return B_BAD_VALUE; +} + + +static status_t +master_read(void *_cookie, off_t offset, void *buffer, size_t *_length) +{ + TRACE(("master_read: cookie %p, offset %Ld, buffer %p, length %lu\n", _cookie, offset, buffer, *_length)); + return B_BAD_VALUE; +} + + +static status_t +master_write(void *_cookie, off_t offset, const void *buffer, size_t *_length) +{ + TRACE(("master_write: cookie %p, offset %Ld, buffer %p, length %lu\n", _cookie, offset, buffer, *_length)); + return B_BAD_VALUE; +} + + +static status_t +master_select(void *_cookie, uint8 event, uint32 ref, selectsync *sync) +{ + return B_OK; +} + + +static status_t +master_deselect(void *_cookie, uint8 event, selectsync *sync) +{ + return B_OK; +} + + +device_hooks gMasterTTYHooks = { + &master_open, + &master_close, + &master_free_cookie, + &master_ioctl, + &master_read, + &master_write, + &master_select, + &master_deselect, + NULL, // read_pages() + NULL // write_pages() +}; diff --git a/src/add-ons/kernel/drivers/tty/slave.cpp b/src/add-ons/kernel/drivers/tty/slave.cpp new file mode 100644 index 0000000000..bd4e2be113 --- /dev/null +++ b/src/add-ons/kernel/drivers/tty/slave.cpp @@ -0,0 +1,119 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the Haiku License. +*/ + + +#include "tty_private.h" + +#include + + +#define SLAVE_TRACE +#ifdef SLAVE_TRACE +# define TRACE(x) dprintf x +#else +# define TRACE(x) +#endif + + +struct slave_cookie { + struct tty *tty; + uint32 open_mode; +}; + + +struct tty gSlaveTTYs[kNumTTYs]; + + +static status_t +slave_open(const char *name, uint32 flags, void **_cookie) +{ + int32 index = get_tty_index(name); + + if (gSlaveTTYs[index].open_count == 0) + return B_IO_ERROR; + + atomic_add(&gSlaveTTYs[index].open_count, 1); + + slave_cookie *cookie = (slave_cookie *)malloc(sizeof(struct slave_cookie)); + if (cookie == NULL) + return B_NO_MEMORY; + + cookie->tty = &gSlaveTTYs[index]; + *_cookie = cookie; + + return B_OK; +} + + +static status_t +slave_close(void *_cookie) +{ + slave_cookie *cookie = (slave_cookie *)_cookie; + + TRACE(("slave_close: cookie %p\n", _cookie)); + + atomic_add(&cookie->tty->open_count, -1); + return B_OK; +} + + +static status_t +slave_free_cookie(void *_cookie) +{ + free(_cookie); + return B_OK; +} + + +static status_t +slave_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) +{ + TRACE(("slave_ioctl: cookie %p, op %lu, buffer %p, length %lu\n", _cookie, op, buffer, length)); + return B_BAD_VALUE; +} + + +static status_t +slave_read(void *_cookie, off_t offset, void *buffer, size_t *_length) +{ + TRACE(("slave_read: cookie %p, offset %Ld, buffer %p, length %lu\n", _cookie, offset, buffer, *_length)); + return B_BAD_VALUE; +} + + +static status_t +slave_write(void *_cookie, off_t offset, const void *buffer, size_t *_length) +{ + TRACE(("slave_write: cookie %p, offset %Ld, buffer %p, length %lu\n", _cookie, offset, buffer, *_length)); + return B_BAD_VALUE; +} + + +static status_t +slave_select(void *_cookie, uint8 event, uint32 ref, selectsync *sync) +{ + return B_OK; +} + + +static status_t +slave_deselect(void *_cookie, uint8 event, selectsync *sync) +{ + return B_OK; +} + + +device_hooks gSlaveTTYHooks = { + &slave_open, + &slave_close, + &slave_free_cookie, + &slave_ioctl, + &slave_read, + &slave_write, + &slave_select, + &slave_deselect, + NULL, // read_pages() + NULL // write_pages() +}; diff --git a/src/add-ons/kernel/drivers/tty/tty.cpp b/src/add-ons/kernel/drivers/tty/tty.cpp new file mode 100644 index 0000000000..6ada190c33 --- /dev/null +++ b/src/add-ons/kernel/drivers/tty/tty.cpp @@ -0,0 +1,30 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the Haiku License. +*/ + + +#include "tty_private.h" + + +#define TTY_TRACE +#ifdef TTY_TRACE +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +int32 +get_tty_index(const char *name) +{ + // device names follow this form: "pt/%c%x" + int8 digit = name[4]; + if (digit >= 'a') + digit -= 'a'; + else + digit -= '0'; + + return (name[3] - 'p') * digit; +} + diff --git a/src/add-ons/kernel/drivers/tty/tty_private.h b/src/add-ons/kernel/drivers/tty/tty_private.h new file mode 100644 index 0000000000..d95b78be96 --- /dev/null +++ b/src/add-ons/kernel/drivers/tty/tty_private.h @@ -0,0 +1,30 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the Haiku License. +*/ +#ifndef TTY_PRIVATE_H +#define TTY_PRIVATE_H + + +#include +#include + +#include + + +struct tty { + int32 open_count; +}; + +static const uint32 kNumTTYs = 64; + +extern tty gMasterTTYs[kNumTTYs]; +extern tty gSlaveTTYs[kNumTTYs]; + +extern device_hooks gMasterTTYHooks; +extern device_hooks gSlaveTTYHooks; + + +extern int32 get_tty_index(const char *name); + +#endif /* TTY_PRIVATE_H */