blob: 4d0c84d1a66ba24d8af8e0c5e5d18b580585fcaf [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVICES_USB_DRIVERS_XHCI_REWRITE_XHCI_INTERRUPTER_H_
#define SRC_DEVICES_USB_DRIVERS_XHCI_REWRITE_XHCI_INTERRUPTER_H_
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/executor.h>
#include <lib/zx/interrupt.h>
#include <thread>
#include "xhci-event-ring.h"
namespace usb_xhci {
// An interrupter that manages an event ring, and handles interrupts.
class Interrupter {
public:
Interrupter() = default;
~Interrupter() {
if (thread_.joinable()) {
thread_.join();
}
}
zx_status_t Start(uint32_t interrupter, const RuntimeRegisterOffset& offset,
ddk::MmioView interrupter_regs, UsbXhci* hci);
void Stop() {
if (async_executor_.has_value()) {
async_executor_.value().schedule_task(fit::make_ok_promise().then(
[=](fit::result<void, void>& result) { async_loop_->Quit(); }));
}
}
EventRing& ring() { return event_ring_; }
// Returns a pointer to the IRQ
// owned by this interrupter
zx::interrupt& GetIrq() { return irq_; }
TRBPromise Timeout(zx::time deadline);
private:
uint32_t interrupter_;
zx_status_t IrqThread();
zx::interrupt irq_;
std::thread thread_;
EventRing event_ring_;
std::optional<async::Executor> async_executor_;
std::optional<async::Loop> async_loop_;
// Reference to the xHCI core. Since Interrupter is a part of the
// UsbXhci (always instantiated as a class member), this reference
// will always be valid for the lifetime of the Interrupter.
UsbXhci* hci_ = nullptr;
};
} // namespace usb_xhci
#endif // SRC_DEVICES_USB_DRIVERS_XHCI_REWRITE_XHCI_INTERRUPTER_H_