Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers storage_volume.cpp Source File

storage_volume.cpp

00001 /*
00002  * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 // This file is deprecated so deprecation warnings when building it are silenced
00019 #if   defined ( __CC_ARM )
00020 #pragma diag_suppress 1361  // Deprecated declaration
00021 #elif defined ( __GNUC__ )
00022 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
00023 #endif
00024 
00025 #include "storage-volume-manager/storage_volume_manager.h"
00026 #include <string.h>
00027 #include <inttypes.h>
00028 
00029 /* redefine tr_debug() to a printf() equivalent to emit trace */
00030 #define tr_debug(...)
00031 
00032 
00033 void StorageVolume::setup(uint64_t _addr, uint64_t _size, StorageVolumeManager *_volumeManager)
00034 {
00035     volumeOffset  = _addr;
00036     volumeSize    = _size;
00037     volumeManager = _volumeManager;
00038     allocated     = true;
00039 }
00040 
00041 ARM_DRIVER_VERSION StorageVolume::GetVersion(void)
00042 {
00043     ARM_DRIVER_VERSION bad_ver = {0, 0};
00044 
00045     if (!allocated) {
00046         return bad_ver;
00047     }
00048     return volumeManager->getStorage()->GetVersion();
00049 }
00050 
00051 ARM_STORAGE_CAPABILITIES StorageVolume::GetCapabilities(void)
00052 {
00053     ARM_STORAGE_CAPABILITIES bad_cap;
00054 
00055     if (!allocated) {
00056         memset(&bad_cap, 0, sizeof(ARM_STORAGE_CAPABILITIES));
00057         return bad_cap;
00058     }
00059     return volumeManager->getStorage()->GetCapabilities();
00060 }
00061 
00062 int32_t StorageVolume::Initialize(ARM_Storage_Callback_t _callback)
00063 {
00064     if (!allocated) {
00065         return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED;
00066     }
00067 
00068     callback = _callback; /* nothing else to do since we've already initialized the storage */
00069     return 1; /* synchronous completion. */
00070 }
00071 
00072 int32_t StorageVolume::Uninitialize(void)
00073 {
00074     if (!allocated) {
00075         return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED;
00076     }
00077 
00078     return 1; /* synchronous completion. */
00079 }
00080 
00081 int32_t StorageVolume::PowerControl(ARM_POWER_STATE state)
00082 {
00083     tr_debug("called powerControl(%u)", state);
00084     if (!allocated) {
00085         return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED;
00086     }
00087     if (volumeManager->activeVolume != NULL) {
00088         return ARM_DRIVER_ERROR_BUSY;
00089     }
00090 
00091     volumeManager->activeVolume = this;
00092     int32_t rc = volumeManager->getStorage()->PowerControl(state);
00093     if (rc != ARM_DRIVER_OK) {
00094         volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */
00095     }
00096     return rc;
00097 }
00098 
00099 int32_t StorageVolume::ReadData(uint64_t addr, void *data, uint32_t size)
00100 {
00101     tr_debug("called ReadData(%" PRIu32 ", %" PRIu32 ")", (uint32_t)addr, size);
00102     if (!allocated) {
00103         return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED;
00104     }
00105     if (volumeManager->activeVolume != NULL) {
00106         return ARM_DRIVER_ERROR_BUSY;
00107     }
00108     if ((size > volumeSize) || ((addr + size) > volumeSize)) {
00109         return ARM_DRIVER_ERROR_PARAMETER;
00110     }
00111 
00112     volumeManager->activeVolume = this;
00113     int32_t rc = volumeManager->getStorage()->ReadData(volumeOffset + addr, data, size);
00114     if (rc != ARM_DRIVER_OK) {
00115         volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */
00116     }
00117     return rc;
00118 }
00119 
00120 int32_t StorageVolume::ProgramData(uint64_t addr, const void *data, uint32_t size)
00121 {
00122     tr_debug("called ProgramData(%" PRIu32 ", %" PRIu32 ")", (uint32_t)addr, size);
00123     if (!allocated) {
00124         return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED;
00125     }
00126     if (volumeManager->activeVolume != NULL) {
00127         return ARM_DRIVER_ERROR_BUSY;
00128     }
00129     if ((size > volumeSize) || ((addr + size) > volumeSize)) {
00130         return ARM_DRIVER_ERROR_PARAMETER;
00131     }
00132 
00133     volumeManager->activeVolume = this;
00134     int32_t rc = volumeManager->getStorage()->ProgramData(volumeOffset + addr, data, size);
00135     if (rc != ARM_DRIVER_OK) {
00136         volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */
00137     }
00138     return rc;
00139 }
00140 
00141 int32_t StorageVolume::Erase(uint64_t addr, uint32_t size)
00142 {
00143     tr_debug("called erase(%" PRIu32 ", %" PRIu32 ")", (uint32_t)addr, size);
00144     if (!allocated) {
00145         return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED;
00146     }
00147     if (volumeManager->activeVolume != NULL) {
00148         return ARM_DRIVER_ERROR_BUSY;
00149     }
00150     if ((size > volumeSize) || ((addr + size) > volumeSize)) {
00151         return ARM_DRIVER_ERROR_PARAMETER;
00152     }
00153 
00154     volumeManager->activeVolume = this;
00155     int32_t rc = volumeManager->getStorage()->Erase(volumeOffset + addr, size);
00156     if (rc != ARM_DRIVER_OK) {
00157         volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */
00158     }
00159     return rc;
00160 }
00161 
00162 int32_t StorageVolume::EraseAll(void)
00163 {
00164     tr_debug("called eraseAll");
00165     if (!allocated) {
00166         return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED;
00167     }
00168     if (volumeManager->activeVolume != NULL) {
00169         return ARM_DRIVER_ERROR_BUSY;
00170     }
00171 
00172     int32_t rc;
00173 
00174     /* Allow EraseAll() only if the volume spans the entire storage. */
00175     {
00176         ARM_STORAGE_INFO info;
00177         rc = volumeManager->getStorage()->GetInfo(&info);
00178         if (rc != ARM_DRIVER_OK) {
00179             return ARM_DRIVER_ERROR;
00180         }
00181 
00182         if ((volumeOffset != 0) || (volumeSize != info.total_storage)) {
00183             return ARM_DRIVER_ERROR_UNSUPPORTED;
00184         }
00185     }
00186 
00187     volumeManager->activeVolume = this;
00188     rc = volumeManager->getStorage()->EraseAll();
00189     if (rc != ARM_DRIVER_OK) {
00190         volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */
00191     }
00192     return rc;
00193 }
00194 
00195 ARM_STORAGE_STATUS StorageVolume::GetStatus(void)
00196 {
00197     const uint32_t busy = ((volumeManager->activeVolume != NULL) ? (uint32_t)1 : (uint32_t)0);
00198     ARM_STORAGE_STATUS status = {0, 0};
00199     status.busy = busy;
00200     return status;
00201 }
00202 
00203 int32_t StorageVolume::GetInfo(ARM_STORAGE_INFO *infoP)
00204 {
00205     int32_t rc;
00206     rc = volumeManager->getStorage()->GetInfo(infoP);
00207     if (rc != ARM_DRIVER_OK) {
00208         return ARM_DRIVER_ERROR;
00209     }
00210 
00211     infoP->total_storage = volumeSize;
00212     return ARM_DRIVER_OK;
00213 }
00214 
00215 uint32_t StorageVolume::ResolveAddress(uint64_t addr) {
00216     return (uint32_t)(volumeOffset + addr);
00217 }
00218 
00219 int32_t StorageVolume::GetNextBlock(const ARM_STORAGE_BLOCK* prevP, ARM_STORAGE_BLOCK *nextP)
00220 {
00221     int32_t rc;
00222     ARM_STORAGE_BLOCK tmpBlock;
00223     do {
00224         /* iterate forward */
00225         rc = volumeManager->getStorage()->GetNextBlock(prevP, &tmpBlock);
00226         if (rc != ARM_DRIVER_OK) {
00227             return rc;
00228         }
00229 
00230         /* Stop iteration if we have progressed past the boundary of this volume. */
00231         if (tmpBlock.addr >= (volumeOffset + volumeSize)) {
00232             return ARM_DRIVER_ERROR;
00233         }
00234     } while (!this->overlapsWithBlock(&tmpBlock));
00235 
00236     if (nextP) {
00237         memcpy(nextP, &tmpBlock, sizeof(ARM_STORAGE_BLOCK));
00238         transformBlockToVolume(nextP);
00239     }
00240     return ARM_DRIVER_OK;
00241 }
00242 
00243 int32_t StorageVolume::GetBlock(uint64_t addr, ARM_STORAGE_BLOCK *blockP)
00244 {
00245     ARM_STORAGE_BLOCK tmpBlock;
00246     int32_t rc = volumeManager->getStorage()->GetBlock(ResolveAddress(addr), &tmpBlock);
00247     if (rc != ARM_DRIVER_OK) {
00248         return rc;
00249     }
00250     if (!this->overlapsWithBlock(&tmpBlock)) {
00251         return ARM_DRIVER_ERROR;
00252     }
00253 
00254     if (blockP) {
00255         memcpy(blockP, &tmpBlock, sizeof(ARM_STORAGE_BLOCK));
00256         transformBlockToVolume(blockP);
00257     }
00258     return ARM_DRIVER_OK;
00259 }