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