blob: 83c5a7e65eec40cf077a3d76b1839c7687e768d1 [file] [log] [blame]
// Copyright 2021 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_BIN_DRIVER_MANAGER_BIND_DRIVER_MANAGER_H_
#define SRC_DEVICES_BIN_DRIVER_MANAGER_BIND_DRIVER_MANAGER_H_
#include <lib/ddk/device.h>
#include <memory>
#include "src/devices/bin/driver_manager/coordinator.h"
#include "src/devices/bin/driver_manager/driver_loader.h"
#include "src/devices/bin/driver_manager/v1/init_task.h"
#include "src/devices/bin/driver_manager/v1/resume_task.h"
#include "src/devices/bin/driver_manager/v1/suspend_task.h"
#include "src/devices/bin/driver_manager/v1/unbind_task.h"
class CompositeDevice;
// Function that is invoked to request a driver try to bind to a device
using AttemptBindFunc =
fit::function<zx_status_t(const Driver* drv, const fbl::RefPtr<Device>& dev)>;
using CompositeDeviceMap = std::unordered_map<std::string, std::unique_ptr<CompositeDevice>>;
class BindDriverManager {
public:
BindDriverManager(const BindDriverManager&) = delete;
BindDriverManager& operator=(const BindDriverManager&) = delete;
BindDriverManager(BindDriverManager&&) = delete;
BindDriverManager& operator=(BindDriverManager&&) = delete;
BindDriverManager(Coordinator* coordinator, AttemptBindFunc attempt_bind);
~BindDriverManager();
// Returns ZX_OK if |device| and |driver| are a match for binding.
zx_status_t MatchDevice(const fbl::RefPtr<Device>& dev, const Driver* driver,
bool autobind) const;
zx_status_t BindDriverToDevice(const MatchedDriver& driver, const fbl::RefPtr<Device>& dev);
// Try binding a driver to the device. Returns ZX_ERR_ALREADY_BOUND if there
// is a driver bound to the device and the device is not allowed to be bound multiple times.
zx_status_t BindDevice(const fbl::RefPtr<Device>& dev, std::string_view drvlibname,
bool new_device);
// Attempts to bind the given driver to the given device. Returns ZX_OK on
// success, ZX_ERR_ALREADY_BOUND if there is a driver bound to the device
// and the device is not allowed to be bound multiple times, ZX_ERR_NEXT if
// the driver is not capable of binding to the device, and a different error
// if the driver was capable of binding but failed to bind.
zx_status_t MatchAndBind(const fbl::RefPtr<Device>& dev, const Driver* driver, bool autobind);
// Given a device, return all of the Drivers whose bind programs match with the device.
// The returned vector is organized by priority, so if only one driver is being bound it
// should be the first in the vector.
// If |drvlibname| is not empty then the device will only be checked against the driver
// with that specific name.
zx::status<std::vector<MatchedDriver>> GetMatchingDrivers(const fbl::RefPtr<Device>& dev,
std::string_view drvlibname);
// Binds all the devices to the drivers in the Driver Index.
void BindAllDevicesDriverIndex(const DriverLoader::MatchDeviceConfig& config);
zx_status_t AddDeviceGroup(std::string_view topological_path, std::string_view group_name,
fuchsia_device_manager::wire::DeviceGroupDescriptor group_desc);
// Public for testing only.
void set_attempt_bind(AttemptBindFunc attempt_bind) { attempt_bind_ = std::move(attempt_bind); }
// Only exposed for testing.
const std::unordered_map<std::string, std::unique_ptr<CompositeDevice>>& device_groups() const {
return device_groups_;
}
private:
// Find and return matching drivers for |dev| in the Driver Index.
zx::status<std::vector<MatchedDriver>> MatchDeviceWithDriverIndex(
const fbl::RefPtr<Device>& dev, const DriverLoader::MatchDeviceConfig& config) const;
// Find matching drivers for |dev| through the Driver Index and then bind them.
zx_status_t MatchAndBindWithDriverIndex(const fbl::RefPtr<Device>& dev,
const DriverLoader::MatchDeviceConfig& config);
zx_status_t MatchAndBindDeviceGroup(const fbl::RefPtr<Device>& dev,
std::string_view topological_path);
// Binds the matched fragment in |driver| to |dev|. If a CompositeDevice for |driver| doesn't
// exists in |driver_index_composite_devices_|, this function creates and adds it.
zx_status_t BindDriverToFragment(const MatchedCompositeDriverInfo& driver,
const fbl::RefPtr<Device>& dev);
zx_status_t BindDriverToDeviceGroup(const MatchedDeviceGroupInfo& device_group,
const fbl::RefPtr<Device>& dev);
// Owner. Must outlive BindDriverManager.
Coordinator* coordinator_;
// Callback function. Used to attempt binding a driver to a device.
// TODO(fxb/90932): Remove this callback.
AttemptBindFunc attempt_bind_;
// All the composite devices received from the DriverIndex.
// This maps driver URLs to the CompositeDevice object.
CompositeDeviceMap driver_index_composite_devices_;
// All the composite devices for device groups received from the DriverIndex.
// This maps topological paths to the CompositeDevice object.
CompositeDeviceMap device_groups_;
};
#endif // SRC_DEVICES_BIN_DRIVER_MANAGER_BIND_DRIVER_MANAGER_H_