예제 #1
0
void PCIServer::scan()
{
    Directory *busDir = ZERO, *slotDir = ZERO;
    u16 vendorID, deviceID;
    
    /*
     * Walk the PCI bus by performing a read
     * on the vendor and device ID's for each possible
     * bus, slot and function combination.
     */
    for (u16 bus = 0; bus < 256; bus++)
    {
    for (u16 slot = 0; slot < 32; slot++)
    {
        for (u16 func = 0; func < 8; func++)
        {
            /* Read ID's. */
            vendorID   = PCI_READ_WORD(bus, slot, func, PCI_VID);
            deviceID   = PCI_READ_WORD(bus, slot, func, PCI_DID);

            /* Is this a valid device? */
            if (vendorID == 0xffff || deviceID == 0xffff)
            {
            continue;
            }
            /* Create bus directory, if needed. */
            if (!busDir)
            {
            busDir = new Directory;
            rootDir->insert(DirectoryFile, "%x", bus);
            insertFileCache(busDir, "%x", bus);
        }
        /* Make slot directory, if needed. */
        if (!slotDir)
        {
            slotDir = new Directory;

            busDir->insert(DirectoryFile, "%x", slot);
                insertFileCache(slotDir, "%x/%x", bus, slot);
        }
        /* Then make & fill the function directory. */
        detect(bus, slot, func);
        slotDir->insert(DirectoryFile, "%x", func);
        }
        slotDir = ZERO;
    }
    busDir = ZERO;
    }
}
예제 #2
0
void DeviceServer::registerDevice(Device *dev, const char *path, ...)
{
    char buf[PATHLEN];
    va_list args;

    // Add to the list of Devices
    m_devices.insert(dev);

    // Initialize the device
    dev->initialize();

    // Add to the filesystem cache
    va_start(args, path);
    vsnprintf(buf, sizeof(buf), path, args);
    va_end(args);

    va_start(args, path);
    insertFileCache(dev, path, args);
    va_end(args);

    // Also add to the parent directory
    FileSystemPath p((char *)buf);
    Directory *parent;

    if (p.parent())
        parent = (Directory *) findFileCache(**p.parent())->file;
    else
        parent = (Directory *) m_root->file;

    parent->insert(dev->getType(), **p.base());
}
예제 #3
0
FileCache * FileSystem::insertFileCache(File *file, const char *pathFormat, ...)
{
    va_list args;

    va_start(args, pathFormat);
    FileCache *c = insertFileCache(file, pathFormat, args);
    va_end(args);

    return c;
}
예제 #4
0
void ProcFileSystem::refresh()
{
    CoreMessage msg;
    ProcessInfo info;
    String slash("/");
    Directory *procDir;

    // TODO: memory leak! Cleanup the whole cache first... (currently broken)
    // clearFileCache();
    rootDir->clear();

    /* Update root. */
    rootDir->insert(DirectoryFile, ".");
    rootDir->insert(DirectoryFile, "..");
    
    /* Reinsert into the cache. */
    insertFileCache(rootDir, ".");
    insertFileCache(rootDir, "..");

    // Refresh UserProcess table
    msg.action = ReadProcess;
    msg.buffer = procs;
    msg.number = ZERO;
    msg.type   = IPCType;
    IPCMessage(CORESRV_PID, API::SendReceive, &msg, sizeof(msg));

    // Insert processes pseudo files
    for (int i = 0; i < MAX_PROCS; i++)
    {
        // Skip unused PIDs
        if (!procs[i].command[0])
            continue;

        // Per-process directory
        procDir = new Directory;
        procDir->insert(DirectoryFile, ".");
        procDir->insert(DirectoryFile, "..");
        procDir->insert(RegularFile, "cmdline");
        procDir->insert(RegularFile, "status");
        rootDir->insert(DirectoryFile, "%u", i);

        // Insert into the cache
        insertFileCache(procDir, "%u",    i);
        insertFileCache(procDir, "%u/.",  i);
        insertFileCache(rootDir, "%u/..", i);

        // Set commandline
        insertFileCache(new PseudoFile("%s", procs[i].command),
                        "%u/cmdline", i);

        // Request kernel's process information
        ProcessCtl(i, InfoPID, (Address) &info);

        // Process status
        insertFileCache(new PseudoFile("%s", states[info.state]),
                        "%u/status",  i);
    }    
}
예제 #5
0
Error FileSystem::registerFile(File *file, const char *path, va_list args)
{
    char buf[PATHLEN];

    // Add to the filesystem cache
    vsnprintf(buf, sizeof(buf), path, args);
    insertFileCache(file, path, args);

    // Also add to the parent directory
    FileSystemPath p((char *)buf);
    Directory *parent;

    if (p.parent())
        parent = (Directory *) findFileCache(**p.parent())->file;
    else
        parent = (Directory *) m_root->file;

    parent->insert(file->getType(), **p.base());
    return ESUCCESS;
}
예제 #6
0
void FileSystem::setRoot(Directory *newRoot)
{
    m_root = new FileCache(newRoot, "/", ZERO);
    insertFileCache(newRoot, ".");
    insertFileCache(newRoot, "..");
}
예제 #7
0
Error FileSystem::processRequest(FileSystemRequest *req)
{
    char buf[PATHLEN];
    FileSystemPath path;
    FileCache *cache = ZERO; 
    File *file = ZERO;
    Directory *parent;
    FileSystemMessage *msg = req->getMessage();
    
    // Copy the file path
    if ((msg->result = VMCopy(msg->from, API::Read, (Address) buf,
                    (Address) msg->path, PATHLEN)) <= 0)
    {
        msg->result = EACCES;
        msg->type = IPCType;
        IPCMessage(msg->from, API::Send, msg, sizeof(*msg));
        return msg->result;
    }

    path.parse(buf + strlen(m_mountPath));

    // Do we have this file cached?
    if ((cache = findFileCache(&path)) ||
        (cache = lookupFile(&path)))
    {
        file = cache->file;
    }
    // File not found
    else if (msg->action != CreateFile)
    {
        msg->result = ENOENT;
        msg->type = IPCType;
        IPCMessage(msg->from, API::Send, msg, sizeof(*msg));
        return msg->result;
    }

    // Perform I/O on the file
    switch (msg->action)
    {
        case CreateFile:
            if (cache)
                msg->result = EEXIST;
            else
            {
                /* Attempt to create the new file. */
                if ((file = createFile(msg->filetype, msg->deviceID)))
                {
                    const char *p = **path.full();
                    insertFileCache(file, "%s", p);
            
                    /* Add directory entry to our parent. */
                    if (path.parent())
                    {
                        parent = (Directory *) findFileCache(**path.parent())->file;
                    }
                    else
                        parent = (Directory *) m_root->file;

                    parent->insert(file->getType(), **path.full());
                    msg->result = ESUCCESS;
                }
                else
                    msg->result = EIO;
            }
            break;

        case DeleteFile:
            if (cache->entries.count() == 0)
            {
                clearFileCache(cache);
                msg->result = ESUCCESS;
            }
            else
                msg->result = ENOTEMPTY;
            break;

        case StatFile:
            msg->result = file->status(msg);
            break;

        case ReadFile:
            {
                msg->result = file->read(req->getBuffer(), msg->size, msg->offset);
                if (req->getBuffer().getCount())
                    req->getBuffer().flush();
            }
            break;
        
        case WriteFile:
            {
                if (!req->getBuffer().getCount())
                    req->getBuffer().bufferedRead();

                msg->result = file->write(req->getBuffer(), msg->size, msg->offset);
            }
            break;
    }

    // Only send reply if completed (not EAGAIN)
    if (msg->result != EAGAIN)
    {
        msg->type = IPCType;
        IPCMessage(msg->from, API::Send, msg, sizeof(*msg));
    }
    return msg->result;
}
예제 #8
0
void PCIServer::detect(u16 bus, u16 slot, u16 func)
{
    Directory *dir;

    /* Create PCI function directory. Fill it with entries. */
    dir = new Directory;
    dir->insert(DirectoryFile, ".");
    dir->insert(DirectoryFile, "..");
    dir->insert(RegularFile, "config");
    dir->insert(RegularFile, "vendor");
    dir->insert(RegularFile, "device");
    dir->insert(RegularFile, "revision");
    dir->insert(RegularFile, "interrupt");
    dir->insert(RegularFile, "bar0");
    dir->insert(RegularFile, "bar1");
    dir->insert(RegularFile, "bar2");
    dir->insert(RegularFile, "bar3");
    dir->insert(RegularFile, "bar4");
    dir->insert(RegularFile, "bar5");
    insertFileCache(dir, "%x/%x/%x", bus, slot, func);

    /*
     * Now create actual files.
     * Put them into the cache.
     */
    insertFileCache(new PCIConfig(bus, slot, func),
            "%x/%x/%x/config", bus, slot, func);
    
    insertFileCache(new PCIRegister(bus, slot, func, PCI_VID, 2),
            "%x/%x/%x/vendor", bus, slot, func);
    
    insertFileCache(new PCIRegister(bus, slot, func, PCI_DID, 2),
            "%x/%x/%x/device", bus, slot, func);
                
    insertFileCache(new PCIRegister(bus, slot, func, PCI_RID, 1),
            "%x/%x/%x/revision",  bus, slot, func);

    insertFileCache(new PCIRegister(bus, slot, func, PCI_IRQ, 1),
            "%x/%x/%x/interrupt", bus, slot, func);

    insertFileCache(new PCIRegister(bus, slot, func, PCI_BAR0, 4),
            "%x/%x/%x/bar0", bus, slot, func);

    insertFileCache(new PCIRegister(bus, slot, func, PCI_BAR1, 4),
            "%x/%x/%x/bar1", bus, slot, func);

    insertFileCache(new PCIRegister(bus, slot, func, PCI_BAR2, 4),
            "%x/%x/%x/bar2", bus, slot, func);

    insertFileCache(new PCIRegister(bus, slot, func, PCI_BAR3, 4),
            "%x/%x/%x/bar3", bus, slot, func);

    insertFileCache(new PCIRegister(bus, slot, func, PCI_BAR4, 4),
            "%x/%x/%x/bar4", bus, slot, func);

    insertFileCache(new PCIRegister(bus, slot, func, PCI_BAR5, 4),
            "%x/%x/%x/bar5", bus, slot, func);
}