// 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.

#![allow(non_upper_case_globals)]

use fuchsia_zircon as zx;
use fuchsia_zircon::HandleBased;
use magma::*;
use std::collections::HashMap;
use std::sync::Arc;

use super::ffi::*;
use super::magma::*;
use crate::device::wayland::image_file::*;
use crate::fs::*;
use crate::lock::Mutex;
use crate::logging::impossible_error;
use crate::syscalls::*;
use crate::task::CurrentTask;
use crate::types::*;

#[derive(Clone)]
pub enum BufferInfo {
    Default,
    Image(ImageInfo),
}

/// A `MagmaConnection` is an internal representation of a `magma_connection_t`.
type MagmaConnection = u64;

/// A `BufferMap` stores all the magma buffers for a given connection.
type BufferMap = HashMap<magma_buffer_t, BufferInfo>;

/// A `ConnectionMap` stores the `BufferMap`s associated with each magma connection.
type ConnectionMap = HashMap<MagmaConnection, BufferMap>;
pub struct MagmaFile {
    // TODO(fxbug.dev/12731): The lifecycle of the device channels should be handled by magma.
    devices: Arc<Mutex<Vec<zx::Channel>>>,
    connections: Arc<Mutex<ConnectionMap>>,
}

impl MagmaFile {
    pub fn new() -> Result<Box<dyn FileOps>, Errno> {
        Ok(Box::new(Self {
            devices: Arc::new(Mutex::new(vec![])),
            connections: Arc::new(Mutex::new(HashMap::new())),
        }))
    }

    /// Returns a duplicate of the VMO associated with the file at `fd`, as well as a `BufferInfo`
    /// of the correct type for that file.
    ///
    /// Returns an error if the file does not contain a buffer.
    fn get_vmo_and_magma_buffer(
        current_task: &CurrentTask,
        fd: FdNumber,
    ) -> Result<(zx::Vmo, BufferInfo), Errno> {
        let file = current_task.files.get(fd)?;
        if let Some(file) = file.downcast_file::<ImageFile>() {
            let buffer = BufferInfo::Image(file.info.clone());
            Ok((
                file.vmo.duplicate_handle(zx::Rights::SAME_RIGHTS).map_err(impossible_error)?,
                buffer,
            ))
        } else if let Some(file) = file.downcast_file::<VmoFileObject>() {
            let buffer = BufferInfo::Default;
            Ok((
                file.vmo.duplicate_handle(zx::Rights::SAME_RIGHTS).map_err(impossible_error)?,
                buffer,
            ))
        } else {
            error!(EINVAL)
        }
    }

    /// Adds a `BufferInfo` for the given `magma_buffer_t`, associated with the specified
    /// connection.
    fn add_buffer_info(
        &self,
        connection: magma_connection_t,
        buffer: magma_buffer_t,
        buffer_info: BufferInfo,
    ) {
        self.connections
            .lock()
            .entry(connection as u64)
            .or_insert_with(HashMap::new)
            .insert(buffer, buffer_info);
    }

    /// Returns a `BufferInfo` for the given `magma_buffer_t`, if one exists for the given
    /// `connection`. Otherwise returns `None`.
    fn get_buffer_info(
        &self,
        connection: magma_connection_t,
        buffer: magma_buffer_t,
    ) -> Option<BufferInfo> {
        match self.connections.lock().get(&(connection as u64)) {
            Some(buffers) => buffers.get(&buffer).map(|buffer| buffer.clone()),
            _ => None,
        }
    }
}

impl FileOps for MagmaFile {
    fileops_impl_nonseekable!();
    fileops_impl_nonblocking!();

