mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Clean up the serial driver read and write routines.
This commit is contained in:
parent
a6603dffd9
commit
105278a500
1 changed files with 36 additions and 29 deletions
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sortix/fcntl.h>
|
||||||
#include <sortix/stat.h>
|
#include <sortix/stat.h>
|
||||||
|
|
||||||
#include <sortix/kernel/descriptor.h>
|
#include <sortix/kernel/descriptor.h>
|
||||||
|
@ -259,54 +260,60 @@ int DevCOMPort::sync(ioctx_t* /*ctx*/)
|
||||||
|
|
||||||
ssize_t DevCOMPort::read(ioctx_t* ctx, uint8_t* dest, size_t count)
|
ssize_t DevCOMPort::read(ioctx_t* ctx, uint8_t* dest, size_t count)
|
||||||
{
|
{
|
||||||
if ( !count ) { return 0; }
|
|
||||||
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
|
||||||
ScopedLock lock(&portlock);
|
ScopedLock lock(&portlock);
|
||||||
|
|
||||||
while ( !(CPU::InPortB(port + LSR) & LSR_READY) )
|
for ( size_t i = 0; i < count; i++ )
|
||||||
if ( Signal::IsPending() )
|
{
|
||||||
|
int tries = 0;
|
||||||
|
while ( !IsLineReady(port) )
|
||||||
{
|
{
|
||||||
errno = EINTR;
|
if ( ++tries < 10 )
|
||||||
return -1;
|
continue;
|
||||||
|
if ( i )
|
||||||
|
return (ssize_t) i;
|
||||||
|
if ( ctx->dflags & O_NONBLOCK )
|
||||||
|
return errno = EWOULDBLOCK, -1;
|
||||||
|
if ( Signal::IsPending() )
|
||||||
|
return errno = EINTR, -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sofar = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if ( count <= sofar ) { break; }
|
|
||||||
uint8_t val = CPU::InPortB(port + RXR);
|
uint8_t val = CPU::InPortB(port + RXR);
|
||||||
if ( !ctx->copy_to_dest(dest + sofar++, &val, sizeof(val)) )
|
if ( !ctx->copy_to_dest(dest + i, &val, sizeof(val)) )
|
||||||
return -1;
|
{
|
||||||
} while ( CPU::InPortB(port + LSR) & LSR_READY);
|
// TODO: The byte is lost in this case!
|
||||||
|
return i ? (ssize_t) i : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sofar;
|
return (ssize_t) count;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t DevCOMPort::write(ioctx_t* ctx, const uint8_t* src, size_t count)
|
ssize_t DevCOMPort::write(ioctx_t* ctx, const uint8_t* src, size_t count)
|
||||||
{
|
{
|
||||||
if ( !count ) { return 0; }
|
|
||||||
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; };
|
|
||||||
|
|
||||||
ScopedLock lock(&portlock);
|
ScopedLock lock(&portlock);
|
||||||
|
|
||||||
while ( !(CPU::InPortB(port + LSR) & LSR_THRE) )
|
for ( size_t i = 0; i < count; i++ )
|
||||||
if ( Signal::IsPending() )
|
{
|
||||||
|
int tries = 0;
|
||||||
|
while ( !CanWriteByte(port) )
|
||||||
{
|
{
|
||||||
errno = EINTR;
|
if ( ++tries < 10 )
|
||||||
return -1;
|
continue;
|
||||||
|
if ( i )
|
||||||
|
return (ssize_t) i;
|
||||||
|
if ( ctx->dflags & O_NONBLOCK )
|
||||||
|
return errno = EWOULDBLOCK, -1;
|
||||||
|
if ( Signal::IsPending() )
|
||||||
|
return errno = EINTR, -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sofar = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if ( count <= sofar ) { break; }
|
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
if ( !ctx->copy_from_src(&val, src + sofar++, sizeof(val)) )
|
if ( !ctx->copy_from_src(&val, src + i, sizeof(val)) )
|
||||||
return -1;
|
return i ? (ssize_t) i : -1;
|
||||||
CPU::OutPortB(port + TXR, val);
|
CPU::OutPortB(port + TXR, val);
|
||||||
} while ( CPU::InPortB(port + LSR) & LSR_THRE );
|
}
|
||||||
|
|
||||||
return sofar;
|
return (ssize_t) count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue