Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <assert.h>
      8 #include <debug.h>
      9 #include <io_driver.h>
     10 #include <io_dummy.h>
     11 #include <io_storage.h>
     12 #include <string.h>
     13 
     14 struct file_state {
     15 	int in_use;
     16 	size_t size;
     17 };
     18 
     19 static struct file_state current_file = {0};
     20 
     21 /* Identify the device type as dummy */
     22 static io_type_t device_type_dummy(void)
     23 {
     24 	return IO_TYPE_DUMMY;
     25 }
     26 
     27 /* Dummy device functions */
     28 static int dummy_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
     29 static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
     30 			     io_entity_t *entity);
     31 static int dummy_block_len(io_entity_t *entity, size_t *length);
     32 static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
     33 			     size_t length, size_t *length_read);
     34 static int dummy_block_close(io_entity_t *entity);
     35 static int dummy_dev_close(io_dev_info_t *dev_info);
     36 
     37 
     38 static const io_dev_connector_t dummy_dev_connector = {
     39 	.dev_open = dummy_dev_open
     40 };
     41 
     42 
     43 static const io_dev_funcs_t dummy_dev_funcs = {
     44 	.type = device_type_dummy,
     45 	.open = dummy_block_open,
     46 	.seek = NULL,
     47 	.size = dummy_block_len,
     48 	.read = dummy_block_read,
     49 	.write = NULL,
     50 	.close = dummy_block_close,
     51 	.dev_init = NULL,
     52 	.dev_close = dummy_dev_close,
     53 };
     54 
     55 
     56 static const io_dev_info_t dummy_dev_info = {
     57 	.funcs = &dummy_dev_funcs,
     58 	.info = (uintptr_t)NULL
     59 };
     60 
     61 
     62 /* Open a connection to the dummy device */
     63 static int dummy_dev_open(const uintptr_t dev_spec __attribute__((unused)),
     64 			   io_dev_info_t **dev_info)
     65 {
     66 	assert(dev_info != NULL);
     67 	*dev_info = (io_dev_info_t *)&dummy_dev_info;
     68 
     69 	return 0;
     70 }
     71 
     72 
     73 /* Close a connection to the dummy device */
     74 static int dummy_dev_close(io_dev_info_t *dev_info)
     75 {
     76 	return 0;
     77 }
     78 
     79 
     80 /* Open a file on the dummy device */
     81 static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
     82 			     io_entity_t *entity)
     83 {
     84 	int result;
     85 	const io_block_spec_t *block_spec = (io_block_spec_t *)spec;
     86 
     87 	if (current_file.in_use == 0) {
     88 		assert(block_spec != NULL);
     89 		assert(entity != NULL);
     90 
     91 		current_file.in_use = 1;
     92 		current_file.size = block_spec->length;
     93 		entity->info = (uintptr_t)&current_file;
     94 		result = 0;
     95 	} else {
     96 		WARN("A Dummy device is already active. Close first.\n");
     97 		result = -ENOMEM;
     98 	}
     99 
    100 	return result;
    101 }
    102 
    103 
    104 /* Return the size of a file on the dummy device */
    105 static int dummy_block_len(io_entity_t *entity, size_t *length)
    106 {
    107 	assert(entity != NULL);
    108 	assert(length != NULL);
    109 
    110 	*length =  ((struct file_state *)entity->info)->size;
    111 
    112 	return 0;
    113 }
    114 
    115 
    116 /* Read data from a file on the dummy device */
    117 static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
    118 			     size_t length, size_t *length_read)
    119 {
    120 	assert(length_read != NULL);
    121 
    122 	*length_read = length;
    123 
    124 	return 0;
    125 }
    126 
    127 
    128 /* Close a file on the dummy device */
    129 static int dummy_block_close(io_entity_t *entity)
    130 {
    131 	assert(entity != NULL);
    132 
    133 	entity->info = 0;
    134 	current_file.in_use = 0;
    135 
    136 	return 0;
    137 }
    138 
    139 
    140 /* Exported functions */
    141 
    142 /* Register the dummy driver with the IO abstraction */
    143 int register_io_dev_dummy(const io_dev_connector_t **dev_con)
    144 {
    145 	int result;
    146 
    147 	assert(dev_con != NULL);
    148 
    149 	result = io_register_device(&dummy_dev_info);
    150 	if (result == 0)
    151 		*dev_con = &dummy_dev_connector;
    152 
    153 	return result;
    154 }
    155