    fn ioctl(
        &self,
        _file: &FileObject,
        current_task: &CurrentTask,
        _request: u32,
        user_addr: UserAddress,
    ) -> Result<SyscallResult, Errno> {
        let (command, command_type) = read_magma_command_and_type(current_task, user_addr)?;
        let response_address = UserAddress::from(command.response_address);

        match command_type {
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_DEVICE_IMPORT => {
                let (control, mut response) = read_control_and_response(current_task, &command)?;
                (*self.devices.lock()).push(device_import(control, &mut response)?);

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_DEVICE_IMPORT as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_CREATE_CONNECTION2 => {
                let (control, mut response): (
                    virtio_magma_create_connection2_ctrl,
                    virtio_magma_create_connection2_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut connection_out: magma_connection_t = 0;
                response.result_return =
                    unsafe { magma_create_connection2(control.device, &mut connection_out) as u64 };

                response.connection_out = connection_out;
                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_CREATE_CONNECTION2 as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_RELEASE_CONNECTION => {
                let (control, mut response): (
                    virtio_magma_release_connection_ctrl_t,
                    virtio_magma_release_connection_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let connection = control.connection as magma_connection_t;
                let mut connections = self.connections.lock();
                if connections.contains_key(&connection) {
                    unsafe { magma_release_connection(connection) };
                    connections.remove(&connection);
                }

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_RELEASE_CONNECTION as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_DEVICE_RELEASE => {
                let (control, mut response): (
                    virtio_magma_device_release_ctrl_t,
                    virtio_magma_device_release_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                unsafe { magma_device_release(control.device) };

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_DEVICE_RELEASE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_VIRT_CREATE_IMAGE => {
                let (control, mut response): (
                    virtio_magma_virt_create_image_ctrl_t,
                    virtio_magma_virt_create_image_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut create_info_ptr: u64 = 0;
                let create_info_address = UserAddress::from(control.create_info);
                current_task
                    .mm
                    .read_object(UserRef::new(create_info_address), &mut create_info_ptr)?;

                let mut create_info = magma_image_create_info_t::default();
                let create_info_address = UserAddress::from(create_info_ptr);
                current_task.mm.read_object(UserRef::new(create_info_address), &mut create_info)?;

                let (vmo, token, info) = create_drm_image(0, &create_info).map_err(|e| {
                    tracing::warn!("Error creating drm image: {:?}", e);
                    errno!(EINVAL)
                })?;

                let mut buffer_out = magma_buffer_t::default();
                response.result_return = unsafe {
                    magma_import(
                        control.connection as magma_connection_t,
                        vmo.into_raw(),
                        &mut buffer_out,
                    ) as u64
                };

                self.add_buffer_info(
                    control.connection as magma_connection_t,
                    buffer_out,
                    BufferInfo::Image(ImageInfo { info, token }),
                );

                response.image_out = buffer_out;
                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_VIRT_CREATE_IMAGE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_VIRT_GET_IMAGE_INFO => {
                let (control, mut response): (
                    virtio_magma_virt_get_image_info_ctrl_t,
                    virtio_magma_virt_get_image_info_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let image_info_address_ref =
                    UserRef::new(UserAddress::from(control.image_info_out));
                let mut image_info_ptr = UserAddress::default();
                current_task.mm.read_object(image_info_address_ref, &mut image_info_ptr)?;

                match self.get_buffer_info(
                    control.connection as magma_connection_t,
                    control.image as magma_buffer_t,
                ) {
                    Some(BufferInfo::Image(image_info)) => {
                        let image_info_ref = UserRef::new(image_info_ptr);
                        current_task.mm.write_object(image_info_ref, &image_info.info)?;
                        response.result_return = MAGMA_STATUS_OK as u64;
                    }
                    _ => {
                        tracing::error!("No image info was found for buffer: {:?}", {
                            control.image
                        });
                        response.result_return = MAGMA_STATUS_INVALID_ARGS as u64;
                    }
                };

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_VIRT_GET_IMAGE_INFO as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_GET_BUFFER_SIZE => {
                let (control, mut response): (
                    virtio_magma_get_buffer_size_ctrl_t,
                    virtio_magma_get_buffer_size_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                response.result_return = unsafe { magma_get_buffer_size(control.buffer) };
                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_GET_BUFFER_SIZE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_FLUSH => {
                let (control, mut response): (
                    virtio_magma_flush_ctrl_t,
                    virtio_magma_flush_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                response.result_return =
                    unsafe { magma_flush(control.connection as magma_connection_t) as u64 };

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_FLUSH as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_READ_NOTIFICATION_CHANNEL2 => {
                let (control, mut response): (
                    virtio_magma_read_notification_channel2_ctrl_t,
                    virtio_magma_read_notification_channel2_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                // Buffer has a min length of 1 to make sure the call to
                // `magma_read_notification_channel2` uses a valid reference.
                let mut buffer = vec![0; std::cmp::max(control.buffer_size as usize, 1)];
                let mut buffer_size_out = 0;
                let mut more_data_out: u8 = 0;

                response.result_return = unsafe {
                    magma_read_notification_channel2(
                        control.connection as magma_connection_t,
                        &mut buffer[0] as *mut u8 as *mut std::ffi::c_void,
                        control.buffer_size,
                        &mut buffer_size_out,
                        &mut more_data_out as *mut u8,
                    ) as u64
                };

                response.more_data_out = more_data_out as u64;
                response.buffer_size_out = buffer_size_out;
                current_task.mm.write_memory(UserAddress::from(control.buffer), &mut buffer)?;

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_READ_NOTIFICATION_CHANNEL2 as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_GET_BUFFER_HANDLE2 => {
                let (control, mut response): (
                    virtio_magma_get_buffer_handle2_ctrl_t,
                    virtio_magma_get_buffer_handle2_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut buffer_handle_out = 0;
                let status = unsafe {
                    magma_get_buffer_handle2(
                        control.buffer as magma_buffer_t,
                        &mut buffer_handle_out as *mut magma_handle_t,
                    )
                };
                if status != MAGMA_STATUS_OK as i32 {
                    response.result_return = status as u64;
                } else {
                    let vmo = unsafe { zx::Vmo::from(zx::Handle::from_raw(buffer_handle_out)) };
                    let file = Anon::new_file(
                        anon_fs(current_task.kernel()),
                        Box::new(VmoFileObject::new(Arc::new(vmo))),
                        OpenFlags::RDWR,
                    );
                    let fd = current_task.files.add_with_flags(file, FdFlags::empty())?;
                    response.handle_out = fd.raw() as u64;
                    response.result_return = MAGMA_STATUS_OK as u64;
                }

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_GET_BUFFER_HANDLE2 as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_RELEASE_BUFFER => {
                let (control, mut response): (
                    virtio_magma_release_buffer_ctrl_t,
                    virtio_magma_release_buffer_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                self.connections.lock().get_mut(&{ control.connection }).map(
                    |buffers| match buffers.remove(&(control.buffer as u64)) {
                        Some(_) => unsafe {
                            magma_release_buffer(
                                control.connection as magma_connection_t,
                                control.buffer as magma_buffer_t,
                            );
                        },
                        _ => {
                            tracing::error!("Calling magma_release_buffer with an invalid buffer.");
                        }
                    },
                );

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_RELEASE_BUFFER as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_EXPORT => {
                let (control, mut response): (
                    virtio_magma_export_ctrl_t,
                    virtio_magma_export_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut buffer_handle_out = 0;
                let status = unsafe {
                    magma_export(
                        control.connection as magma_connection_t,
                        control.buffer as magma_buffer_t,
                        &mut buffer_handle_out as *mut magma_handle_t,
                    )
                };

                if status as u32 == MAGMA_STATUS_OK {
                    let vmo = unsafe { zx::Vmo::from(zx::Handle::from_raw(buffer_handle_out)) };
                    let file = match self
                        .connections
                        .lock()
                        .get(&{ control.connection })
                        .and_then(|buffers| buffers.get(&(control.buffer as magma_buffer_t)))
                    {
                        Some(BufferInfo::Image(image_info)) => {
                            ImageFile::new(current_task.kernel(), image_info.clone(), vmo)
                        }
                        _ => Anon::new_file(
                            anon_fs(current_task.kernel()),
                            Box::new(VmoFileObject::new(Arc::new(vmo))),
                            OpenFlags::RDWR,
                        ),
                    };
                    let fd = current_task.files.add_with_flags(file, FdFlags::empty())?;
                    response.buffer_handle_out = fd.raw() as u64;
                }

                response.result_return = status as u64;
                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_EXPORT as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_IMPORT => {
                let (control, mut response): (
                    virtio_magma_import_ctrl_t,
                    virtio_magma_import_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let buffer_fd = FdNumber::from_raw(control.buffer_handle as i32);
                let (vmo, buffer) = MagmaFile::get_vmo_and_magma_buffer(current_task, buffer_fd)?;

                let mut buffer_out = magma_buffer_t::default();
                response.result_return = unsafe {
                    magma_import(
                        control.connection as magma_connection_t,
                        vmo.into_raw(),
                        &mut buffer_out,
                    ) as u64
                };

                // Store the information for the newly imported buffer.
                self.add_buffer_info(control.connection as magma_connection_t, buffer_out, buffer);
                // Import is expected to close the file that was imported.
                let _ = current_task.files.close(buffer_fd);

                response.buffer_out = buffer_out;
                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_IMPORT as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_QUERY2 => {
                let (control, mut response): (
                    virtio_magma_query2_ctrl_t,
                    virtio_magma_query2_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut value_out = 0;
                response.result_return =
                    unsafe { magma_query2(control.device, control.id, &mut value_out) as u64 };
                response.value_out = value_out;

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_QUERY2 as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_GET_NOTIFICATION_CHANNEL_HANDLE => {
                let (control, mut response): (
                    virtio_magma_get_notification_channel_handle_ctrl_t,
                    virtio_magma_get_notification_channel_handle_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                response.result_return = unsafe {
                    magma_get_notification_channel_handle(control.connection as magma_connection_t)
                };

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_GET_NOTIFICATION_CHANNEL_HANDLE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_CREATE_CONTEXT => {
                let (control, mut response): (
                    virtio_magma_create_context_ctrl_t,
                    virtio_magma_create_context_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut context_id_out = 0;
                response.result_return = unsafe {
                    magma_create_context(
                        control.connection as magma_connection_t,
                        &mut context_id_out,
                    ) as u64
                };
                response.context_id_out = context_id_out as u64;

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_CREATE_CONTEXT as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_RELEASE_CONTEXT => {
                let (control, mut response): (
                    virtio_magma_release_context_ctrl_t,
                    virtio_magma_release_context_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                unsafe {
                    magma_release_context(
                        control.connection as magma_connection_t,
                        control.context_id as u32,
                    );
                }

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_RELEASE_CONTEXT as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_CREATE_BUFFER => {
                let (control, mut response): (
                    virtio_magma_create_buffer_ctrl_t,
                    virtio_magma_create_buffer_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut size_out = 0;
                let mut buffer_out = 0;
                response.result_return = unsafe {
                    magma_create_buffer(
                        control.connection as magma_connection_t,
                        control.size,
                        &mut size_out,
                        &mut buffer_out,
                    ) as u64
                };
                response.size_out = size_out;
                response.buffer_out = buffer_out;
                self.add_buffer_info(
                    control.connection as magma_connection_t,
                    buffer_out,
                    BufferInfo::Default,
                );

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_CREATE_BUFFER as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_GET_BUFFER_ID => {
                let (control, mut response): (
                    virtio_magma_get_buffer_id_ctrl_t,
                    virtio_magma_get_buffer_id_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                response.result_return =
                    unsafe { magma_get_buffer_id(control.buffer as magma_buffer_t) };

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_GET_BUFFER_ID as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_CREATE_SEMAPHORE => {
                let (control, mut response): (
                    virtio_magma_create_semaphore_ctrl_t,
                    virtio_magma_create_semaphore_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut semaphore_out = 0;
                response.result_return = unsafe {
                    magma_create_semaphore(
                        control.connection as magma_connection_t,
                        &mut semaphore_out,
                    ) as u64
                };

                response.semaphore_out = semaphore_out;
                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_CREATE_SEMAPHORE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_QUERY_RETURNS_BUFFER2 => {
                let (control, mut response): (
                    virtio_magma_query_returns_buffer2_ctrl_t,
                    virtio_magma_query_returns_buffer2_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut handle_out = 0;
                response.result_return = unsafe {
                    magma_query_returns_buffer2(
                        control.device as magma_device_t,
                        control.id,
                        &mut handle_out,
                    ) as u64
                };
                let vmo = unsafe { zx::Vmo::from(zx::Handle::from_raw(handle_out)) };
                let file = Anon::new_file(
                    anon_fs(current_task.kernel()),
                    Box::new(VmoFileObject::new(Arc::new(vmo))),
                    OpenFlags::RDWR,
                );
                let fd = current_task.files.add_with_flags(file, FdFlags::empty())?;

                response.handle_out = fd.raw() as u64;
                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_QUERY_RETURNS_BUFFER2 as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_GET_ERROR => {
                let (control, mut response): (
                    virtio_magma_get_error_ctrl_t,
                    virtio_magma_get_error_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                response.result_return =
                    unsafe { magma_get_error(control.connection as magma_connection_t) as u64 };

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_GET_ERROR as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_IMPORT_SEMAPHORE => {
                let (control, mut response): (
                    virtio_magma_import_semaphore_ctrl_t,
                    virtio_magma_import_semaphore_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut semaphore_out = 0;
                response.result_return = unsafe {
                    magma_import_semaphore(
                        control.connection as magma_connection_t,
                        control.semaphore_handle,
                        &mut semaphore_out,
                    ) as u64
                };
                response.semaphore_out = semaphore_out;

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_IMPORT_SEMAPHORE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_GET_SEMAPHORE_ID => {
                let (control, mut response): (
                    virtio_magma_get_semaphore_id_ctrl_t,
                    virtio_magma_get_semaphore_id_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                response.result_return = unsafe {
                    magma_get_semaphore_id(control.semaphore as magma_semaphore_t) as u64
                };

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_GET_SEMAPHORE_ID as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_RELEASE_SEMAPHORE => {
                let (control, mut response): (
                    virtio_magma_release_semaphore_ctrl_t,
                    virtio_magma_release_semaphore_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                unsafe {
                    magma_release_semaphore(
                        control.connection as magma_connection_t,
                        control.semaphore as magma_semaphore_t,
                    );
                };

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_RELEASE_SEMAPHORE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_EXPORT_SEMAPHORE => {
                let (control, mut response): (
                    virtio_magma_export_semaphore_ctrl_t,
                    virtio_magma_export_semaphore_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                let mut semaphore_handle_out = 0;
                response.result_return = unsafe {
                    magma_export_semaphore(
                        control.connection as magma_connection_t,
                        control.semaphore as magma_semaphore_t,
                        &mut semaphore_handle_out,
                    ) as u64
                };
                response.semaphore_handle_out = semaphore_handle_out as u64;

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_EXPORT_SEMAPHORE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_RESET_SEMAPHORE => {
                let (control, mut response): (
                    virtio_magma_reset_semaphore_ctrl_t,
                    virtio_magma_reset_semaphore_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                unsafe {
                    magma_reset_semaphore(control.semaphore as magma_semaphore_t);
                };

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_RESET_SEMAPHORE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_SIGNAL_SEMAPHORE => {
                let (control, mut response): (
                    virtio_magma_signal_semaphore_ctrl_t,
                    virtio_magma_signal_semaphore_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                unsafe {
                    magma_signal_semaphore(control.semaphore as magma_semaphore_t);
                };

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_SIGNAL_SEMAPHORE as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_MAP_BUFFER_GPU => {
                let (control, mut response): (
                    virtio_magma_map_buffer_gpu_ctrl_t,
                    virtio_magma_map_buffer_gpu_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                response.result_return = unsafe {
                    magma_map_buffer_gpu(
                        control.connection as magma_connection_t,
                        control.buffer,
                        control.page_offset,
                        control.page_count,
                        control.gpu_va,
                        control.map_flags,
                    ) as u64
                };

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_MAP_BUFFER_GPU as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_POLL => {
                let (control, mut response): (virtio_magma_poll_ctrl_t, virtio_magma_poll_resp_t) =
                    read_control_and_response(current_task, &command)?;

                let num_items = control.count as usize / std::mem::size_of::<StarnixPollItem>();
                let items_ref = UserRef::new(UserAddress::from(control.items));
                // Read the poll items as `StarnixPollItem`, since they contain a union. Also note
                // that the minimum length of the vector is 1, to always have a valid reference for
                // `magma_poll`.
                let mut starnix_items =
                    vec![StarnixPollItem::default(); std::cmp::max(num_items, 1)];
                current_task.mm.read_objects(items_ref, &mut starnix_items)?;
                // Then convert each item "manually" into `magma_poll_item_t`.
                let mut magma_items: Vec<magma_poll_item_t> =
                    starnix_items.iter().map(|item| item.into_poll_item()).collect();

                response.result_return = unsafe {
                    magma_poll(
                        &mut magma_items[0] as *mut magma_poll_item,
                        num_items as u32,
                        control.timeout_ns,
                    ) as u64
                };

                // Convert the poll items back to a serializable version after the `magma_poll`
                // call.
                let starnix_items: Vec<StarnixPollItem> =
                    magma_items.iter().map(StarnixPollItem::new).collect();
                current_task.mm.write_objects(items_ref, &starnix_items)?;

                response.hdr.type_ = virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_POLL as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            virtio_magma_ctrl_type_VIRTIO_MAGMA_CMD_EXECUTE_COMMAND_BUFFER_WITH_RESOURCES2 => {
                let (control, mut response): (
                    virtio_magma_execute_command_buffer_with_resources2_ctrl_t,
                    virtio_magma_execute_command_buffer_with_resources2_resp_t,
                ) = read_control_and_response(current_task, &command)?;

                // First read the `virtmagma_command_buffer`, this contains pointers to all the
                // remaining structures needed by `magma_execute_command_buffer_with_resources2`.
                let virt_command_buffer_ref =
                    UserRef::new(UserAddress::from(control.command_buffer as u64));
                let mut virt_command_buffer = virtmagma_command_buffer::default();
                current_task.mm.read_object(virt_command_buffer_ref, &mut virt_command_buffer)?;

                let command_buffer_ref = UserRef::<magma_command_buffer>::new(UserAddress::from(
                    virt_command_buffer.command_buffer,
                ));
                let mut command_buffer = magma_command_buffer::default();
                current_task.mm.read_object(command_buffer_ref, &mut command_buffer)?;

                let resources_ref = UserRef::<magma_exec_resource>::new(UserAddress::from(
                    virt_command_buffer.resources as u64,
                ));
                let mut resources = vec![
                    magma_exec_resource::default();
                    std::cmp::max(1, command_buffer.resource_count as usize)
                ];
                // The resources vector is of length >= 1, since we need a valid reference to pass
                // to the magma function even when there is no data. This check is here to prevent
                // us from reading objects when the length is really 0.
                if command_buffer.resource_count > 0 {
                    current_task.mm.read_objects(resources_ref, &mut resources)?;
                }

                let semaphore_ids_ref =
                    UserRef::<u64>::new(UserAddress::from(virt_command_buffer.semaphores as u64));
                let semaphore_count = (command_buffer.wait_semaphore_count
                    + command_buffer.signal_semaphore_count)
                    as usize;
                let mut semaphore_ids = vec![0; std::cmp::max(1, semaphore_count)];
                // This check exists for the same reason as the command_buffer.resource_count check
                // above (to avoid reading when the actual count is 0).
                if semaphore_count > 0 {
                    current_task.mm.read_objects(semaphore_ids_ref, &mut semaphore_ids)?;
                }
                response.result_return = unsafe {
                    magma_execute_command_buffer_with_resources2(
                        control.connection as magma_connection_t,
                        control.context_id,
                        &mut command_buffer,
                        &mut resources[0] as *mut magma_exec_resource,
                        &mut semaphore_ids[0] as *mut u64,
                    ) as u64
                };

                response.hdr.type_ =
                    virtio_magma_ctrl_type_VIRTIO_MAGMA_RESP_EXECUTE_COMMAND_BUFFER_WITH_RESOURCES2
                        as u32;
                current_task.mm.write_object(UserRef::new(response_address), &response)
            }
            t => {
                tracing::warn!("Got unknown request: {:?}", t);
                error!(ENOSYS)
            }
        }?;

        Ok(SUCCESS)
    }

    fn read(
        &self,
        _file: &FileObject,
        _current_task: &CurrentTask,
        _data: &[UserBuffer],
    ) -> Result<usize, Errno> {
        error!(EINVAL)
    }

    fn write(
        &self,
        _file: &FileObject,
        _current_task: &CurrentTask,
        _data: &[UserBuffer],
    ) -> Result<usize, Errno> {
        error!(EINVAL)
    }
}
