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.
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 #include "storage-volume-manager/storage_volume_manager.h" 00019 #include <string.h> 00020 #include <inttypes.h> 00021 00022 /* redefine tr_debug() to a printf() equivalent to emit trace */ 00023 #define tr_debug(...) 00024 00025 00026 void StorageVolume::setup(uint64_t _addr, uint64_t _size, StorageVolumeManager *_volumeManager) 00027 { 00028 volumeOffset = _addr; 00029 volumeSize = _size; 00030 volumeManager = _volumeManager; 00031 allocated = true; 00032 } 00033 00034 ARM_DRIVER_VERSION StorageVolume::GetVersion(void) 00035 { 00036 ARM_DRIVER_VERSION bad_ver = {0, 0}; 00037 00038 if (!allocated) { 00039 return bad_ver; 00040 } 00041 return volumeManager->getStorage()->GetVersion(); 00042 } 00043 00044 ARM_STORAGE_CAPABILITIES StorageVolume::GetCapabilities(void) 00045 { 00046 ARM_STORAGE_CAPABILITIES bad_cap; 00047 00048 if (!allocated) { 00049 memset(&bad_cap, 0, sizeof(ARM_STORAGE_CAPABILITIES)); 00050 return bad_cap; 00051 } 00052 return volumeManager->getStorage()->GetCapabilities(); 00053 } 00054 00055 int32_t StorageVolume::Initialize(ARM_Storage_Callback_t _callback) 00056 { 00057 if (!allocated) { 00058 return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED; 00059 } 00060 00061 callback = _callback; /* nothing else to do since we've already initialized the storage */ 00062 return 1; /* synchronous completion. */ 00063 } 00064 00065 int32_t StorageVolume::Uninitialize(void) 00066 { 00067 if (!allocated) { 00068 return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED; 00069 } 00070 00071 return 1; /* synchronous completion. */ 00072 } 00073 00074 int32_t StorageVolume::PowerControl(ARM_POWER_STATE state) 00075 { 00076 tr_debug("called powerControl(%u)", state); 00077 if (!allocated) { 00078 return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED; 00079 } 00080 if (volumeManager->activeVolume != NULL) { 00081 return ARM_DRIVER_ERROR_BUSY; 00082 } 00083 00084 volumeManager->activeVolume = this; 00085 int32_t rc = volumeManager->getStorage()->PowerControl(state); 00086 if (rc != ARM_DRIVER_OK) { 00087 volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */ 00088 } 00089 return rc; 00090 } 00091 00092 int32_t StorageVolume::ReadData(uint64_t addr, void *data, uint32_t size) 00093 { 00094 tr_debug("called ReadData(%" PRIu32 ", %" PRIu32 ")", (uint32_t)addr, size); 00095 if (!allocated) { 00096 return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED; 00097 } 00098 if (volumeManager->activeVolume != NULL) { 00099 return ARM_DRIVER_ERROR_BUSY; 00100 } 00101 if ((size > volumeSize) || ((addr + size) > volumeSize)) { 00102 return ARM_DRIVER_ERROR_PARAMETER; 00103 } 00104 00105 volumeManager->activeVolume = this; 00106 int32_t rc = volumeManager->getStorage()->ReadData(volumeOffset + addr, data, size); 00107 if (rc != ARM_DRIVER_OK) { 00108 volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */ 00109 } 00110 return rc; 00111 } 00112 00113 int32_t StorageVolume::ProgramData(uint64_t addr, const void *data, uint32_t size) 00114 { 00115 tr_debug("called ProgramData(%" PRIu32 ", %" PRIu32 ")", (uint32_t)addr, size); 00116 if (!allocated) { 00117 return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED; 00118 } 00119 if (volumeManager->activeVolume != NULL) { 00120 return ARM_DRIVER_ERROR_BUSY; 00121 } 00122 if ((size > volumeSize) || ((addr + size) > volumeSize)) { 00123 return ARM_DRIVER_ERROR_PARAMETER; 00124 } 00125 00126 volumeManager->activeVolume = this; 00127 int32_t rc = volumeManager->getStorage()->ProgramData(volumeOffset + addr, data, size); 00128 if (rc != ARM_DRIVER_OK) { 00129 volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */ 00130 } 00131 return rc; 00132 } 00133 00134 int32_t StorageVolume::Erase(uint64_t addr, uint32_t size) 00135 { 00136 tr_debug("called erase(%" PRIu32 ", %" PRIu32 ")", (uint32_t)addr, size); 00137 if (!allocated) { 00138 return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED; 00139 } 00140 if (volumeManager->activeVolume != NULL) { 00141 return ARM_DRIVER_ERROR_BUSY; 00142 } 00143 if ((size > volumeSize) || ((addr + size) > volumeSize)) { 00144 return ARM_DRIVER_ERROR_PARAMETER; 00145 } 00146 00147 volumeManager->activeVolume = this; 00148 int32_t rc = volumeManager->getStorage()->Erase(volumeOffset + addr, size); 00149 if (rc != ARM_DRIVER_OK) { 00150 volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */ 00151 } 00152 return rc; 00153 } 00154 00155 int32_t StorageVolume::EraseAll(void) 00156 { 00157 tr_debug("called eraseAll"); 00158 if (!allocated) { 00159 return STORAGE_VOLUME_MANAGER_STATUS_ERROR_VOLUME_NOT_ALLOCATED; 00160 } 00161 if (volumeManager->activeVolume != NULL) { 00162 return ARM_DRIVER_ERROR_BUSY; 00163 } 00164 00165 int32_t rc; 00166 00167 /* Allow EraseAll() only if the volume spans the entire storage. */ 00168 { 00169 ARM_STORAGE_INFO info; 00170 rc = volumeManager->getStorage()->GetInfo(&info); 00171 if (rc != ARM_DRIVER_OK) { 00172 return ARM_DRIVER_ERROR; 00173 } 00174 00175 if ((volumeOffset != 0) || (volumeSize != info.total_storage)) { 00176 return ARM_DRIVER_ERROR_UNSUPPORTED; 00177 } 00178 } 00179 00180 volumeManager->activeVolume = this; 00181 rc = volumeManager->getStorage()->EraseAll(); 00182 if (rc != ARM_DRIVER_OK) { 00183 volumeManager->activeVolume = NULL; /* we're certain that there is no more pending asynch. activity */ 00184 } 00185 return rc; 00186 } 00187 00188 ARM_STORAGE_STATUS StorageVolume::GetStatus(void) 00189 { 00190 const uint32_t busy = ((volumeManager->activeVolume != NULL) ? (uint32_t)1 : (uint32_t)0); 00191 ARM_STORAGE_STATUS status = {0, 0}; 00192 status.busy = busy; 00193 return status; 00194 } 00195 00196 int32_t StorageVolume::GetInfo(ARM_STORAGE_INFO *infoP) 00197 { 00198 int32_t rc; 00199 rc = volumeManager->getStorage()->GetInfo(infoP); 00200 if (rc != ARM_DRIVER_OK) { 00201 return ARM_DRIVER_ERROR; 00202 } 00203 00204 infoP->total_storage = volumeSize; 00205 return ARM_DRIVER_OK; 00206 } 00207 00208 uint32_t StorageVolume::ResolveAddress(uint64_t addr) { 00209 return (uint32_t)(volumeOffset + addr); 00210 } 00211 00212 int32_t StorageVolume::GetNextBlock(const ARM_STORAGE_BLOCK* prevP, ARM_STORAGE_BLOCK *nextP) 00213 { 00214 int32_t rc; 00215 ARM_STORAGE_BLOCK tmpBlock; 00216 do { 00217 /* iterate forward */ 00218 rc = volumeManager->getStorage()->GetNextBlock(prevP, &tmpBlock); 00219 if (rc != ARM_DRIVER_OK) { 00220 return rc; 00221 } 00222 00223 /* Stop iteration if we have progressed past the boundary of this volume. */ 00224 if (tmpBlock.addr >= (volumeOffset + volumeSize)) { 00225 return ARM_DRIVER_ERROR; 00226 } 00227 } while (!this->overlapsWithBlock(&tmpBlock)); 00228 00229 if (nextP) { 00230 memcpy(nextP, &tmpBlock, sizeof(ARM_STORAGE_BLOCK)); 00231 transformBlockToVolume(nextP); 00232 } 00233 return ARM_DRIVER_OK; 00234 } 00235 00236 int32_t StorageVolume::GetBlock(uint64_t addr, ARM_STORAGE_BLOCK *blockP) 00237 { 00238 ARM_STORAGE_BLOCK tmpBlock; 00239 int32_t rc = volumeManager->getStorage()->GetBlock(ResolveAddress(addr), &tmpBlock); 00240 if (rc != ARM_DRIVER_OK) { 00241 return rc; 00242 } 00243 if (!this->overlapsWithBlock(&tmpBlock)) { 00244 return ARM_DRIVER_ERROR; 00245 } 00246 00247 if (blockP) { 00248 memcpy(blockP, &tmpBlock, sizeof(ARM_STORAGE_BLOCK)); 00249 transformBlockToVolume(blockP); 00250 } 00251 return ARM_DRIVER_OK; 00252 }
Generated on Tue Jul 12 2022 18:19:34 by
