Port pc_serial to the new tty module.
Builds but won't work because the tty module lacks essential calls to read and write data :^) Lots of ifdef since I need the R5 code around for now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39791 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -31,7 +31,9 @@ tty_module_info *gTTYModule = NULL;
|
||||
#else
|
||||
tty_module_info_v1_bone *gTTYModule = NULL;
|
||||
#endif
|
||||
#ifdef __BEOS__
|
||||
struct ddomain gSerialDomain;
|
||||
#endif
|
||||
sem_id gDriverLock = -1;
|
||||
bool gHandleISA = false;
|
||||
|
||||
@@ -297,10 +299,10 @@ scan_bus(bus_type bus)
|
||||
while ((gConfigManagerModule->get_next_device_info(bus,
|
||||
&cookie, &big_info.di, sizeof(big_info)) == B_OK)) {
|
||||
// skip disabled devices
|
||||
if (dinfo.flags & B_DEVICE_INFO_ENABLED == 0)
|
||||
if ((dinfo.flags & B_DEVICE_INFO_ENABLED) == 0)
|
||||
continue;
|
||||
// skip non configured devices
|
||||
if (dinfo.flags & B_DEVICE_INFO_CONFIGURED == 0)
|
||||
if ((dinfo.flags & B_DEVICE_INFO_CONFIGURED) == 0)
|
||||
continue;
|
||||
// and devices in error
|
||||
if (dinfo.config_status < B_OK)
|
||||
@@ -467,8 +469,12 @@ next_split:
|
||||
TRACE_ALWAYS("inserting device at io 0x%04lx as %s\n", ioport,
|
||||
supported->name);
|
||||
|
||||
|
||||
|
||||
#ifdef __HAIKU__
|
||||
device = new(std::nothrow) SerialDevice(supported, ioport, irq, master);
|
||||
#else
|
||||
device = new SerialDevice(supported, ioport, irq, master);
|
||||
#endif
|
||||
if (pc_serial_insert_device(device) < B_OK) {
|
||||
TRACE_ALWAYS("can't insert device\n");
|
||||
continue;
|
||||
@@ -504,7 +510,7 @@ scan_pci_alt()
|
||||
// probe PCI devices
|
||||
for (ix = 0; (*gPCIModule->get_nth_pci_info)(ix, &info) == B_OK; ix++) {
|
||||
// sanity check
|
||||
if (info.header_type & PCI_header_type_mask != PCI_header_type_generic)
|
||||
if ((info.header_type & PCI_header_type_mask) != PCI_header_type_generic)
|
||||
continue;
|
||||
/*
|
||||
TRACE_ALWAYS("probing PCI device %2d [%x|%x|%x] %04x:%04x\n",
|
||||
@@ -614,7 +620,11 @@ next_split_alt:
|
||||
|
||||
|
||||
/**/
|
||||
#ifdef __HAIKU__
|
||||
device = new(std::nothrow) SerialDevice(supported, ioport, irq, master);
|
||||
#else
|
||||
device = new SerialDevice(supported, ioport, irq, master);
|
||||
#endif
|
||||
if (pc_serial_insert_device(device) < B_OK) {
|
||||
TRACE_ALWAYS("can't insert device\n");
|
||||
continue;
|
||||
@@ -732,9 +742,10 @@ init_driver()
|
||||
|
||||
status = ENOENT;
|
||||
|
||||
#ifdef __BEOS__
|
||||
memset(&gSerialDomain, 0, sizeof(gSerialDomain));
|
||||
ddbackground(&gSerialDomain);
|
||||
|
||||
#endif
|
||||
|
||||
scan_bus(B_ISA_BUS);
|
||||
//scan_bus(B_PCI_BUS);
|
||||
@@ -797,6 +808,26 @@ uninit_driver()
|
||||
}
|
||||
|
||||
|
||||
#ifdef __HAIKU__
|
||||
bool
|
||||
pc_serial_service(struct tty *tty, uint32 op, void *buffer, size_t length)
|
||||
{
|
||||
TRACE_FUNCALLS("> pc_serial_service(%p, 0x%08lx, %p, %lu)\n", tty,
|
||||
op, buffer, length);
|
||||
|
||||
|
||||
for (int32 i = 0; i < DEVICES_COUNT; i++) {
|
||||
if (gSerialDevices[i]
|
||||
&& gSerialDevices[i]->Service(tty, op, buffer, length)) {
|
||||
TRACE_FUNCRET("< pc_serial_service() returns: true\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_FUNCRET("< pc_serial_service() returns: false\n");
|
||||
return false;
|
||||
}
|
||||
#else /* __HAIKU__ */
|
||||
bool
|
||||
pc_serial_service(struct tty *ptty, struct ddrover *ddr, uint flags)
|
||||
{
|
||||
@@ -812,6 +843,7 @@ pc_serial_service(struct tty *ptty, struct ddrover *ddr, uint flags)
|
||||
TRACE_FUNCRET("< pc_serial_service() returns: false\n");
|
||||
return false;
|
||||
}
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
|
||||
int32
|
||||
|
||||
@@ -22,14 +22,19 @@
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <lock.h>
|
||||
#include <new>
|
||||
#else
|
||||
#include "BeOSCompatibility.h"
|
||||
#endif
|
||||
#include "kernel_cpp.h"
|
||||
#endif
|
||||
#include "Tracing.h"
|
||||
|
||||
extern "C" {
|
||||
#ifdef __HAIKU__
|
||||
#include <tty_module.h>
|
||||
#else
|
||||
#include <ttylayer.h>
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +140,7 @@ typedef struct pc_serial_line_coding_s {
|
||||
|
||||
|
||||
|
||||
#ifndef __HAIKU__
|
||||
#ifdef __BEOS__
|
||||
|
||||
// All this mess is due to BeOS R5 and BONE having
|
||||
// an incompatible module API for the same version
|
||||
@@ -184,8 +189,7 @@ struct tty_module_info_v1_bone {
|
||||
void (*ddrdone)(struct ddrover *);
|
||||
void (*ddacquire)(struct ddrover *, struct ddomain *);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __BEOS__ */
|
||||
|
||||
|
||||
extern config_manager_for_driver_module_info *gConfigManagerModule;
|
||||
@@ -199,10 +203,16 @@ extern tty_module_info_v1_bone *gTTYModule;
|
||||
extern struct ddomain gSerialDomain;
|
||||
|
||||
extern "C" {
|
||||
|
||||
status_t init_hardware();
|
||||
void uninit_driver();
|
||||
|
||||
#ifdef __BEOS__
|
||||
bool pc_serial_service(struct tty *ptty, struct ddrover *ddr, uint flags);
|
||||
#else
|
||||
bool pc_serial_service(struct tty *tty, uint32 op, void *buffer,
|
||||
size_t length);
|
||||
#endif /* __BEOS__ */
|
||||
int32 pc_serial_interrupt(void *arg);
|
||||
|
||||
status_t pc_serial_open(const char *name, uint32 flags, void **cookie);
|
||||
@@ -216,6 +226,7 @@ status_t pc_serial_free(void *cookie);
|
||||
|
||||
const char **publish_devices();
|
||||
device_hooks *find_device(const char *name);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,12 +38,19 @@ SerialDevice::SerialDevice(const struct serial_support_descriptor *device,
|
||||
fDoneWrite(-1),
|
||||
fControlOut(0),
|
||||
fInputStopped(false),
|
||||
#ifdef __HAIKU__
|
||||
fMasterTTY(NULL),
|
||||
fSlaveTTY(NULL),
|
||||
fTTYCookie(NULL),
|
||||
#endif /* __HAIKU__ */
|
||||
fDeviceThread(-1),
|
||||
fStopDeviceThread(false)
|
||||
{
|
||||
#ifdef __BEOS__
|
||||
memset(&fTTYFile, 0, sizeof(ttyfile));
|
||||
memset(&fTTY, 0, sizeof(tty));
|
||||
memset(&fRover, 0, sizeof(ddrover));
|
||||
#endif /* __BEOS__ */
|
||||
}
|
||||
|
||||
|
||||
@@ -87,21 +94,30 @@ SerialDevice::Init()
|
||||
}
|
||||
|
||||
|
||||
#ifdef __BEOS__
|
||||
void
|
||||
SerialDevice::SetModes()
|
||||
{
|
||||
struct termios tios;
|
||||
memcpy(&tios, &fTTY.t, sizeof(struct termios));
|
||||
//TRACE_FUNCRES(trace_termios, &tios);
|
||||
SetModes(&tios);
|
||||
}
|
||||
#endif /* __BEOS__ */
|
||||
|
||||
|
||||
void
|
||||
SerialDevice::SetModes(struct termios *tios)
|
||||
{
|
||||
//TRACE_FUNCRES(trace_termios, tios);
|
||||
spin(10000);
|
||||
uint32 baudIndex = tios.c_cflag & CBAUD;
|
||||
uint32 baudIndex = tios->c_cflag & CBAUD;
|
||||
if (baudIndex > BLAST)
|
||||
baudIndex = BLAST;
|
||||
|
||||
uint8 lcr = 0;
|
||||
uint16 divisor = SupportDescriptor()->bauds[baudIndex];
|
||||
|
||||
switch (tios.c_cflag & CSIZE) {
|
||||
switch (tios->c_cflag & CSIZE) {
|
||||
#if CS5 != CS7
|
||||
// in case someday...
|
||||
case CS5:
|
||||
@@ -120,11 +136,11 @@ SerialDevice::SetModes()
|
||||
break;
|
||||
}
|
||||
|
||||
if (tios.c_cflag & CSTOPB)
|
||||
if (tios->c_cflag & CSTOPB)
|
||||
lcr |= LCR_2STOP;
|
||||
if (tios.c_cflag & PARENB)
|
||||
if (tios->c_cflag & PARENB)
|
||||
lcr |= LCR_P_EN;
|
||||
if (tios.c_cflag & PARODD == 0)
|
||||
if ((tios->c_cflag & PARODD) == 0)
|
||||
lcr |= LCR_P_EVEN;
|
||||
|
||||
if (baudIndex == B0) {
|
||||
@@ -179,16 +195,16 @@ SerialDevice::SetModes()
|
||||
|
||||
usb_serial_line_coding lineCoding;
|
||||
lineCoding.speed = baudRates[baudIndex];
|
||||
lineCoding.stopbits = (tios.c_cflag & CSTOPB) ? LC_STOP_BIT_2 : LC_STOP_BIT_1;
|
||||
lineCoding.stopbits = (tios->c_cflag & CSTOPB) ? LC_STOP_BIT_2 : LC_STOP_BIT_1;
|
||||
|
||||
if (tios.c_cflag & PARENB) {
|
||||
if (tios->c_cflag & PARENB) {
|
||||
lineCoding.parity = LC_PARITY_EVEN;
|
||||
if (tios.c_cflag & PARODD)
|
||||
if (tios->c_cflag & PARODD)
|
||||
lineCoding.parity = LC_PARITY_ODD;
|
||||
} else
|
||||
lineCoding.parity = LC_PARITY_NONE;
|
||||
|
||||
lineCoding.databits = (tios.c_cflag & CS8) ? 8 : 7;
|
||||
lineCoding.databits = (tios->c_cflag & CS8) ? 8 : 7;
|
||||
|
||||
if (lineCoding.speed == 0) {
|
||||
newControl &= 0xfffffffe;
|
||||
@@ -216,6 +232,127 @@ SerialDevice::SetModes()
|
||||
}
|
||||
|
||||
|
||||
#ifdef __HAIKU__
|
||||
|
||||
|
||||
bool
|
||||
SerialDevice::Service(struct tty *tty, uint32 op, void *buffer, size_t length)
|
||||
{
|
||||
uint8 msr;
|
||||
status_t err;
|
||||
|
||||
if (tty != fMasterTTY)
|
||||
return false;
|
||||
|
||||
TRACE("%s(,0x%08lx,,%d)\n", __FUNCTION__, op, length);
|
||||
|
||||
switch (op) {
|
||||
case TTYENABLE:
|
||||
{
|
||||
bool enable = *(bool *)buffer;
|
||||
TRACE("TTYENABLE: %sable\n", enable ? "en" : "dis");
|
||||
|
||||
if (enable) {
|
||||
//XXX:must call SetModes();
|
||||
err = install_io_interrupt_handler(IRQ(), pc_serial_interrupt, this, 0);
|
||||
TRACE("installing irq handler for %d: %s\n", IRQ(), strerror(err));
|
||||
} else {
|
||||
// remove the handler
|
||||
remove_io_interrupt_handler(IRQ(), pc_serial_interrupt, this);
|
||||
// disable IRQ
|
||||
WriteReg8(IER, 0);
|
||||
WriteReg8(MCR, 0);
|
||||
}
|
||||
|
||||
msr = ReadReg8(MSR);
|
||||
|
||||
SignalControlLineState(TTYHWDCD, msr & MSR_DCD);
|
||||
SignalControlLineState(TTYHWCTS, msr & MSR_CTS);
|
||||
|
||||
if (enable) {
|
||||
//
|
||||
WriteReg8(MCR, MCR_DTR | MCR_RTS | MCR_IRQ_EN /*| MCR_LOOP*//*XXXXXXX*/);
|
||||
// enable irqs
|
||||
WriteReg8(IER, IER_RLS | IER_MS | IER_RDA);
|
||||
//WriteReg8(IER, IER_RDA);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case TTYISTOP:
|
||||
fInputStopped = *(bool *)buffer;
|
||||
TRACE("TTYISTOP: %sstopped\n", fInputStopped ? "" : "not ");
|
||||
|
||||
if (fInputStopped)
|
||||
MaskReg8(MCR, MCR_RTS);
|
||||
else
|
||||
OrReg8(MCR, MCR_RTS);
|
||||
|
||||
//gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, false);
|
||||
//SignalControlLineState(TTYHWCTS, !fInputStopped);
|
||||
//msr = ReadReg8(MSR);
|
||||
//SignalControlLineState(TTYHWCTS, msr & MSR_CTS);
|
||||
return true;
|
||||
|
||||
case TTYGETSIGNALS:
|
||||
TRACE("TTYGETSIGNALS\n");
|
||||
msr = ReadReg8(MSR);
|
||||
SignalControlLineState(TTYHWDCD, msr & MSR_DCD);
|
||||
SignalControlLineState(TTYHWCTS, msr & MSR_CTS);
|
||||
SignalControlLineState(TTYHWDSR, msr & MSR_DSR);
|
||||
SignalControlLineState(TTYHWRI, msr & MSR_RI);
|
||||
return true;
|
||||
|
||||
case TTYSETMODES:
|
||||
TRACE("TTYSETMODES\n");
|
||||
SetModes((struct termios *)buffer);
|
||||
//WriteReg8(IER, IER_RLS | IER_MS | IER_RDA);
|
||||
return true;
|
||||
|
||||
case TTYSETDTR:
|
||||
case TTYSETRTS:
|
||||
{
|
||||
bool set = *(bool *)buffer;
|
||||
uint8 bit = TTYSETDTR ? MCR_DTR : MCR_RTS;
|
||||
if (set)
|
||||
OrReg8(MCR, bit);
|
||||
else
|
||||
MaskReg8(MCR, bit);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case TTYOSTART:
|
||||
TRACE("TTYOSTART\n");
|
||||
// enable irqs
|
||||
WriteReg8(IER, IER_RLS | IER_MS | IER_RDA | IER_THRE);
|
||||
return true;
|
||||
case TTYOSYNC:
|
||||
TRACE("TTYOSYNC\n");
|
||||
return (ReadReg8(LSR) & (LSR_THRE | LSR_TSRE)) == (LSR_THRE | LSR_TSRE);
|
||||
return true;
|
||||
case TTYSETBREAK:
|
||||
{
|
||||
bool set = *(bool *)buffer;
|
||||
if (set)
|
||||
OrReg8(MCR, LCR_BREAK);
|
||||
else
|
||||
MaskReg8(MCR, LCR_BREAK);
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#else /* __HAIKU__ */
|
||||
|
||||
|
||||
bool
|
||||
SerialDevice::Service(struct tty *ptty, struct ddrover *ddr, uint flags)
|
||||
{
|
||||
@@ -227,113 +364,115 @@ SerialDevice::Service(struct tty *ptty, struct ddrover *ddr, uint flags)
|
||||
|
||||
TRACE("%s(,,0x%08lx)\n", __FUNCTION__, flags);
|
||||
|
||||
if (flags <= TTYGETSIGNALS) {
|
||||
switch (flags) {
|
||||
case TTYENABLE:
|
||||
TRACE("TTYENABLE\n");
|
||||
|
||||
SetModes();
|
||||
err = install_io_interrupt_handler(IRQ(), pc_serial_interrupt, this, 0);
|
||||
TRACE("installing irq handler for %d: %s\n", IRQ(), strerror(err));
|
||||
msr = ReadReg8(MSR);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, msr & MSR_DCD);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, msr & MSR_CTS);
|
||||
//
|
||||
WriteReg8(MCR, MCR_DTR | MCR_RTS | MCR_IRQ_EN /*| MCR_LOOP*//*XXXXXXX*/);
|
||||
// enable irqs
|
||||
WriteReg8(IER, IER_RLS | IER_MS | IER_RDA);
|
||||
//WriteReg8(IER, IER_RDA);
|
||||
break;
|
||||
switch (flags) {
|
||||
case TTYENABLE:
|
||||
TRACE("TTYENABLE\n");
|
||||
|
||||
case TTYDISABLE:
|
||||
TRACE("TTYDISABLE\n");
|
||||
// remove the handler
|
||||
remove_io_interrupt_handler(IRQ(), pc_serial_interrupt, this);
|
||||
// disable IRQ
|
||||
WriteReg8(IER, 0);
|
||||
WriteReg8(MCR, 0);
|
||||
msr = ReadReg8(MSR);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, msr & MSR_DCD);
|
||||
break;
|
||||
SetModes();
|
||||
err = install_io_interrupt_handler(IRQ(), pc_serial_interrupt, this, 0);
|
||||
TRACE("installing irq handler for %d: %s\n", IRQ(), strerror(err));
|
||||
msr = ReadReg8(MSR);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, msr & MSR_DCD);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, msr & MSR_CTS);
|
||||
//
|
||||
WriteReg8(MCR, MCR_DTR | MCR_RTS | MCR_IRQ_EN /*| MCR_LOOP*//*XXXXXXX*/);
|
||||
// enable irqs
|
||||
WriteReg8(IER, IER_RLS | IER_MS | IER_RDA);
|
||||
//WriteReg8(IER, IER_RDA);
|
||||
break;
|
||||
|
||||
case TTYISTOP:
|
||||
TRACE("TTYISTOP\n");
|
||||
MaskReg8(MCR, MCR_RTS);
|
||||
//fInputStopped = true;
|
||||
//gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, false);
|
||||
break;
|
||||
case TTYDISABLE:
|
||||
TRACE("TTYDISABLE\n");
|
||||
// remove the handler
|
||||
remove_io_interrupt_handler(IRQ(), pc_serial_interrupt, this);
|
||||
// disable IRQ
|
||||
WriteReg8(IER, 0);
|
||||
WriteReg8(MCR, 0);
|
||||
msr = ReadReg8(MSR);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, msr & MSR_DCD);
|
||||
break;
|
||||
|
||||
case TTYIRESUME:
|
||||
TRACE("TTYIRESUME\n");
|
||||
OrReg8(MCR, MCR_RTS);
|
||||
//gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, true);
|
||||
//fInputStopped = false;
|
||||
break;
|
||||
case TTYISTOP:
|
||||
TRACE("TTYISTOP\n");
|
||||
MaskReg8(MCR, MCR_RTS);
|
||||
//fInputStopped = true;
|
||||
//gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, false);
|
||||
break;
|
||||
|
||||
case TTYGETSIGNALS:
|
||||
TRACE("TTYGETSIGNALS\n");
|
||||
msr = ReadReg8(MSR);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, msr & MSR_DCD);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, msr & MSR_CTS);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDSR, msr & MSR_DSR);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWRI, msr & MSR_RI);
|
||||
break;
|
||||
case TTYIRESUME:
|
||||
TRACE("TTYIRESUME\n");
|
||||
OrReg8(MCR, MCR_RTS);
|
||||
//gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, true);
|
||||
//fInputStopped = false;
|
||||
break;
|
||||
|
||||
case TTYSETMODES:
|
||||
TRACE("TTYSETMODES\n");
|
||||
SetModes();
|
||||
case TTYGETSIGNALS:
|
||||
TRACE("TTYGETSIGNALS\n");
|
||||
msr = ReadReg8(MSR);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDCD, msr & MSR_DCD);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWCTS, msr & MSR_CTS);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWDSR, msr & MSR_DSR);
|
||||
gTTYModule->ttyhwsignal(ptty, ddr, TTYHWRI, msr & MSR_RI);
|
||||
break;
|
||||
|
||||
case TTYSETMODES:
|
||||
TRACE("TTYSETMODES\n");
|
||||
SetModes();
|
||||
//WriteReg8(IER, IER_RLS | IER_MS | IER_RDA);
|
||||
break;
|
||||
break;
|
||||
|
||||
case TTYOSTART:
|
||||
TRACE("TTYOSTART\n");
|
||||
// enable irqs
|
||||
WriteReg8(IER, IER_RLS | IER_MS | IER_RDA | IER_THRE);
|
||||
break;
|
||||
case TTYOSYNC:
|
||||
TRACE("TTYOSYNC\n");
|
||||
return (ReadReg8(LSR) & (LSR_THRE | LSR_TSRE)) == (LSR_THRE | LSR_TSRE);
|
||||
break;
|
||||
case TTYSETBREAK:
|
||||
TRACE("TTYSETBREAK\n");
|
||||
OrReg8(LCR, LCR_BREAK);
|
||||
break;
|
||||
case TTYCLRBREAK:
|
||||
TRACE("TTYCLRBREAK\n");
|
||||
MaskReg8(LCR, LCR_BREAK);
|
||||
break;
|
||||
case TTYSETDTR:
|
||||
TRACE("TTYSETDTR\n");
|
||||
OrReg8(MCR, MCR_DTR);
|
||||
break;
|
||||
case TTYCLRDTR:
|
||||
TRACE("TTYCLRDTR\n");
|
||||
MaskReg8(MCR, MCR_DTR);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
case TTYOSTART:
|
||||
TRACE("TTYOSTART\n");
|
||||
// enable irqs
|
||||
WriteReg8(IER, IER_RLS | IER_MS | IER_RDA | IER_THRE);
|
||||
break;
|
||||
case TTYOSYNC:
|
||||
TRACE("TTYOSYNC\n");
|
||||
return (ReadReg8(LSR) & (LSR_THRE | LSR_TSRE)) == (LSR_THRE | LSR_TSRE);
|
||||
break;
|
||||
case TTYSETBREAK:
|
||||
TRACE("TTYSETBREAK\n");
|
||||
OrReg8(LCR, LCR_BREAK);
|
||||
break;
|
||||
case TTYCLRBREAK:
|
||||
TRACE("TTYCLRBREAK\n");
|
||||
MaskReg8(LCR, LCR_BREAK);
|
||||
break;
|
||||
case TTYSETDTR:
|
||||
TRACE("TTYSETDTR\n");
|
||||
OrReg8(MCR, MCR_DTR);
|
||||
break;
|
||||
case TTYCLRDTR:
|
||||
TRACE("TTYCLRDTR\n");
|
||||
MaskReg8(MCR, MCR_DTR);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
|
||||
int32
|
||||
SerialDevice::InterruptHandler()
|
||||
{
|
||||
int32 ret = B_UNHANDLED_INTERRUPT;
|
||||
#ifdef __HAIKU__
|
||||
//XXX: what should we do here ? (certainly not use a mutex !)
|
||||
#else /* __HAIKU__ */
|
||||
gTTYModule->ddrstart(&fRover);
|
||||
gTTYModule->ttyilock(&fTTY, &fRover, true);
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
uint8 iir, lsr, msr;
|
||||
int count;
|
||||
|
||||
while (((iir = ReadReg8(IIR)) & IIR_PENDING) == 0) { // 0 means yes
|
||||
int fifoavail = 1;
|
||||
|
||||
//DEBUG
|
||||
// for (count = 0; ReadReg8(LSR) & LSR_DR; count++)
|
||||
// for (int count = 0; ReadReg8(LSR) & LSR_DR; count++)
|
||||
// gTTYModule->ttyin(&fTTY, &fRover, ReadReg8(RBR));
|
||||
|
||||
switch (iir & (IIR_IMASK | IIR_TO)) {
|
||||
@@ -341,12 +480,17 @@ SerialDevice::InterruptHandler()
|
||||
TRACE(("IIR_THRE\n"));
|
||||
// check how much fifo we can use
|
||||
//XXX: move to Init() ?
|
||||
if (iir & IIR_FMASK == IIR_FMASK)
|
||||
if ((iir & IIR_FMASK) == IIR_FMASK)
|
||||
fifoavail = 16;
|
||||
if (iir & IIR_F64EN)
|
||||
fifoavail = 64;
|
||||
for (int i = 0; i < fifoavail; i++) {
|
||||
int chr = gTTYModule->ttyout(&fTTY, &fRover);
|
||||
int chr;
|
||||
#ifdef __HAIKU__
|
||||
chr = 'H';//XXX: what should we do here ? (certainly not call tty_read() !)
|
||||
#else /* __HAIKU__ */
|
||||
chr = gTTYModule->ttyout(&fTTY, &fRover);
|
||||
#endif /* __HAIKU__ */
|
||||
if (chr < 0) {
|
||||
//WriteReg8(THB, (uint8)chr);
|
||||
break;
|
||||
@@ -361,7 +505,11 @@ SerialDevice::InterruptHandler()
|
||||
TRACE(("IIR_TO/RDA\n"));
|
||||
// while data is ready... get it
|
||||
while (ReadReg8(LSR) & LSR_DR)
|
||||
#ifdef __HAIKU__
|
||||
ReadReg8(RBR);//XXX: what should we do here ? (certainly not call tty_write() !)
|
||||
#else /* __HAIKU__ */
|
||||
gTTYModule->ttyin(&fTTY, &fRover, ReadReg8(RBR));
|
||||
#endif /* __HAIKU__ */
|
||||
break;
|
||||
case IIR_RLS:
|
||||
TRACE(("IIR_RLS\n"));
|
||||
@@ -374,13 +522,13 @@ SerialDevice::InterruptHandler()
|
||||
// modem signals changed
|
||||
msr = ReadReg8(MSR);
|
||||
if (msr & MSR_DDCD)
|
||||
gTTYModule->ttyhwsignal(&fTTY, &fRover, TTYHWDCD, msr & MSR_DCD);
|
||||
SignalControlLineState(TTYHWDCD, msr & MSR_DCD);
|
||||
if (msr & MSR_DCTS)
|
||||
gTTYModule->ttyhwsignal(&fTTY, &fRover, TTYHWCTS, msr & MSR_CTS);
|
||||
SignalControlLineState(TTYHWCTS, msr & MSR_CTS);
|
||||
if (msr & MSR_DDSR)
|
||||
gTTYModule->ttyhwsignal(&fTTY, &fRover, TTYHWDSR, msr & MSR_DSR);
|
||||
SignalControlLineState(TTYHWDSR, msr & MSR_DSR);
|
||||
if (msr & MSR_TERI)
|
||||
gTTYModule->ttyhwsignal(&fTTY, &fRover, TTYHWRI, msr & MSR_RI);
|
||||
SignalControlLineState(TTYHWRI, msr & MSR_RI);
|
||||
break;
|
||||
default:
|
||||
TRACE(("IIR_?\n"));
|
||||
@@ -392,8 +540,12 @@ SerialDevice::InterruptHandler()
|
||||
}
|
||||
|
||||
|
||||
#ifdef __HAIKU__
|
||||
//XXX: what should we do here ? (certainly not use a mutex !)
|
||||
#else /* __HAIKU__ */
|
||||
gTTYModule->ttyilock(&fTTY, &fRover, false);
|
||||
gTTYModule->ddrdone(&fRover);
|
||||
#endif /* __HAIKU__ */
|
||||
TRACE_FUNCRET("< IRQ:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -402,15 +554,45 @@ SerialDevice::InterruptHandler()
|
||||
status_t
|
||||
SerialDevice::Open(uint32 flags)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
if (fDeviceOpen)
|
||||
return B_BUSY;
|
||||
|
||||
if (fDeviceRemoved)
|
||||
return B_DEV_NOT_READY;
|
||||
|
||||
#ifdef __HAIKU__
|
||||
fMasterTTY = gTTYModule->tty_create(pc_serial_service, true);
|
||||
if (fMasterTTY == NULL) {
|
||||
TRACE_ALWAYS("open: failed to init master tty\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
fSlaveTTY = gTTYModule->tty_create(NULL, false);
|
||||
if (fSlaveTTY == NULL) {
|
||||
TRACE_ALWAYS("open: failed to init slave tty\n");
|
||||
gTTYModule->tty_destroy(fMasterTTY);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
fTTYCookie = gTTYModule->tty_create_cookie(fMasterTTY, fSlaveTTY, flags);
|
||||
if (fTTYCookie == NULL) {
|
||||
TRACE_ALWAYS("open: failed to init tty cookie\n");
|
||||
gTTYModule->tty_destroy(fMasterTTY);
|
||||
gTTYModule->tty_destroy(fSlaveTTY);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
ResetDevice();
|
||||
|
||||
#else /* __HAIKU__ */
|
||||
|
||||
gTTYModule->ttyinit(&fTTY, false);
|
||||
fTTYFile.tty = &fTTY;
|
||||
fTTYFile.flags = flags;
|
||||
|
||||
|
||||
ResetDevice();
|
||||
|
||||
struct ddrover *ddr = gTTYModule->ddrstart(NULL);
|
||||
@@ -418,9 +600,11 @@ SerialDevice::Open(uint32 flags)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
gTTYModule->ddacquire(ddr, &gSerialDomain);
|
||||
status_t status = gTTYModule->ttyopen(&fTTYFile, ddr, pc_serial_service);
|
||||
status = gTTYModule->ttyopen(&fTTYFile, ddr, pc_serial_service);
|
||||
gTTYModule->ddrdone(ddr);
|
||||
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
if (status < B_OK) {
|
||||
TRACE_ALWAYS("open: failed to open tty\n");
|
||||
return status;
|
||||
@@ -460,30 +644,33 @@ SerialDevice::Read(char *buffer, size_t *numBytes)
|
||||
}
|
||||
|
||||
status_t status;
|
||||
#if 0
|
||||
status_t status = mutex_lock(&fReadLock);
|
||||
|
||||
#ifdef __HAIKU__
|
||||
|
||||
status = mutex_lock(&fReadLock);
|
||||
if (status != B_OK) {
|
||||
TRACE_ALWAYS("read: failed to get read lock\n");
|
||||
*numBytes = 0;
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
status = gTTYModule->tty_read(fTTYCookie, buffer, numBytes);
|
||||
|
||||
mutex_unlock(&fReadLock);
|
||||
|
||||
#else /* __HAIKU__ */
|
||||
|
||||
struct ddrover *ddr = gTTYModule->ddrstart(NULL);
|
||||
if (!ddr) {
|
||||
*numBytes = 0;
|
||||
#if 0
|
||||
mutex_unlock(&fReadLock);
|
||||
#endif
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
status = gTTYModule->ttyread(&fTTYFile, ddr, buffer, numBytes);
|
||||
gTTYModule->ddrdone(ddr);
|
||||
|
||||
#if 0
|
||||
mutex_unlock(&fReadLock);
|
||||
#endif
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -491,10 +678,25 @@ SerialDevice::Read(char *buffer, size_t *numBytes)
|
||||
status_t
|
||||
SerialDevice::Write(const char *buffer, size_t *numBytes)
|
||||
{
|
||||
size_t bytesLeft = *numBytes;
|
||||
//size_t bytesLeft = *numBytes;
|
||||
//*numBytes = 0;
|
||||
|
||||
status_t status = EINVAL;
|
||||
|
||||
#ifdef __HAIKU__
|
||||
|
||||
status = mutex_lock(&fWriteLock);
|
||||
if (status != B_OK) {
|
||||
TRACE_ALWAYS("write: failed to get write lock\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
//XXX: WTF tty_write() is not for write() hook ?
|
||||
//status = gTTYModule->tty_write(fTTYCookie, buffer, numBytes);
|
||||
mutex_unlock(&fWriteLock);
|
||||
|
||||
#else /* __HAIKU__ */
|
||||
|
||||
struct ddrover *ddr = gTTYModule->ddrstart(NULL);
|
||||
if (!ddr) {
|
||||
*numBytes = 0;
|
||||
@@ -504,6 +706,8 @@ SerialDevice::Write(const char *buffer, size_t *numBytes)
|
||||
status = gTTYModule->ttywrite(&fTTYFile, ddr, buffer, numBytes);
|
||||
gTTYModule->ddrdone(ddr);
|
||||
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
#if 0
|
||||
status_t status = mutex_lock(&fWriteLock);
|
||||
if (status != B_OK) {
|
||||
@@ -560,15 +764,26 @@ SerialDevice::Write(const char *buffer, size_t *numBytes)
|
||||
status_t
|
||||
SerialDevice::Control(uint32 op, void *arg, size_t length)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
if (fDeviceRemoved)
|
||||
return B_DEV_NOT_READY;
|
||||
|
||||
#ifdef __HAIKU__
|
||||
|
||||
status = gTTYModule->tty_control(fTTYCookie, op, arg, length);
|
||||
|
||||
#else /* __HAIKU__ */
|
||||
|
||||
struct ddrover *ddr = gTTYModule->ddrstart(NULL);
|
||||
if (!ddr)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t status = gTTYModule->ttycontrol(&fTTYFile, ddr, op, arg, length);
|
||||
status = gTTYModule->ttycontrol(&fTTYFile, ddr, op, arg, length);
|
||||
gTTYModule->ddrdone(ddr);
|
||||
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -579,13 +794,22 @@ SerialDevice::Select(uint8 event, uint32 ref, selectsync *sync)
|
||||
if (fDeviceRemoved)
|
||||
return B_DEV_NOT_READY;
|
||||
|
||||
#ifdef __HAIKU__
|
||||
|
||||
return gTTYModule->tty_select(fTTYCookie, event, ref, sync);
|
||||
|
||||
#else /* __HAIKU__ */
|
||||
|
||||
struct ddrover *ddr = gTTYModule->ddrstart(NULL);
|
||||
if (!ddr)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t status = gTTYModule->ttyselect(&fTTYFile, ddr, event, ref, sync);
|
||||
gTTYModule->ddrdone(ddr);
|
||||
|
||||
return status;
|
||||
|
||||
#endif /* __HAIKU__ */
|
||||
}
|
||||
|
||||
|
||||
@@ -595,19 +819,30 @@ SerialDevice::DeSelect(uint8 event, selectsync *sync)
|
||||
if (fDeviceRemoved)
|
||||
return B_DEV_NOT_READY;
|
||||
|
||||
#ifdef __HAIKU__
|
||||
|
||||
return gTTYModule->tty_deselect(fTTYCookie, event, sync);
|
||||
|
||||
#else /* __HAIKU__ */
|
||||
|
||||
struct ddrover *ddr = gTTYModule->ddrstart(NULL);
|
||||
if (!ddr)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t status = gTTYModule->ttydeselect(&fTTYFile, ddr, event, sync);
|
||||
gTTYModule->ddrdone(ddr);
|
||||
|
||||
return status;
|
||||
|
||||
#endif /* __HAIKU__ */
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SerialDevice::Close()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
OnClose();
|
||||
|
||||
if (!fDeviceRemoved) {
|
||||
@@ -618,13 +853,18 @@ SerialDevice::Close()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __HAIKU__
|
||||
gTTYModule->tty_destroy_cookie(fTTYCookie);
|
||||
#else /* __HAIKU__ */
|
||||
struct ddrover *ddr = gTTYModule->ddrstart(NULL);
|
||||
if (!ddr)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t status = gTTYModule->ttyclose(&fTTYFile, ddr);
|
||||
status = gTTYModule->ttyclose(&fTTYFile, ddr);
|
||||
gTTYModule->ddrdone(ddr);
|
||||
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
fDeviceOpen = false;
|
||||
return status;
|
||||
}
|
||||
@@ -633,12 +873,18 @@ SerialDevice::Close()
|
||||
status_t
|
||||
SerialDevice::Free()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
#ifdef __HAIKU__
|
||||
gTTYModule->tty_destroy(fMasterTTY);
|
||||
gTTYModule->tty_destroy(fSlaveTTY);
|
||||
#else /* __HAIKU__ */
|
||||
struct ddrover *ddr = gTTYModule->ddrstart(NULL);
|
||||
if (!ddr)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t status = gTTYModule->ttyfree(&fTTYFile, ddr);
|
||||
status = gTTYModule->ttyfree(&fTTYFile, ddr);
|
||||
gTTYModule->ddrdone(ddr);
|
||||
#endif /* __HAIKU__ */
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -661,7 +907,7 @@ SerialDevice::Removed()
|
||||
gUSBModule->cancel_queued_transfers(fControlPipe);
|
||||
#endif
|
||||
|
||||
int32 result = B_OK;
|
||||
//int32 result = B_OK;
|
||||
//wait_for_thread(fDeviceThread, &result);
|
||||
fDeviceThread = -1;
|
||||
|
||||
@@ -696,9 +942,14 @@ SerialDevice::SetLineCoding(usb_serial_line_coding *coding)
|
||||
#endif
|
||||
|
||||
status_t
|
||||
SerialDevice::SetControlLineState(uint16 state)
|
||||
SerialDevice::SignalControlLineState(int line, bool enable)
|
||||
{
|
||||
// default implementation - does nothing
|
||||
#ifdef __HAIKU__
|
||||
gTTYModule->tty_hardware_signal(fTTYCookie, line, enable);
|
||||
#else
|
||||
// XXX: only works for interrupt handler, Service func must pass the ddrover
|
||||
gTTYModule->ttyhwsignal(&fTTY, &fRover, line, enable);
|
||||
#endif
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -727,8 +978,8 @@ SerialDevice::OnClose()
|
||||
int32
|
||||
SerialDevice::DeviceThread(void *data)
|
||||
{
|
||||
SerialDevice *device = (SerialDevice *)data;
|
||||
#if 0
|
||||
SerialDevice *device = (SerialDevice *)data;
|
||||
|
||||
while (!device->fStopDeviceThread) {
|
||||
status_t status = gUSBModule->queue_bulk(device->fReadPipe,
|
||||
@@ -868,7 +1119,7 @@ SerialDevice::MakeDevice(usb_device device, uint16 vendorID,
|
||||
if (!description)
|
||||
break;
|
||||
|
||||
return new ProlificDevice(device, vendorID, productID, description);
|
||||
return new(std::nothrow) ProlificDevice(device, vendorID, productID, description);
|
||||
}
|
||||
|
||||
case VENDOR_FTDI:
|
||||
@@ -881,7 +1132,7 @@ SerialDevice::MakeDevice(usb_device device, uint16 vendorID,
|
||||
if (!description)
|
||||
break;
|
||||
|
||||
return new FTDIDevice(device, vendorID, productID, description);
|
||||
return new(std::nothrow) FTDIDevice(device, vendorID, productID, description);
|
||||
}
|
||||
|
||||
case VENDOR_PALM:
|
||||
@@ -895,11 +1146,11 @@ SerialDevice::MakeDevice(usb_device device, uint16 vendorID,
|
||||
if (!description)
|
||||
break;
|
||||
|
||||
return new KLSIDevice(device, vendorID, productID, description);
|
||||
return new(std::nothrow) KLSIDevice(device, vendorID, productID, description);
|
||||
}
|
||||
}
|
||||
|
||||
return new ACMDevice(device, vendorID, productID, "CDC ACM compatible device");
|
||||
return new(std::nothrow) ACMDevice(device, vendorID, productID, "CDC ACM compatible device");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -43,9 +43,17 @@ static SerialDevice * MakeDevice(struct serial_config_descriptor
|
||||
char * WriteBuffer() { return fWriteBuffer; };
|
||||
size_t WriteBufferSize() { return fWriteBufferSize; };
|
||||
|
||||
#ifdef __BEOS__
|
||||
void SetModes();
|
||||
#endif
|
||||
void SetModes(struct termios *tios);
|
||||
#ifdef __HAIKU__
|
||||
bool Service(struct tty *tty, uint32 op,
|
||||
void *buffer, size_t length);
|
||||
#else
|
||||
bool Service(struct tty *ptty, struct ddrover *ddr,
|
||||
uint flags);
|
||||
#endif
|
||||
|
||||
int32 InterruptHandler();
|
||||
|
||||
@@ -68,10 +76,11 @@ virtual status_t AddDevice(const struct serial_config_descriptor *device);
|
||||
virtual status_t ResetDevice();
|
||||
|
||||
//virtual status_t SetLineCoding(usb_serial_line_coding *coding);
|
||||
virtual status_t SetControlLineState(uint16 state);
|
||||
//virtual status_t SetControlLineState(uint16 state);
|
||||
virtual status_t SignalControlLineState(int line, bool enable);
|
||||
|
||||
virtual void OnRead(char **buffer, size_t *numBytes);
|
||||
virtual void OnWrite(const char *buffer, size_t *numBytes,
|
||||
virtual void OnWrite(const char *buffer, size_t *numBytes,
|
||||
size_t *packetBytes);
|
||||
virtual void OnClose();
|
||||
|
||||
@@ -138,9 +147,15 @@ static void InterruptCallbackFunction(void *cookie,
|
||||
|
||||
uint16 fControlOut;
|
||||
bool fInputStopped;
|
||||
#ifdef __HAIKU__
|
||||
struct tty * fMasterTTY;
|
||||
struct tty * fSlaveTTY;
|
||||
struct tty_cookie * fTTYCookie;
|
||||
#else
|
||||
struct ttyfile fTTYFile;
|
||||
struct tty fTTY;
|
||||
struct ddrover fRover;
|
||||
#endif
|
||||
|
||||
/* device thread management */
|
||||
thread_id fDeviceThread;
|
||||
|
||||
@@ -69,7 +69,7 @@ create_log_file()
|
||||
|
||||
|
||||
void
|
||||
usb_serial_trace(bool force, char *format, ...)
|
||||
usb_serial_trace(bool force, const char *format, ...)
|
||||
{
|
||||
if (!gLogEnabled && !force)
|
||||
return;
|
||||
@@ -98,15 +98,6 @@ usb_serial_trace(bool force, char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
trace_ddomain(struct ddomain *dd)
|
||||
{
|
||||
TRACE("struct ddomain:\n"
|
||||
"\tddrover: 0x%08x\n"
|
||||
"\tbg: %d, locked: %d\n", dd->r, dd->bg, dd->locked);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
trace_termios(struct termios *tios)
|
||||
{
|
||||
@@ -128,6 +119,18 @@ trace_termios(struct termios *tios)
|
||||
}
|
||||
|
||||
|
||||
#ifdef __BEOS__
|
||||
|
||||
|
||||
void
|
||||
trace_ddomain(struct ddomain *dd)
|
||||
{
|
||||
TRACE("struct ddomain:\n"
|
||||
"\tddrover: 0x%08x\n"
|
||||
"\tbg: %d, locked: %d\n", dd->r, dd->bg, dd->locked);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
trace_str(struct str *str)
|
||||
{
|
||||
@@ -182,3 +185,6 @@ trace_tty(struct tty *tty)
|
||||
|
||||
TRACE("\tservice: 0x%08x\n", tty->service);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __BEOS__ */
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
void load_settings();
|
||||
void create_log_file();
|
||||
void usb_serial_trace(bool force, char *format, ...);
|
||||
void usb_serial_trace(bool force, const char *format, ...);
|
||||
|
||||
#define TRACE_ALWAYS(x...) usb_serial_trace(true, x);
|
||||
#define TRACE(x...) usb_serial_trace(false, x);
|
||||
@@ -30,10 +30,13 @@ extern bool gLogFunctionResults;
|
||||
if (gLogFunctionResults) \
|
||||
func(param);
|
||||
|
||||
void trace_ddomain(struct ddomain *dd);
|
||||
void trace_termios(struct termios *tios);
|
||||
|
||||
#ifdef __BEOS__
|
||||
void trace_ddomain(struct ddomain *dd);
|
||||
void trace_str(struct str *str);
|
||||
void trace_winsize(struct winsize *ws);
|
||||
void trace_tty(struct tty *tty);
|
||||
#endif /* __BEOS__ */
|
||||
|
||||
#endif //_PC_SERIAL_TRACING_H_
|
||||
|
||||
Reference in New Issue
Block a user