// SPDX-License-Identifier: MPL-2.0
//
// Do NOT modify or remove this copyright and license
//
// Copyright (c) 2012-2026 Seagate Technology LLC and/or its Affiliates, All Rights Reserved
//
// This software is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// ******************************************************************************************
//
// \file host_erase.h
// \brief This file defines the function for performing a host based erase functions (host issues a series of write
// commands)

#pragma once

#include "operations_Common.h"

#if defined(__cplusplus)
extern "C"
{
#endif

    //-----------------------------------------------------------------------------
    //
    //  is_Trim_Or_Unmap_Supported( tDevice* M_NONNULL device )
    //
    //! \brief   Get whether a device supports TRIM (ATA) or UNMAP (SCSI) commands. Can also tell you how many
    //! descriptors can be specified in the command.
    //
    //  Entry:
    //!   \param device - file descriptor
    //!   \param maxTrimOrUnmapBlockDescriptors - pointer to a uint16_t to hold the number of decriptors that can be
    //!   sent. This can be M_NULLPTR. On ATA, this will be a value divisible by 64 since 64 descriptors can be placed
    //!   inside each TRIM command. \param maxLBACount - this is only for SAS since SAS can specify the maximum number
    //!   of LBA's to unmap in a single command. If maxTrimOrUnmapBlockDescriptors is non-M_NULLPTR, this MUST be
    //!   non-M_NULLPTR as well or neither value will be filled in
    //!
    //  Exit:
    //!   \return SUCCESS = good, !SUCCESS something went wrong see error codes
    //
    //-----------------------------------------------------------------------------
    M_PARAM_RO(1)
    M_PARAM_WO(2)
    M_PARAM_WO(3)
    OPENSEA_OPERATIONS_API bool is_Trim_Or_Unmap_Supported(const tDevice* M_NONNULL device,
                                                           uint32_t* M_NONNULL      maxTrimOrUnmapBlockDescriptors,
                                                           uint32_t* M_NONNULL      maxLBACount);

    //-----------------------------------------------------------------------------
    //
    //  trim_unmap_range( tDevice* M_NONNULL device )
    //
    //! \brief   TRIM or UNMAP a range of LBAs from a starting LBA until the end of the range. This will auto detect ATA
    //! vs SCSI to send the appropriate command
    //
    //  Entry:
    //!   \param device - file descriptor
    //!   \param startLBA - the LBA to start the unmap/trim at
    //!   \param range - the range of LBAs to trim/unmap from the starting LBA
    //!
    //  Exit:
    //!   \return SUCCESS = good, !SUCCESS something went wrong see error codes
    //
    //-----------------------------------------------------------------------------
    M_PARAM_RO(1)
    OPENSEA_OPERATIONS_API eReturnValues trim_Unmap_Range(const tDevice* M_NONNULL device,
                                                          uint64_t                 startLBA,
                                                          uint64_t                 range);

    //-----------------------------------------------------------------------------
    //
    //  scsi_Unmap_Range( tDevice* M_NONNULL device )
    //
    //! \brief   UNMAP a range of LBAs from a starting LBA until the end of the range. This will send the SCSI unmap
    //! command, possibly multiple times depending on the range. A SAT driver or interface may translate this to an ATA
    //! TRIM command, but that is beyond this library
    //
    //  Entry:
    //!   \param device - file descriptor
    //!   \param startLBA - the LBA to start the unmap/trim at
    //!   \param range - the range of LBAs to trim/unmap from the starting LBA
    //!
    //  Exit:
    //!   \return SUCCESS = good, !SUCCESS something went wrong see error codes
    //
    //-----------------------------------------------------------------------------
    M_PARAM_RO(1)
    OPENSEA_OPERATIONS_API eReturnValues scsi_Unmap_Range(const tDevice* M_NONNULL device,
                                                          uint64_t                 startLBA,
                                                          uint64_t                 range);

    //-----------------------------------------------------------------------------
    //
    //  ata_Trim_Range( tDevice* M_NONNULL device )
    //
    //! \brief   TRIM a range of LBAs from a starting LBA until the end of the range. This will send the ATA data set
    //! management command with the TRIM bit set, possibly multiple times depending on the range.
    //
    //  Entry:
    //!   \param device - file descriptor
    //!   \param startLBA - the LBA to start the unmap/trim at
    //!   \param range - the range of LBAs to trim/unmap from the starting LBA
    //!
    //  Exit:
    //!   \return SUCCESS = good, !SUCCESS something went wrong see error codes
    //
    //-----------------------------------------------------------------------------
    M_PARAM_RO(1)
    OPENSEA_OPERATIONS_API eReturnValues ata_Trim_Range(const tDevice* M_NONNULL device,
                                                        uint64_t                 startLBA,
                                                        uint64_t                 range);

    //-----------------------------------------------------------------------------
    //
    //  nvme_Deallocate_Range( tDevice* M_NONNULL device )
    //
    //! \brief   Deallocate a range of LBAs from a starting LBA until the end of the range. This will send the NVMe data
    //! set management command with the deallocate bit set. Currently, this will only issue a single command. NOTE:
    //! Lower level OS's might have limitations on this command.
    //
    //  Entry:
    //!   \param device - file descriptor
    //!   \param startLBA - the LBA to start the unmap/trim at
    //!   \param range - the range of LBAs to trim/unmap from the starting LBA
    //!
    //  Exit:
    //!   \return SUCCESS = good, !SUCCESS something went wrong see error codes
    //
    //-----------------------------------------------------------------------------
    M_PARAM_RO(1)
    OPENSEA_OPERATIONS_API eReturnValues nvme_Deallocate_Range(const tDevice* M_NONNULL device,
                                                               uint64_t                 startLBA,
                                                               uint64_t                 range);

#if defined(__cplusplus)
}
#endif
