Add XHCI.reset()
This commit is contained in:
parent
699f53ac15
commit
a02df12924
@ -11,6 +11,8 @@ module hulk.usb.xhci;
|
|||||||
import hulk.pci;
|
import hulk.pci;
|
||||||
import hulk.hurl.a1;
|
import hulk.hurl.a1;
|
||||||
import hulk.klog;
|
import hulk.klog;
|
||||||
|
import hulk.time;
|
||||||
|
import core.volatile;
|
||||||
|
|
||||||
struct XHCI
|
struct XHCI
|
||||||
{
|
{
|
||||||
@ -351,6 +353,14 @@ struct XHCI
|
|||||||
m_runtime_registers = cast(RuntimeRegisters *)(base_address + m_capability_registers.rts_offset);
|
m_runtime_registers = cast(RuntimeRegisters *)(base_address + m_capability_registers.rts_offset);
|
||||||
m_doorbell_registers = cast(DoorbellRegister *)(base_address + m_capability_registers.doorbell_offset);
|
m_doorbell_registers = cast(DoorbellRegister *)(base_address + m_capability_registers.doorbell_offset);
|
||||||
dump_extended_capabilities();
|
dump_extended_capabilities();
|
||||||
|
if (reset())
|
||||||
|
{
|
||||||
|
Klog.writefln("XHCI controller initialization successful");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Klog.writefln("XHCI controller failed to initialize");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dump_extended_capabilities()
|
private void dump_extended_capabilities()
|
||||||
@ -393,6 +403,56 @@ struct XHCI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool reset()
|
||||||
|
{
|
||||||
|
/* Clear run/stop bit. */
|
||||||
|
m_operational_registers.usb_command &= ~0x1u;
|
||||||
|
|
||||||
|
/* Wait for HCHalted bit to be set. */
|
||||||
|
enum halt_timeout = 40u;
|
||||||
|
for (size_t halt_timeout_counter = 0u;;)
|
||||||
|
{
|
||||||
|
Time.msleep(1u);
|
||||||
|
|
||||||
|
if ((volatileLoad(&m_operational_registers.usb_status) & 1u) != 0u)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
halt_timeout_counter++;
|
||||||
|
if (halt_timeout_counter >= halt_timeout)
|
||||||
|
{
|
||||||
|
Klog.writefln("XHCI controller failed to halt");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set HC reset bit. */
|
||||||
|
m_operational_registers.usb_command |= (1u << 1u);
|
||||||
|
|
||||||
|
/* Wait for controller to be ready. */
|
||||||
|
enum reset_timeout = 100u;
|
||||||
|
for (size_t reset_timeout_counter = 0u;;)
|
||||||
|
{
|
||||||
|
Time.msleep(1u);
|
||||||
|
|
||||||
|
if (((volatileLoad(&m_operational_registers.usb_command) & (1u << 1u)) == 0u) &&
|
||||||
|
((volatileLoad(&m_operational_registers.usb_status) & (1u << 11u)) == 0u))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_timeout_counter++;
|
||||||
|
if (reset_timeout_counter >= reset_timeout)
|
||||||
|
{
|
||||||
|
Klog.writefln("XHCI controller failed to reset");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void build(Pci.Device * pci_device)
|
static void build(Pci.Device * pci_device)
|
||||||
{
|
{
|
||||||
if (pci_device.memory_ranges[0].address != null)
|
if (pci_device.memory_ranges[0].address != null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user