mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Made detected ATA devices available as /dev/ataN block devices.
This commit is contained in:
parent
a3a2226bb5
commit
d3ad36b181
3 changed files with 149 additions and 3 deletions
|
@ -26,6 +26,7 @@
|
|||
#include <libmaxsi/error.h>
|
||||
#include <libmaxsi/memory.h>
|
||||
#include "ata.h"
|
||||
#include "fs/devfs.h"
|
||||
|
||||
// TODO: Use the PCI to detect ATA devices instead of relying on them being on
|
||||
// standard locations.
|
||||
|
@ -66,7 +67,7 @@ namespace Sortix
|
|||
unsigned ataid = busid*2 + driveid;
|
||||
ATADrive* drive = bus->Instatiate(driveid);
|
||||
if ( !drive ) { return; }
|
||||
// TODO: Actually use the drive somewhere.
|
||||
RegisterATADrive(ataid, drive);
|
||||
}
|
||||
|
||||
void DetectBus(unsigned busid, uint16_t ioport, uint16_t altio)
|
||||
|
@ -78,6 +79,7 @@ namespace Sortix
|
|||
|
||||
void Init()
|
||||
{
|
||||
InitATADriveList();
|
||||
DetectBus(0, 0x1F0, 0x3F6);
|
||||
DetectBus(1, 0x170, 0x366);
|
||||
}
|
||||
|
|
|
@ -30,12 +30,125 @@
|
|||
#include "../directory.h"
|
||||
#include "../stream.h"
|
||||
#include "../vga.h"
|
||||
#include "../ata.h"
|
||||
#include "devfs.h"
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
class DevATA : public DevBuffer
|
||||
{
|
||||
public:
|
||||
typedef DevBuffer BaseClass;
|
||||
|
||||
public:
|
||||
DevATA(ATADrive* drive);
|
||||
virtual ~DevATA();
|
||||
|
||||
private:
|
||||
ATADrive* drive;
|
||||
off_t offset;
|
||||
|
||||
public:
|
||||
virtual ssize_t Read(byte* dest, size_t count);
|
||||
virtual ssize_t Write(const byte* src, size_t count);
|
||||
virtual bool IsReadable();
|
||||
virtual bool IsWritable();
|
||||
virtual size_t BlockSize();
|
||||
virtual uintmax_t Size();
|
||||
virtual uintmax_t Position();
|
||||
virtual bool Seek(uintmax_t position);
|
||||
virtual bool Resize(uintmax_t size);
|
||||
|
||||
};
|
||||
|
||||
DevATA::DevATA(ATADrive* drive)
|
||||
{
|
||||
this->drive = drive;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
DevATA::~DevATA()
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t DevATA::Read(byte* dest, size_t count)
|
||||
{
|
||||
if ( SIZE_MAX < count ) { count = SIZE_MAX; }
|
||||
if ( drive->GetSize() - offset < count ) { count = drive->GetSize() - offset; }
|
||||
size_t amount = drive->Read(offset, dest, count);
|
||||
if ( count && !amount ) { return -1; }
|
||||
offset += amount;
|
||||
return amount;
|
||||
}
|
||||
|
||||
ssize_t DevATA::Write(const byte* src, size_t count)
|
||||
{
|
||||
if ( SIZE_MAX < count ) { count = SIZE_MAX; }
|
||||
if ( drive->GetSize() <= offset && count ) { Error::Set(ENOSPC); return -1; }
|
||||
if ( drive->GetSize() - offset < count ) { count = drive->GetSize() - offset; }
|
||||
size_t amount = drive->Write(offset, src, count);
|
||||
if ( count && !amount ) { return -1; }
|
||||
offset += amount;
|
||||
return amount;
|
||||
}
|
||||
|
||||
bool DevATA::IsReadable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DevATA::IsWritable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t DevATA::BlockSize()
|
||||
{
|
||||
return drive->GetSectorSize();
|
||||
}
|
||||
|
||||
uintmax_t DevATA::Size()
|
||||
{
|
||||
return drive->GetSize();
|
||||
}
|
||||
|
||||
uintmax_t DevATA::Position()
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
bool DevATA::Seek(uintmax_t position)
|
||||
{
|
||||
if ( drive->GetSize() <= position ) { Error::Set(ENOSPC); return false; }
|
||||
offset = position;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DevATA::Resize(uintmax_t size)
|
||||
{
|
||||
Error::Set(EPERM);
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t NUM_ATAS = 4;
|
||||
DevATA* atalist[NUM_ATAS];
|
||||
|
||||
void InitATADriveList()
|
||||
{
|
||||
for ( size_t i = 0; i < NUM_ATAS; i++ )
|
||||
{
|
||||
atalist[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterATADrive(unsigned ataid, ATADrive* drive)
|
||||
{
|
||||
atalist[ataid] = new DevATA(drive);
|
||||
atalist[ataid]->Refer();
|
||||
}
|
||||
|
||||
class DevLogTTY : public DevStream
|
||||
{
|
||||
public:
|
||||
|
@ -177,8 +290,8 @@ namespace Sortix
|
|||
|
||||
int DevDevFSDir::Read(sortix_dirent* dirent, size_t available)
|
||||
{
|
||||
const char* names[] = { "null", "tty", "vga" };
|
||||
const size_t nameslength = 3;
|
||||
const char* names[] = { "null", "tty", "vga", "ata0", "ata1", "ata2", "ata3" };
|
||||
const size_t nameslength = 7;
|
||||
|
||||
if ( available <= sizeof(sortix_dirent) ) { return -1; }
|
||||
if ( nameslength <= position )
|
||||
|
@ -192,6 +305,15 @@ namespace Sortix
|
|||
size_t namelen = String::Length(name);
|
||||
size_t needed = sizeof(sortix_dirent) + namelen + 1;
|
||||
|
||||
if ( name[0] == 'a' && name[1] == 't' && name[2] == 'a' )
|
||||
{
|
||||
if ( !atalist[name[3]-'0'] )
|
||||
{
|
||||
position++;
|
||||
return Read(dirent, available);
|
||||
}
|
||||
}
|
||||
|
||||
if ( available < needed )
|
||||
{
|
||||
dirent->d_namelen = needed;
|
||||
|
@ -225,6 +347,23 @@ namespace Sortix
|
|||
if ( String::Compare(path, "/null") == 0 ) { return new DevNull; }
|
||||
if ( String::Compare(path, "/tty") == 0 ) { return new DevLogTTY; }
|
||||
if ( String::Compare(path, "/vga") == 0 ) { return new DevVGA; }
|
||||
if ( path[0] == '/' && path[1] == 'a' && path[2] == 't' && path[3] == 'a' && path[4] && !path[5] )
|
||||
{
|
||||
if ( '0' <= path[4] && path[4] <= '9' )
|
||||
{
|
||||
size_t index = path[4] - '0';
|
||||
if ( index <= NUM_ATAS && atalist[index] )
|
||||
{
|
||||
bool write = flags & O_WRONLY; // TODO: HACK: O_RDWD != O_WRONLY | O_RDONLY
|
||||
if ( write && !ENABLE_DISKWRITE )
|
||||
{
|
||||
Error::Set(EPERM);
|
||||
return false;
|
||||
}
|
||||
return new DevFileWrapper(atalist[index], flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Error::Set(flags & O_CREAT ? EPERM : ENOENT);
|
||||
return NULL;
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
namespace Sortix
|
||||
{
|
||||
class ATADrive;
|
||||
|
||||
class DevDevFS : public DevFileSystem
|
||||
{
|
||||
public:
|
||||
|
@ -41,6 +43,9 @@ namespace Sortix
|
|||
virtual bool Unlink(const char* path);
|
||||
|
||||
};
|
||||
|
||||
void InitATADriveList();
|
||||
void RegisterATADrive(unsigned ataid, ATADrive* drive);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue