IgH EtherCAT Master  1.5.2
foe_request.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 2008 Olav Zarges, imc Messsysteme GmbH
4 * Copyright (C) 2020 Florian Pose, IgH
5 *
6 * This file is part of the IgH EtherCAT Master.
7 *
8 * The IgH EtherCAT Master is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2, as
10 * published by the Free Software Foundation.
11 *
12 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 * Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with the IgH EtherCAT Master; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 * ---
22 *
23 * The license mentioned above concerns the source code only. Using the
24 * EtherCAT technology and brand is only permitted in compliance with the
25 * industrial property and similar rights of Beckhoff Automation GmbH.
26 *
27 *****************************************************************************/
28
33/*****************************************************************************/
34
35#include <linux/module.h>
36#include <linux/jiffies.h>
37#include <linux/slab.h>
38#include <linux/vmalloc.h>
39
40#include "foe_request.h"
41#include "foe.h"
42
43/*****************************************************************************/
44
47#define EC_FOE_REQUEST_RESPONSE_TIMEOUT 3000
48
49/*****************************************************************************/
50
52
53/*****************************************************************************/
54
58 ec_foe_request_t *req,
59 uint8_t* file_name )
60{
61 INIT_LIST_HEAD(&req->list);
62 req->buffer = NULL;
63 req->file_name = file_name;
64 req->buffer_size = 0;
65 req->data_size = 0;
66 req->dir = EC_DIR_INVALID;
67 req->issue_timeout = 0; // no timeout
69 req->state = EC_INT_REQUEST_INIT;
70 req->result = FOE_BUSY;
71 req->error_code = 0x00000000;
72}
73
74/*****************************************************************************/
75
80 )
81{
83}
84
85/*****************************************************************************/
86
91 )
92{
93 if (req->buffer) {
94 vfree(req->buffer);
95 req->buffer = NULL;
96 }
97
98 req->buffer_size = 0;
99 req->data_size = 0;
100}
101
102/*****************************************************************************/
103
112 ec_foe_request_t *req,
113 size_t size
114 )
115{
116 if (size <= req->buffer_size) {
117 return 0;
118 }
119
121
122 if (!(req->buffer = (uint8_t *) vmalloc(size))) {
123 EC_ERR("Failed to allocate %zu bytes of FoE memory.\n", size);
124 return -ENOMEM;
125 }
126
127 req->buffer_size = size;
128 req->data_size = 0;
129 return 0;
130}
131
132/*****************************************************************************/
133
141 ec_foe_request_t *req,
142 const uint8_t *source,
143 size_t size
144 )
145{
146 int ret;
147
148 ret = ec_foe_request_alloc(req, size);
149 if (ret) {
150 return ret;
151 }
152
153 memcpy(req->buffer, source, size);
154 req->data_size = size;
155 return 0;
156}
157
158/*****************************************************************************/
159
165 const ec_foe_request_t *req
166 )
167{
168 return req->issue_timeout
169 && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000;
170}
171
172/*****************************************************************************/
173
177 ec_foe_request_t *req,
178 uint32_t timeout
179 )
180{
181 req->issue_timeout = timeout;
182}
183
184/*****************************************************************************/
185
191 ec_foe_request_t *req
192 )
193{
194 return req->buffer;
195}
196
197/*****************************************************************************/
198
204 const ec_foe_request_t *req
205 )
206{
207 return req->data_size;
208}
209
210/*****************************************************************************/
211
215 ec_foe_request_t *req
216 )
217{
218 req->dir = EC_DIR_INPUT;
219 req->state = EC_INT_REQUEST_QUEUED;
220 req->result = FOE_BUSY;
221 req->jiffies_start = jiffies;
222}
223
224/*****************************************************************************/
225
229 ec_foe_request_t *req
230 )
231{
232 req->dir = EC_DIR_OUTPUT;
233 req->state = EC_INT_REQUEST_QUEUED;
234 req->result = FOE_BUSY;
235 req->jiffies_start = jiffies;
236}
237
238/*****************************************************************************/
FoE defines.
@ FOE_BUSY
Busy.
Definition: foe.h:42
void ec_foe_request_write(ec_foe_request_t *req)
Prepares a write request (master to slave).
Definition: foe_request.c:228
int ec_foe_request_copy_data(ec_foe_request_t *req, const uint8_t *source, size_t size)
Copies FoE data from an external source.
Definition: foe_request.c:140
int ec_foe_request_timed_out(const ec_foe_request_t *req)
Checks, if the timeout was exceeded.
Definition: foe_request.c:164
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:214
size_t ec_foe_request_data_size(const ec_foe_request_t *req)
Returns the data size.
Definition: foe_request.c:203
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:111
void ec_foe_request_init(ec_foe_request_t *req, uint8_t *file_name)
FoE request constructor.
Definition: foe_request.c:57
uint8_t * ec_foe_request_data(ec_foe_request_t *req)
Returns a pointer to the request's data.
Definition: foe_request.c:190
void ec_foe_request_timeout(ec_foe_request_t *req, uint32_t timeout)
Set the request timeout.
Definition: foe_request.c:176
#define EC_FOE_REQUEST_RESPONSE_TIMEOUT
Default timeout in ms to wait for FoE transfer responses.
Definition: foe_request.c:47
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:78
void ec_foe_request_clear_data(ec_foe_request_t *)
FoE request destructor.
Definition: foe_request.c:89
EtherCAT FoE request structure.
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition: globals.h:215
@ EC_DIR_INVALID
Invalid direction.
Definition: ecrt.h:431
@ EC_DIR_INPUT
Values read by the master.
Definition: ecrt.h:433
@ EC_DIR_OUTPUT
Values written by the master.
Definition: ecrt.h:432
FoE request.
Definition: foe_request.h:50
ec_direction_t dir
Direction.
Definition: foe_request.h:60
uint32_t issue_timeout
Maximum time in ms, the processing of the request may take.
Definition: foe_request.h:56
uint32_t response_timeout
Maximum time in ms, the transfer is retried, if the slave does not respond.
Definition: foe_request.h:58
uint32_t result
FoE request abort code.
Definition: foe_request.h:68
struct list_head list
List item.
Definition: foe_request.h:51
unsigned long jiffies_start
Jiffies, when the request was issued.
Definition: foe_request.h:64
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:69
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:52
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:67
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:63