Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Sun Jul 17 2022 08:25:31 by 1.7.2