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/error.h>
|
||||||
#include <libmaxsi/memory.h>
|
#include <libmaxsi/memory.h>
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
|
#include "fs/devfs.h"
|
||||||
|
|
||||||
// TODO: Use the PCI to detect ATA devices instead of relying on them being on
|
// TODO: Use the PCI to detect ATA devices instead of relying on them being on
|
||||||
// standard locations.
|
// standard locations.
|
||||||
|
@ -66,7 +67,7 @@ namespace Sortix
|
||||||
unsigned ataid = busid*2 + driveid;
|
unsigned ataid = busid*2 + driveid;
|
||||||
ATADrive* drive = bus->Instatiate(driveid);
|
ATADrive* drive = bus->Instatiate(driveid);
|
||||||
if ( !drive ) { return; }
|
if ( !drive ) { return; }
|
||||||
// TODO: Actually use the drive somewhere.
|
RegisterATADrive(ataid, drive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectBus(unsigned busid, uint16_t ioport, uint16_t altio)
|
void DetectBus(unsigned busid, uint16_t ioport, uint16_t altio)
|
||||||
|
@ -78,6 +79,7 @@ namespace Sortix
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
|
InitATADriveList();
|
||||||
DetectBus(0, 0x1F0, 0x3F6);
|
DetectBus(0, 0x1F0, 0x3F6);
|
||||||
DetectBus(1, 0x170, 0x366);
|
DetectBus(1, 0x170, 0x366);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,12 +30,125 @@
|
||||||
#include "../directory.h"
|
#include "../directory.h"
|
||||||
#include "../stream.h"
|
#include "../stream.h"
|
||||||
#include "../vga.h"
|
#include "../vga.h"
|
||||||
|
#include "../ata.h"
|
||||||
#include "devfs.h"
|
#include "devfs.h"
|
||||||
|
|
||||||
using namespace Maxsi;
|
using namespace Maxsi;
|
||||||
|
|
||||||
namespace Sortix
|
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
|
class DevLogTTY : public DevStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -177,8 +290,8 @@ namespace Sortix
|
||||||
|
|
||||||
int DevDevFSDir::Read(sortix_dirent* dirent, size_t available)
|
int DevDevFSDir::Read(sortix_dirent* dirent, size_t available)
|
||||||
{
|
{
|
||||||
const char* names[] = { "null", "tty", "vga" };
|
const char* names[] = { "null", "tty", "vga", "ata0", "ata1", "ata2", "ata3" };
|
||||||
const size_t nameslength = 3;
|
const size_t nameslength = 7;
|
||||||
|
|
||||||
if ( available <= sizeof(sortix_dirent) ) { return -1; }
|
if ( available <= sizeof(sortix_dirent) ) { return -1; }
|
||||||
if ( nameslength <= position )
|
if ( nameslength <= position )
|
||||||
|
@ -192,6 +305,15 @@ namespace Sortix
|
||||||
size_t namelen = String::Length(name);
|
size_t namelen = String::Length(name);
|
||||||
size_t needed = sizeof(sortix_dirent) + namelen + 1;
|
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 )
|
if ( available < needed )
|
||||||
{
|
{
|
||||||
dirent->d_namelen = needed;
|
dirent->d_namelen = needed;
|
||||||
|
@ -225,6 +347,23 @@ namespace Sortix
|
||||||
if ( String::Compare(path, "/null") == 0 ) { return new DevNull; }
|
if ( String::Compare(path, "/null") == 0 ) { return new DevNull; }
|
||||||
if ( String::Compare(path, "/tty") == 0 ) { return new DevLogTTY; }
|
if ( String::Compare(path, "/tty") == 0 ) { return new DevLogTTY; }
|
||||||
if ( String::Compare(path, "/vga") == 0 ) { return new DevVGA; }
|
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);
|
Error::Set(flags & O_CREAT ? EPERM : ENOENT);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
|
class ATADrive;
|
||||||
|
|
||||||
class DevDevFS : public DevFileSystem
|
class DevDevFS : public DevFileSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -41,6 +43,9 @@ namespace Sortix
|
||||||
virtual bool Unlink(const char* path);
|
virtual bool Unlink(const char* path);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void InitATADriveList();
|
||||||
|
void RegisterATADrive(unsigned ataid, ATADrive* drive);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue