IgH EtherCAT Master  1.6.9
soe_request.c
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * Copyright (C) 2006-2023 Florian Pose, Ingenieurgemeinschaft IgH
4 *
5 * This file is part of the IgH EtherCAT Master.
6 *
7 * The IgH EtherCAT Master is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
10 *
11 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 * Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with the IgH EtherCAT Master; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 ****************************************************************************/
21
25
26/****************************************************************************/
27
28#include <linux/module.h>
29#include <linux/jiffies.h>
30#include <linux/slab.h>
31
32#include "soe_request.h"
33
34/****************************************************************************/
35
38#define EC_SOE_REQUEST_RESPONSE_TIMEOUT 1000
39
40/****************************************************************************/
41
43
44/****************************************************************************/
45
50 )
51{
52 INIT_LIST_HEAD(&req->list);
53 req->drive_no = 0x00;
54 req->idn = 0x0000;
56 req->data = NULL;
57 req->mem_size = 0;
58 req->data_size = 0;
59 req->issue_timeout = 0; // no timeout
60 req->dir = EC_DIR_INVALID;
61 req->state = EC_INT_REQUEST_INIT;
62 req->jiffies_start = 0U;
63 req->jiffies_sent = 0U;
64 req->error_code = 0x0000;
65}
66
67/****************************************************************************/
68
77
78/****************************************************************************/
79
85 ec_soe_request_t *req,
86 const ec_soe_request_t *other
87 )
88{
89 req->drive_no = other->drive_no;
90 req->idn = other->idn;
91 req->al_state = other->al_state;
92 return ec_soe_request_copy_data(req, other->data, other->data_size);
93}
94
95/****************************************************************************/
96
100 ec_soe_request_t *req,
101 uint8_t drive_no
102 )
103{
104 req->drive_no = drive_no;
105}
106
107/****************************************************************************/
108
112 ec_soe_request_t *req,
113 uint16_t idn
114 )
115{
116 req->idn = idn;
117}
118
119/****************************************************************************/
120
124 ec_soe_request_t *req
125 )
126{
127 if (req->data) {
128 kfree(req->data);
129 req->data = NULL;
130 }
131
132 req->mem_size = 0;
133 req->data_size = 0;
134}
135
136/****************************************************************************/
137
145 ec_soe_request_t *req,
146 size_t size
147 )
148{
149 if (size <= req->mem_size)
150 return 0;
151
153
154 if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) {
155 EC_ERR("Failed to allocate %zu bytes of SoE memory.\n", size);
156 return -ENOMEM;
157 }
158
159 req->mem_size = size;
160 req->data_size = 0;
161 return 0;
162}
163
164/****************************************************************************/
165
174 ec_soe_request_t *req,
175 const uint8_t *source,
176 size_t size
177 )
178{
179 int ret = ec_soe_request_alloc(req, size);
180 if (ret < 0)
181 return ret;
182
183 memcpy(req->data, source, size);
184 req->data_size = size;
185 return 0;
186}
187
188/****************************************************************************/
189
198 ec_soe_request_t *req,
199 const uint8_t *source,
200 size_t size
201 )
202{
203 if (req->data_size + size > req->mem_size) {
204 size_t new_size = req->mem_size ? req->mem_size * 2 : size;
205 uint8_t *new_data = (uint8_t *) kmalloc(new_size, GFP_KERNEL);
206 if (!new_data) {
207 EC_ERR("Failed to allocate %zu bytes of SoE memory.\n",
208 new_size);
209 return -ENOMEM;
210 }
211 memcpy(new_data, req->data, req->data_size);
212 kfree(req->data);
213 req->data = new_data;
214 req->mem_size = new_size;
215 }
216
217 memcpy(req->data + req->data_size, source, size);
218 req->data_size += size;
219 return 0;
220}
221
222/****************************************************************************/
223
227 ec_soe_request_t *req
228 )
229{
230 req->dir = EC_DIR_INPUT;
231 req->state = EC_INT_REQUEST_QUEUED;
232 req->error_code = 0x0000;
233 req->jiffies_start = jiffies;
234 return 0;
235}
236
237/****************************************************************************/
238
242 ec_soe_request_t *req
243 )
244{
245 req->dir = EC_DIR_OUTPUT;
246 req->state = EC_INT_REQUEST_QUEUED;
247 req->error_code = 0x0000;
248 req->jiffies_start = jiffies;
249 return 0;
250}
251
252/****************************************************************************/
253
259{
260 return req->issue_timeout
261 && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000;
262}
263
264/*****************************************************************************
265 * Application interface.
266 ****************************************************************************/
267
268int ecrt_soe_request_idn(ec_soe_request_t *req, uint8_t drive_no,
269 uint16_t idn)
270{
271 req->drive_no = drive_no;
272 req->idn = idn;
273 return 0;
274}
275
276/****************************************************************************/
277
279{
280 req->issue_timeout = timeout;
281 return 0;
282}
283
284/****************************************************************************/
285
287{
288 return req->data;
289}
290
291/****************************************************************************/
292
294{
295 return req->data_size;
296}
297
298/****************************************************************************/
299
304
305/****************************************************************************/
306
308{
309 return ec_soe_request_read(req);
310}
311
312/****************************************************************************/
313
318
319/****************************************************************************/
320
322
323EXPORT_SYMBOL(ecrt_soe_request_idn);
324EXPORT_SYMBOL(ecrt_soe_request_timeout);
325EXPORT_SYMBOL(ecrt_soe_request_data);
326EXPORT_SYMBOL(ecrt_soe_request_data_size);
327EXPORT_SYMBOL(ecrt_soe_request_state);
328EXPORT_SYMBOL(ecrt_soe_request_read);
329EXPORT_SYMBOL(ecrt_soe_request_write);
330
332
333/****************************************************************************/
const ec_request_state_t ec_request_state_translation_table[]
Global request state type translation table.
Definition module.c:658
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition globals.h:224
struct ec_soe_request ec_soe_request_t
Definition ecrt.h:312
int ecrt_soe_request_write(ec_soe_request_t *req)
Schedule an SoE IDN write operation.
int ecrt_soe_request_idn(ec_soe_request_t *req, uint8_t drive_no, uint16_t idn)
Set the request's drive and Sercos ID numbers.
ec_request_state_t ecrt_soe_request_state(const ec_soe_request_t *req)
Get the current state of the SoE request.
size_t ecrt_soe_request_data_size(const ec_soe_request_t *req)
Returns the current IDN data size.
uint8_t * ecrt_soe_request_data(const ec_soe_request_t *req)
Access to the SoE request's data.
ec_request_state_t
Request state.
Definition ecrt.h:604
int ecrt_soe_request_read(ec_soe_request_t *req)
Schedule an SoE IDN read operation.
int ecrt_soe_request_timeout(ec_soe_request_t *req, uint32_t timeout)
Set the timeout for an SoE request.
@ EC_AL_STATE_INIT
Init.
Definition ecrt.h:616
@ EC_DIR_INVALID
Invalid direction.
Definition ecrt.h:505
@ EC_DIR_INPUT
Values read by the master.
Definition ecrt.h:507
@ EC_DIR_OUTPUT
Values written by the master.
Definition ecrt.h:506
void ec_soe_request_clear_data(ec_soe_request_t *)
Free allocated memory.
int ec_soe_request_read(ec_soe_request_t *req)
Request a read operation.
int ec_soe_request_copy(ec_soe_request_t *req, const ec_soe_request_t *other)
Copy another SoE request.
Definition soe_request.c:84
void ec_soe_request_set_idn(ec_soe_request_t *req, uint16_t idn)
Set IDN.
void ec_soe_request_set_drive_no(ec_soe_request_t *req, uint8_t drive_no)
Set drive number.
Definition soe_request.c:99
int ec_soe_request_timed_out(const ec_soe_request_t *req)
Checks, if the timeout was exceeded.
int ec_soe_request_copy_data(ec_soe_request_t *req, const uint8_t *source, size_t size)
Copies SoE data from an external source.
int ec_soe_request_append_data(ec_soe_request_t *req, const uint8_t *source, size_t size)
Copies SoE data from an external source.
int ec_soe_request_write(ec_soe_request_t *req)
Request a write operation.
void ec_soe_request_init(ec_soe_request_t *req)
SoE request constructor.
Definition soe_request.c:48
int ec_soe_request_alloc(ec_soe_request_t *req, size_t size)
Pre-allocates the data memory.
void ec_soe_request_clear(ec_soe_request_t *req)
SoE request destructor.
Definition soe_request.c:71
EtherCAT SoE request structure.
ec_al_state_t al_state
AL state (only valid for IDN config).
Definition soe_request.h:44
uint32_t issue_timeout
Maximum time in ms, the processing of the request may take.
Definition soe_request.h:48
uint16_t idn
Sercos ID-Number.
Definition soe_request.h:43
size_t mem_size
Size of SDO data memory.
Definition soe_request.h:46
uint8_t drive_no
Drive number.
Definition soe_request.h:42
ec_direction_t dir
Direction.
Definition soe_request.h:50
size_t data_size
Size of SDO data.
Definition soe_request.h:47
unsigned long jiffies_start
Jiffies, when the request was issued.
Definition soe_request.h:53
uint16_t error_code
SoE error code.
Definition soe_request.h:56
ec_internal_request_state_t state
Request state.
Definition soe_request.h:52
uint8_t * data
Pointer to SDO data.
Definition soe_request.h:45
struct list_head list
List item.
Definition soe_request.h:41
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition soe_request.h:54