Thread secured the COM driver.
This commit is contained in:
parent
f3f33e22e7
commit
38349da082
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
|
||||||
|
|
||||||
This file is part of Sortix.
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <sortix/kernel/platform.h>
|
#include <sortix/kernel/platform.h>
|
||||||
|
#include <sortix/kernel/kthread.h>
|
||||||
#include <libmaxsi/error.h>
|
#include <libmaxsi/error.h>
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
@ -52,7 +53,17 @@ namespace COM {
|
||||||
|
|
||||||
// Yet another alternative is to use POLL_HACK, but return EGAIN and let user-
|
// Yet another alternative is to use POLL_HACK, but return EGAIN and let user-
|
||||||
// space call retry, rather than relying on the broken syscall interstructure.
|
// space call retry, rather than relying on the broken syscall interstructure.
|
||||||
|
#ifndef GOT_ACTUAL_KTHREAD
|
||||||
#define POLL_EAGAIN 1
|
#define POLL_EAGAIN 1
|
||||||
|
#else
|
||||||
|
#define POLL_EAGAIN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !POLL_EAGAIN && !POLL_HACK && defined(GOT_ACTUAL_KTHREAD)
|
||||||
|
#error The interrupt-based code was broken in the kthread branch.
|
||||||
|
#error You need to port this to the new thread/interrupt API.
|
||||||
|
#warning Oh, and fix the above mentioned bugs too.
|
||||||
|
#endif
|
||||||
|
|
||||||
const uint16_t TXR = 0; // Transmit register
|
const uint16_t TXR = 0; // Transmit register
|
||||||
const uint16_t RXR = 0; // Receive register
|
const uint16_t RXR = 0; // Receive register
|
||||||
|
@ -222,14 +233,18 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
|
kthread_mutex_t portlock;
|
||||||
|
#ifdef GOT_FAKE_KTHREAD
|
||||||
Event dataevent;
|
Event dataevent;
|
||||||
Event sentevent;
|
Event sentevent;
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DevCOMPort::DevCOMPort(uint16_t port)
|
DevCOMPort::DevCOMPort(uint16_t port)
|
||||||
{
|
{
|
||||||
this->port = port;
|
this->port = port;
|
||||||
|
this->portlock = KTHREAD_MUTEX_INITIALIZER;
|
||||||
}
|
}
|
||||||
|
|
||||||
DevCOMPort::~DevCOMPort()
|
DevCOMPort::~DevCOMPort()
|
||||||
|
@ -247,7 +262,16 @@ ssize_t DevCOMPort::Read(byte* dest, size_t count)
|
||||||
{
|
{
|
||||||
if ( !count ) { return 0; }
|
if ( !count ) { return 0; }
|
||||||
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
||||||
|
ScopedLock lock(&portlock);
|
||||||
|
|
||||||
|
#ifdef GOT_ACTUAL_KTHREAD
|
||||||
|
while ( !(CPU::InPortB(port + LSR) & LSR_READY) )
|
||||||
|
if ( Signal::IsPending() )
|
||||||
|
{
|
||||||
|
Error::Set(EINTR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
uint8_t lsr;
|
uint8_t lsr;
|
||||||
for ( unsigned i = 0; i < TRIES; i++ )
|
for ( unsigned i = 0; i < TRIES; i++ )
|
||||||
{
|
{
|
||||||
|
@ -265,6 +289,7 @@ ssize_t DevCOMPort::Read(byte* dest, size_t count)
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t sofar = 0;
|
size_t sofar = 0;
|
||||||
do
|
do
|
||||||
|
@ -281,6 +306,16 @@ ssize_t DevCOMPort::Write(const byte* src, size_t count)
|
||||||
if ( !count ) { return 0; }
|
if ( !count ) { return 0; }
|
||||||
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; };
|
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; };
|
||||||
|
|
||||||
|
ScopedLock lock(&portlock);
|
||||||
|
|
||||||
|
#ifdef GOT_ACTUAL_KTHREAD
|
||||||
|
while ( !(CPU::InPortB(port + LSR) & LSR_THRE) )
|
||||||
|
if ( Signal::IsPending() )
|
||||||
|
{
|
||||||
|
Error::Set(EINTR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
uint8_t lsr;
|
uint8_t lsr;
|
||||||
for ( unsigned i = 0; i < TRIES; i++ )
|
for ( unsigned i = 0; i < TRIES; i++ )
|
||||||
{
|
{
|
||||||
|
@ -298,6 +333,7 @@ ssize_t DevCOMPort::Write(const byte* src, size_t count)
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t sofar = 0;
|
size_t sofar = 0;
|
||||||
do
|
do
|
||||||
|
@ -321,7 +357,11 @@ ssize_t DevCOMPort::Read(byte* dest, size_t count)
|
||||||
uint8_t lsr = CPU::InPortB(port + LSR);
|
uint8_t lsr = CPU::InPortB(port + LSR);
|
||||||
if ( !(lsr & LSR_READY) )
|
if ( !(lsr & LSR_READY) )
|
||||||
{
|
{
|
||||||
|
#ifdef GOT_ACTUAL_KTHREAD
|
||||||
|
Panic("Can't wait for com data receive event");
|
||||||
|
#else
|
||||||
dataevent.Register();
|
dataevent.Register();
|
||||||
|
#endif
|
||||||
Error::Set(EBLOCKING);
|
Error::Set(EBLOCKING);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -346,7 +386,11 @@ ssize_t DevCOMPort::Write(const byte* src, size_t count)
|
||||||
uint8_t lsr = CPU::InPortB(port + LSR);
|
uint8_t lsr = CPU::InPortB(port + LSR);
|
||||||
if ( !(lsr & LSR_THRE) )
|
if ( !(lsr & LSR_THRE) )
|
||||||
{
|
{
|
||||||
|
#ifdef GOT_ACTUAL_KTHREAD
|
||||||
|
Panic("Can't wait for com data sent event");
|
||||||
|
#else
|
||||||
sentevent.Register();
|
sentevent.Register();
|
||||||
|
#endif
|
||||||
Error::Set(EBLOCKING);
|
Error::Set(EBLOCKING);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -382,10 +426,18 @@ void DevCOMPort::OnInterrupt()
|
||||||
CPU::InPortB(port + LSR);
|
CPU::InPortB(port + LSR);
|
||||||
break;
|
break;
|
||||||
case IIR_RECV_DATA:
|
case IIR_RECV_DATA:
|
||||||
|
#ifdef GOT_ACTUAL_KTHREAD
|
||||||
|
Panic("Can't wait for com data sent event");
|
||||||
|
#else
|
||||||
dataevent.Signal();
|
dataevent.Signal();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case IIR_SENT_DATA:
|
case IIR_SENT_DATA:
|
||||||
|
#ifdef GOT_ACTUAL_KTHREAD
|
||||||
|
Panic("Can't wait for com data sent event");
|
||||||
|
#else
|
||||||
sentevent.Signal();
|
sentevent.Signal();
|
||||||
|
#endif
|
||||||
CPU::InPortB(port + IIR);
|
CPU::InPortB(port + IIR);
|
||||||
break;
|
break;
|
||||||
case IIR_MODEM_STATUS:
|
case IIR_MODEM_STATUS:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
|
||||||
|
|
||||||
This file is part of Sortix.
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue