banan-os/kernel/kernel/USB/USBManager.cpp

89 lines
2.2 KiB
C++

#include <BAN/UniqPtr.h>
#include <kernel/USB/USBManager.h>
#include <kernel/USB/XHCI/Controller.h>
namespace Kernel
{
static BAN::UniqPtr<USBManager> s_instance;
BAN::ErrorOr<void> USBManager::initialize()
{
ASSERT(!s_instance);
auto manager = TRY(BAN::UniqPtr<USBManager>::create());
s_instance = BAN::move(manager);
PCI::PCIManager::get().for_each_device(
[](PCI::Device& pci_device)
{
if (pci_device.class_code() != 0x0C || pci_device.subclass() != 0x03)
return;
switch (pci_device.prog_if())
{
case 0x00:
dprintln("Unsupported UHCI controller");
break;
case 0x10:
dprintln("Unsupported OHCI controller");
break;
case 0x20:
dprintln("Unsupported EHCI controller");
break;
case 0x30:
if (auto ret = XHCIController::take_ownership(pci_device); ret.is_error())
dprintln("Could not take ownership of xHCI controller: {}", ret.error());
else
dprintln("Took ownership of xHCI controller");
break;
default:
dprintln("Unsupported USB controller, prog if {2H}", pci_device.prog_if());
break;
}
}
);
return {};
}
USBManager& USBManager::get()
{
ASSERT(s_instance);
return *s_instance;
}
BAN::ErrorOr<void> USBManager::add_controller(PCI::Device& pci_device)
{
ASSERT(pci_device.class_code() == 0x0C);
ASSERT(pci_device.subclass() == 0x03);
BAN::UniqPtr<USBController> controller;
switch (pci_device.prog_if())
{
case 0x00:
dprintln("Unsupported UHCI controller");
return BAN::Error::from_errno(ENOTSUP);
case 0x10:
dprintln("Unsupported OHCI controller");
return BAN::Error::from_errno(ENOTSUP);
case 0x20:
dprintln("Unsupported EHCI controller");
return BAN::Error::from_errno(ENOTSUP);
case 0x30:
if (auto ret = XHCIController::create(pci_device); ret.is_error())
dprintln("Could not initialize XHCI controller: {}", ret.error());
else
controller = ret.release_value();
break;
default:
dprintln("Unsupported USB controller, prog if {2H}", pci_device.prog_if());
return BAN::Error::from_errno(EINVAL);
}
TRY(m_controllers.push_back(BAN::move(controller)));
return {};
}
}