flinklib
flinklib: flink C library for Linux
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
lowlevel.c
Go to the documentation of this file.
1 /*******************************************************************
2  * _________ _____ _____ ____ _____ ___ ____ *
3  * |_ ___ | |_ _| |_ _| |_ \|_ _| |_ ||_ _| *
4  * | |_ \_| | | | | | \ | | | |_/ / *
5  * | _| | | _ | | | |\ \| | | __'. *
6  * _| |_ _| |__/ | _| |_ _| |_\ |_ _| | \ \_ *
7  * |_____| |________| |_____| |_____|\____| |____||____| *
8  * *
9  *******************************************************************
10  * *
11  * fLink userspace library, low level operations *
12  * *
13  *******************************************************************/
14 
26 #include "flinklib.h"
27 #include "flinkioctl.h"
28 #include "types.h"
29 #include "error.h"
30 #include "log.h"
31 #include "valid.h"
32 
33 #include <sys/ioctl.h>
34 #include <unistd.h>
35 
36 
44 int flink_ioctl(flink_dev* dev, int cmd, void* arg) {
45  int ret;
46 
47  dbg_print("flink_ioctl '0x%x'\n", cmd);
48 
49  if(!validate_flink_dev(dev)) {
51  return EXIT_ERROR;
52  }
53 
54  ret = ioctl(dev->fd, cmd, arg);
55  if(ret < 0) {
56  libc_error();
57  }
58 
59  return ret;
60 }
61 
62 
71 ssize_t flink_read(flink_subdev* subdev, uint32_t offset, uint8_t size, void* rdata) {
72  int res = 0;
73  ssize_t read_size = 0;
74  ioctl_container_t ioctl_arg;
75  ioctl_arg.subdevice = subdev->id;
76  ioctl_arg.offset = offset;
77  ioctl_arg.size = size;
78  ioctl_arg.data = rdata;
79 
80  // Check data pointer
81  if(rdata == NULL) {
83  return EXIT_ERROR;
84  }
85 
86  // Check flink subdevice structure
87  if(!validate_flink_subdev(subdev)) {
89  return EXIT_ERROR;
90  }
91 
92  // read data from device
93  read_size = flink_ioctl(subdev->parent, SELECT_AND_READ, &ioctl_arg);
94  if(read_size == -1) {
95  libc_error();
96  return EXIT_ERROR;
97  }
98 
99  return read_size;
100 }
101 
102 
111 ssize_t flink_write(flink_subdev* subdev, uint32_t offset, uint8_t size, void* wdata) {
112  int res = 0;
113  ssize_t write_size = 0;
114  ioctl_container_t ioctl_arg;
115  ioctl_arg.subdevice = subdev->id;
116  ioctl_arg.offset = offset;
117  ioctl_arg.size = size;
118  ioctl_arg.data = wdata;
119 
120  // Check data pointer
121  if(wdata == NULL) {
123  return EXIT_ERROR;
124  }
125 
126  // Check flink subdevice structure
127  if(!validate_flink_subdev(subdev)) {
129  return EXIT_ERROR;
130  }
131 
132  // write data to device
133  write_size = flink_ioctl(subdev->parent, SELECT_AND_WRITE, &ioctl_arg);
134  if(write_size == -1) {
135  libc_error();
136  return EXIT_ERROR;
137  }
138 
139  return write_size;
140 }
141 
142 
151 int flink_read_bit(flink_subdev* subdev, uint32_t offset, uint8_t bit, void* rdata) {
152  ioctl_bit_container_t ioctl_arg;
153  ioctl_arg.offset = offset;
154  ioctl_arg.bit = bit;
155  ioctl_arg.subdevice = subdev->id;
156 
157  // Check data pointer
158  if(rdata == NULL) {
160  return EXIT_ERROR;
161  }
162 
163  // Check flink subdevice structure
164  if(!validate_flink_subdev(subdev)) {
166  return EXIT_ERROR;
167  }
168 
169  // select subdevice and read data
170  if(flink_ioctl(subdev->parent, SELECT_AND_READ_BIT, &ioctl_arg) < 0) {
171  libc_error();
172  return EXIT_ERROR;
173  }
174 
175  *((uint8_t*)rdata) = ioctl_arg.value;
176 
177  return EXIT_SUCCESS;
178 }
179 
180 
189 int flink_write_bit(flink_subdev* subdev, uint32_t offset, uint8_t bit, void* wdata) {
190  ioctl_bit_container_t ioctl_arg;
191  ioctl_arg.offset = offset;
192  ioctl_arg.bit = bit;
193  ioctl_arg.value = *((uint8_t*)wdata);
194  ioctl_arg.subdevice = subdev->id;
195 
196  // Check data pointer
197  if(wdata == NULL) {
199  return EXIT_ERROR;
200  }
201 
202  // Check flink subdevice structure
203  if(!validate_flink_subdev(subdev)) {
205  return EXIT_ERROR;
206  }
207 
208  // select subdevice and write data
209  if(flink_ioctl(subdev->parent, SELECT_AND_WRITE_BIT, &ioctl_arg) < 0) {
210  libc_error();
211  return EXIT_ERROR;
212  }
213 
214  return EXIT_SUCCESS;
215 }
Data structures for flink devices and subdevices.
uint8_t bit
Offset of byte containing the single bit, taken from subdevice base address.
Definition: flinkioctl.h:41
ssize_t flink_write(flink_subdev *subdev, uint32_t offset, uint8_t size, void *wdata)
Write to a flink subdevice.
Definition: lowlevel.c:111
void * data
size of data
Definition: flinkioctl.h:50
#define FLINK_ENULLPTR
Definition: error.h:32
uint32_t offset
subdevice to read from / write to
Definition: flinkioctl.h:48
#define FLINK_EINVALDEV
Definition: error.h:29
uint8_t value
Bit number in byte.
Definition: flinkioctl.h:42
#define EXIT_ERROR
Definition: flinklib.h:118
uint8_t subdevice
Value of the bit.
Definition: flinkioctl.h:43
Error handling.
uint8_t size
offset to base address of subdevice
Definition: flinkioctl.h:49
flink userspace library, ioctl definitions.
#define EXIT_SUCCESS
Definition: flinklib.h:117
int flink_read_bit(flink_subdev *subdev, uint32_t offset, uint8_t bit, void *rdata)
Read a single bit from a flink subdevice.
Definition: lowlevel.c:151
int flink_ioctl(flink_dev *dev, int cmd, void *arg)
IOCTL operation for a flink device.
Definition: lowlevel.c:44
int validate_flink_subdev(flink_subdev *subdev)
Checks if flink subdevice belongs to the device.
Definition: valid.c:40
Contains validation functions for flink.
void flink_error(int e)
Definition: error.c:64
ssize_t flink_read(flink_subdev *subdev, uint32_t offset, uint8_t size, void *rdata)
Read from a flink subdevice.
Definition: lowlevel.c:71
int validate_flink_dev(flink_dev *dev)
Checks if flink device was opened.
Definition: valid.c:28
int flink_write_bit(flink_subdev *subdev, uint32_t offset, uint8_t bit, void *wdata)
Write a single bit to a flink subdevice.
Definition: lowlevel.c:189
void libc_error(void)
Definition: error.c:56
Debug utilities.
#define dbg_print(fmt,...)
Definition: log.h:29