summaryrefslogtreecommitdiffstats
path: root/protocols/software.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/software.c')
-rw-r--r--protocols/software.c42
1 files changed, 7 insertions, 35 deletions
diff --git a/protocols/software.c b/protocols/software.c
index 55f62e8..0cba819 100644
--- a/protocols/software.c
+++ b/protocols/software.c
@@ -12,33 +12,21 @@
typedef struct pcilib_software_register_bank_context_s pcilib_software_register_bank_context_t;
+/**
+ * structure defining the context of software registers
+ */
struct pcilib_software_register_bank_context_s {
pcilib_register_bank_context_t bank_ctx; /**< the bank context associated with the software registers */
-
pcilib_kmem_handle_t *kmem; /**< the kernel memory for software registers */
void *addr; /**< the virtual adress of the allocated kernel memory*/
};
-/**
- * pcilib_software_registers_close
- * this function clear the kernel memory space that could have been allocated for software registers
- * @param[in] bank_ctx the bank context running that we get from the initialisation function
- */
void pcilib_software_registers_close(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx) {
if (((pcilib_software_register_bank_context_t*)bank_ctx)->kmem)
pcilib_free_kernel_memory(ctx, ((pcilib_software_register_bank_context_t*)bank_ctx)->kmem, PCILIB_KMEM_FLAG_REUSE);
free(bank_ctx);
}
-/**
- * pcilib_software_registers_open
- * this function initializes the kernel space memory and stores in it the default values of the registers of the given bank index, if it was not initialized by a concurrent process, and return a bank context containing the adress of this kernel space. It the kernel space memory was already initialized by a concurrent process, then this function just return the bank context with the adress of this kernel space already used
- * @param[in] ctx the pcilib_t structure running
- * @param[in] bank the bank index that will permits to get the bank we want registers from
- * @param[in] model not used
- * @param[in] args not used
- * @return a bank context with the adress of the kernel space memory related to it
- */
pcilib_register_bank_context_t* pcilib_software_registers_open(pcilib_t *ctx, pcilib_register_bank_t bank, const char* model, const void *args) {
int err;
pcilib_software_register_bank_context_t *bank_ctx;
@@ -59,6 +47,7 @@ pcilib_register_bank_context_t* pcilib_software_registers_open(pcilib_t *ctx, pc
return NULL;
}
+ /*we get a lock to protect the creation of the kernel space for software registers against multiple creations*/
lock = pcilib_get_lock(ctx, PCILIB_LOCK_FLAGS_DEFAULT, "softreg/%s", bank_desc->name);
if (!lock) {
pcilib_software_registers_close(ctx, (pcilib_register_bank_context_t*)bank_ctx);
@@ -74,7 +63,7 @@ pcilib_register_bank_context_t* pcilib_software_registers_open(pcilib_t *ctx, pc
return NULL;
}
-
+ /*creation of the kernel space*/
handle = pcilib_alloc_kernel_memory(ctx, PCILIB_KMEM_TYPE_PAGE, 1, PCILIB_KMEM_PAGE_SIZE, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_SOFTWARE_REGISTERS, bank_desc->addr), PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_PERSISTENT);
if (!handle) {
pcilib_unlock(lock);
@@ -98,7 +87,8 @@ pcilib_register_bank_context_t* pcilib_software_registers_open(pcilib_t *ctx, pc
pcilib_error("Inconsistent software registers are found (only part of required buffers is available)");
return NULL;
}
-
+
+ /* here we fill the software registers with their default value*/
for (i = 0; ctx->model_info.registers[i].name != NULL; i++) {
if ((ctx->model_info.registers[i].bank == ctx->banks[bank].addr)&&(ctx->model_info.registers[i].type == PCILIB_REGISTER_STANDARD)) {
*(pcilib_register_value_t*)(bank_ctx->addr + ctx->model_info.registers[i].addr) = ctx->model_info.registers[i].defvalue;
@@ -112,15 +102,6 @@ pcilib_register_bank_context_t* pcilib_software_registers_open(pcilib_t *ctx, pc
return (pcilib_register_bank_context_t*)bank_ctx;
}
-/**
- * pcilib_software_registers_read
- * this function read the value of a said register in the kernel space
- * @param[in] ctx the pcilib_t structure runnning
- * @param[in] bank_ctx the bank context that was returned by the initialisation function
- * @param[in] addr the adress of the register we want to read
- * @param[out] value the value of the register
- * @return 0 in case of success
- */
int pcilib_software_registers_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t *value){
if ((addr + sizeof(pcilib_register_value_t)) > bank_ctx->bank->size) {
pcilib_error("Trying to access space outside of the define register bank (bank: %s, addr: 0x%lx)", bank_ctx->bank->name, addr);
@@ -132,15 +113,6 @@ int pcilib_software_registers_read(pcilib_t *ctx, pcilib_register_bank_context_t
return 0;
}
-/**
- * pcilib_software_registers_write
- * this function write the said value to a said register in the kernel space
- * @param[in] ctx the pcilib_t structure runnning
- * @param[in] bank_ctx the bank context that was returned by the initialisation function
- * @param[in] addr the adress of the register we want to write in
- * @param[out] value the value we want to write in the register
- * @return 0 in case of success
- */
int pcilib_software_registers_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t value) {
if ((addr + sizeof(pcilib_register_value_t)) > bank_ctx->bank->size) {
pcilib_error("Trying to access space outside of the define register bank (bank: %s, addr: 0x%lx)", bank_ctx->bank->name, addr);