Thread secured the COM driver.

This commit is contained in:
Jonas 'Sortie' Termansen 2012-08-01 17:30:34 +02:00
parent f3f33e22e7
commit 38349da082
2 changed files with 54 additions and 2 deletions

View File

@ -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:

View File

@ -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.