Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
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 Fri Jul 22 2022 04:54:01 by
