mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Refactored devfs so new devices can easily be added.
This commit is contained in:
parent
5ec4e33196
commit
798b421d16
4 changed files with 135 additions and 61 deletions
|
@ -67,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; }
|
||||||
RegisterATADrive(ataid, drive);
|
DeviceFS::RegisterATADrive(ataid, drive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectBus(unsigned busid, uint16_t ioport, uint16_t altio)
|
void DetectBus(unsigned busid, uint16_t ioport, uint16_t altio)
|
||||||
|
@ -79,7 +79,6 @@ namespace Sortix
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
InitATADriveList();
|
|
||||||
DetectBus(0, 0x1F0, 0x3F6);
|
DetectBus(0, 0x1F0, 0x3F6);
|
||||||
DetectBus(1, 0x170, 0x366);
|
DetectBus(1, 0x170, 0x366);
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,29 +127,12 @@ namespace Sortix
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DevATA::Resize(uintmax_t size)
|
bool DevATA::Resize(uintmax_t /*size*/)
|
||||||
{
|
{
|
||||||
Error::Set(EPERM);
|
Error::Set(EPERM);
|
||||||
return false;
|
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 DevNull : public DevStream
|
class DevNull : public DevStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -202,6 +185,85 @@ namespace Sortix
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move this namespace into something like devicefs.cpp.
|
||||||
|
namespace DeviceFS {
|
||||||
|
|
||||||
|
size_t entriesused;
|
||||||
|
size_t entrieslength;
|
||||||
|
DevEntry* deventries;
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
deventries = NULL;
|
||||||
|
entriesused = 0;
|
||||||
|
entrieslength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RegisterDevice(const char* name, Device* dev)
|
||||||
|
{
|
||||||
|
if ( entriesused == entrieslength )
|
||||||
|
{
|
||||||
|
size_t newentrieslength = entrieslength ? 32 : 2 * entrieslength;
|
||||||
|
DevEntry* newdeventries = new DevEntry[newentrieslength];
|
||||||
|
if ( !newdeventries ) { return false; }
|
||||||
|
size_t bytes = sizeof(DevEntry) * entriesused;
|
||||||
|
Memory::Copy(newdeventries, deventries, bytes);
|
||||||
|
delete[] deventries;
|
||||||
|
entrieslength = newentrieslength;
|
||||||
|
deventries = newdeventries;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* nameclone = String::Clone(name);
|
||||||
|
if ( !nameclone ) { return false; }
|
||||||
|
|
||||||
|
size_t index = entriesused++;
|
||||||
|
dev->Refer();
|
||||||
|
deventries[index].name = nameclone;
|
||||||
|
deventries[index].dev = dev;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Device* LookUp(const char* name)
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < entriesused; i++ )
|
||||||
|
{
|
||||||
|
if ( String::Compare(name, deventries[i].name) ) { continue; }
|
||||||
|
deventries[i].dev->Refer();
|
||||||
|
return deventries[i].dev;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetNumDevices()
|
||||||
|
{
|
||||||
|
return entriesused;
|
||||||
|
}
|
||||||
|
|
||||||
|
DevEntry* GetDevice(size_t index)
|
||||||
|
{
|
||||||
|
if ( entriesused <= index ) { return NULL; }
|
||||||
|
return deventries + index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Hack to register ATA devices.
|
||||||
|
// FIXME: Move class DevATA into ata.cpp.
|
||||||
|
void RegisterATADrive(unsigned ataid, ATADrive* drive)
|
||||||
|
{
|
||||||
|
DevATA* ata = new DevATA(drive);
|
||||||
|
if ( !ata ) { Panic("Cannot allocate ATA device"); }
|
||||||
|
ata->Refer();
|
||||||
|
ASSERT(ataid < 10);
|
||||||
|
char name[5] = "ataN";
|
||||||
|
name[3] = '0' + ataid;
|
||||||
|
if ( !RegisterDevice(name, ata) )
|
||||||
|
{
|
||||||
|
PanicF("Cannot register /dev/%s", name);
|
||||||
|
}
|
||||||
|
ata->Unref();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace DeviceFS
|
||||||
|
|
||||||
class DevDevFSDir : public DevDirectory
|
class DevDevFSDir : public DevDirectory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -236,30 +298,30 @@ 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", "ata0", "ata1", "ata2", "ata3" };
|
const char* names[] = { "null", "tty", "vga" };
|
||||||
const size_t nameslength = 7;
|
const char* name = NULL;
|
||||||
|
if ( position < DeviceFS::GetNumDevices() )
|
||||||
if ( available <= sizeof(sortix_dirent) ) { return -1; }
|
{
|
||||||
if ( nameslength <= position )
|
name = DeviceFS::GetDevice(position)->name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_t nameslength = 3;
|
||||||
|
size_t index = position - DeviceFS::GetNumDevices();
|
||||||
|
if ( nameslength <= index )
|
||||||
{
|
{
|
||||||
dirent->d_namelen = 0;
|
dirent->d_namelen = 0;
|
||||||
dirent->d_name[0] = 0;
|
dirent->d_name[0] = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
name = names[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( available <= sizeof(sortix_dirent) ) { return -1; }
|
||||||
|
|
||||||
const char* name = names[position];
|
|
||||||
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;
|
||||||
|
@ -283,7 +345,7 @@ namespace Sortix
|
||||||
|
|
||||||
extern DevTerminal* tty;
|
extern DevTerminal* tty;
|
||||||
|
|
||||||
Device* DevDevFS::Open(const char* path, int flags, mode_t mode)
|
Device* DevDevFS::Open(const char* path, int flags, mode_t /*mode*/)
|
||||||
{
|
{
|
||||||
int lowerflags = flags & O_LOWERFLAGS;
|
int lowerflags = flags & O_LOWERFLAGS;
|
||||||
|
|
||||||
|
@ -296,27 +358,22 @@ 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 ) { tty->Refer(); return tty; }
|
if ( String::Compare(path, "/tty") == 0 ) { tty->Refer(); return tty; }
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Device* dev = DeviceFS::LookUp(path + 1);
|
||||||
|
if ( !dev )
|
||||||
|
{
|
||||||
Error::Set(flags & O_CREAT ? EPERM : ENOENT);
|
Error::Set(flags & O_CREAT ? EPERM : ENOENT);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if ( dev->IsType(Device::BUFFER) )
|
||||||
|
{
|
||||||
|
DevBuffer* buffer = (DevBuffer*) dev;
|
||||||
|
DevFileWrapper* wrapper = new DevFileWrapper(buffer, flags);
|
||||||
|
buffer->Unref();
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
bool DevDevFS::Unlink(const char* path)
|
bool DevDevFS::Unlink(const char* path)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,8 +44,22 @@ namespace Sortix
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitATADriveList();
|
namespace DeviceFS {
|
||||||
|
|
||||||
|
struct DevEntry
|
||||||
|
{
|
||||||
|
char* name;
|
||||||
|
Device* dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Init();
|
||||||
void RegisterATADrive(unsigned ataid, ATADrive* drive);
|
void RegisterATADrive(unsigned ataid, ATADrive* drive);
|
||||||
|
bool RegisterDevice(const char* name, Device* dev);
|
||||||
|
Device* LookUp(const char* name);
|
||||||
|
size_t GetNumDevices();
|
||||||
|
DevEntry* GetDevice(size_t index);
|
||||||
|
|
||||||
|
} // namespace DeviceFS
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
#include "directory.h"
|
#include "directory.h"
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
|
#include "fs/devfs.h"
|
||||||
|
|
||||||
using namespace Maxsi;
|
using namespace Maxsi;
|
||||||
|
|
||||||
|
@ -217,6 +218,9 @@ namespace Sortix
|
||||||
// Initialize the kernel heap.
|
// Initialize the kernel heap.
|
||||||
Maxsi::Memory::Init();
|
Maxsi::Memory::Init();
|
||||||
|
|
||||||
|
// Initialize the list of kernel devices.
|
||||||
|
DeviceFS::Init();
|
||||||
|
|
||||||
// Initialize the keyboard.
|
// Initialize the keyboard.
|
||||||
Keyboard::Init();
|
Keyboard::Init();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue