blob: bf130c31ade2f699ae3357bc83f9814b2f553be3 [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.
#include <fidl/fuchsia.device/cpp/wire.h>
#include <fidl/fuchsia.hardware.nand/cpp/wire.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/unsafe.h>
#include <lib/fdio/watcher.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <zircon/types.h>
#include <utility>
#include <fbl/string_buffer.h>
#include <fbl/unique_fd.h>
#include <ramdevice-client-test/ramnandctl.h>
namespace ramdevice_client_test {
__EXPORT
zx_status_t RamNandCtl::Create(std::unique_ptr<RamNandCtl>* out) {
driver_integration_test::IsolatedDevmgr::Args args;
args.disable_block_watcher = true;
// TODO(surajmalhotra): Remove creation of isolated devmgr from this lib so that caller can choose
// their creation parameters.
args.board_name = "astro";
driver_integration_test::IsolatedDevmgr devmgr;
if (zx_status_t status = driver_integration_test::IsolatedDevmgr::Create(&args, &devmgr);
status != ZX_OK) {
fprintf(stderr, "Could not create ram_nand_ctl device: %s\n", zx_status_get_string(status));
return status;
}
zx::result channel = device_watcher::RecursiveWaitForFile(devmgr.devfs_root().get(),
"sys/platform/00:00:2e/nand-ctl");
if (channel.is_error()) {
fprintf(stderr, "ram_nand_ctl device failed enumerated: %s\n", channel.status_string());
return channel.status_value();
}
fidl::ClientEnd<fuchsia_hardware_nand::RamNandCtl> client_end(std::move(channel.value()));
*out = std::unique_ptr<RamNandCtl>(new RamNandCtl(std::move(devmgr), std::move(client_end)));
return ZX_OK;
}
__EXPORT
zx_status_t RamNandCtl::CreateRamNand(fuchsia_hardware_nand::wire::RamNandInfo config,
std::optional<ramdevice_client::RamNand>* out) const {
const fidl::WireResult result = fidl::WireCall(ctl())->CreateDevice(std::move(config));
if (!result.ok()) {
fprintf(stderr, "Could not create ram_nand device: %s\n", result.status_string());
return result.status();
}
const fidl::WireResponse response = result.value();
if (zx_status_t status = response.status; status != ZX_OK) {
fprintf(stderr, "Could not create ram_nand device: %s\n", zx_status_get_string(status));
return status;
}
fbl::String path = fbl::String::Concat({
"sys/platform/00:00:2e/nand-ctl/",
response.name.get(),
});
fprintf(stderr, "Trying to open (%s)\n", path.c_str());
std::string controller_path = std::string(path.c_str()) + "/device_controller";
zx::result channel =
device_watcher::RecursiveWaitForFile(devfs_root().get(), controller_path.c_str());
if (channel.is_error()) {
fprintf(stderr, "Could not open ram_nand device (%s): %s\n", path.c_str(),
channel.status_string());
return channel.status_value();
}
fidl::ClientEnd<fuchsia_device::Controller> client_end(std::move(channel.value()));
*out = ramdevice_client::RamNand(std::move(client_end));
return ZX_OK;
}
__EXPORT
zx_status_t RamNandCtl::CreateWithRamNand(fuchsia_hardware_nand::wire::RamNandInfo config,
std::optional<ramdevice_client::RamNand>* out) {
std::unique_ptr<RamNandCtl> ctl;
if (zx_status_t status = RamNandCtl::Create(&ctl); status != ZX_OK) {
return status;
}
return ctl->CreateRamNand(std::move(config), out);
}
} // namespace ramdevice_client_test