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
This commit is contained in:
Axel Dörfler
2004-09-23 13:54:20 +00:00
parent a78a421de8
commit 6b30603314
7 changed files with 413 additions and 0 deletions
+1
View File
@@ -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 ;
+10
View File
@@ -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
;
+104
View File
@@ -0,0 +1,104 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include "tty_private.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#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<const char **>(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;
}
+119
View File
@@ -0,0 +1,119 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include "tty_private.h"
#include <stdlib.h>
#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()
};
+119
View File
@@ -0,0 +1,119 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include "tty_private.h"
#include <stdlib.h>
#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()
};
+30
View File
@@ -0,0 +1,30 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. 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;
}
@@ -0,0 +1,30 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#ifndef TTY_PRIVATE_H
#define TTY_PRIVATE_H
#include <KernelExport.h>
#include <Drivers.h>
#include <termios.h>
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 */