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; } }
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()); }
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; }
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); } }
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; }
void FileSystem::setRoot(Directory *newRoot) { m_root = new FileCache(newRoot, "/", ZERO); insertFileCache(newRoot, "."); insertFileCache(newRoot, ".."); }
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; }
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); }