IgH EtherCAT Master  1.6.0-rc1
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->password = 0;
65  req->buffer_size = 0;
66  req->data_size = 0;
67  req->dir = EC_DIR_INVALID;
68  req->issue_timeout = 0; // no timeout
70  req->state = EC_INT_REQUEST_INIT;
71  req->result = FOE_BUSY;
72  req->error_code = 0x00000000;
73 }
74 
75 /*****************************************************************************/
76 
80  ec_foe_request_t *req
81  )
82 {
84 }
85 
86 /*****************************************************************************/
87 
91  ec_foe_request_t *req
92  )
93 {
94  if (req->buffer) {
95  vfree(req->buffer);
96  req->buffer = NULL;
97  }
98 
99  req->buffer_size = 0;
100  req->data_size = 0;
101 }
102 
103 /*****************************************************************************/
104 
113  ec_foe_request_t *req,
114  size_t size
115  )
116 {
117  if (size <= req->buffer_size) {
118  return 0;
119  }
120 
122 
123  if (!(req->buffer = (uint8_t *) vmalloc(size))) {
124  EC_ERR("Failed to allocate %zu bytes of FoE memory.\n", size);
125  return -ENOMEM;
126  }
127 
128  req->buffer_size = size;
129  req->data_size = 0;
130  return 0;
131 }
132 
133 /*****************************************************************************/
134 
142  ec_foe_request_t *req,
143  const uint8_t *source,
144  size_t size
145  )
146 {
147  int ret;
148 
149  ret = ec_foe_request_alloc(req, size);
150  if (ret) {
151  return ret;
152  }
153 
154  memcpy(req->buffer, source, size);
155  req->data_size = size;
156  return 0;
157 }
158 
159 /*****************************************************************************/
160 
166  const ec_foe_request_t *req
167  )
168 {
169  return req->issue_timeout
170  && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000;
171 }
172 
173 /*****************************************************************************/
174 
178  ec_foe_request_t *req,
179  uint32_t timeout
180  )
181 {
182  req->issue_timeout = timeout;
183 }
184 
185 /*****************************************************************************/
186 
192  ec_foe_request_t *req
193  )
194 {
195  return req->buffer;
196 }
197 
198 /*****************************************************************************/
199 
205  const ec_foe_request_t *req
206  )
207 {
208  return req->data_size;
209 }
210 
211 /*****************************************************************************/
212 
216  ec_foe_request_t *req
217  )
218 {
219  req->dir = EC_DIR_INPUT;
220  req->state = EC_INT_REQUEST_QUEUED;
221  req->result = FOE_BUSY;
222  req->jiffies_start = jiffies;
223 }
224 
225 /*****************************************************************************/
226 
230  ec_foe_request_t *req
231  )
232 {
233  req->dir = EC_DIR_OUTPUT;
234  req->state = EC_INT_REQUEST_QUEUED;
235  req->result = FOE_BUSY;
236  req->jiffies_start = jiffies;
237 }
238 
239 /*****************************************************************************/
ec_direction_t dir
Direction.
Definition: foe_request.h:60
int ec_foe_request_timed_out(const ec_foe_request_t *req)
Checks, if the timeout was exceeded.
Definition: foe_request.c:165
void ec_foe_request_write(ec_foe_request_t *req)
Prepares a write request (master to slave).
Definition: foe_request.c:229
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:112
uint32_t result
FoE request abort code.
Definition: foe_request.h:69
uint32_t response_timeout
Maximum time in ms, the transfer is retried, if the slave does not respond.
Definition: foe_request.h:58
void ec_foe_request_timeout(ec_foe_request_t *req, uint32_t timeout)
Set the request timeout.
Definition: foe_request.c:177
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:79
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
#define EC_FOE_REQUEST_RESPONSE_TIMEOUT
Default timeout in ms to wait for FoE transfer responses.
Definition: foe_request.c:47
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:52
Busy.
Definition: foe.h:42
EtherCAT FoE request structure.
void ec_foe_request_init(ec_foe_request_t *req, uint8_t *file_name)
FoE request constructor.
Definition: foe_request.c:57
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:141
uint8_t * ec_foe_request_data(ec_foe_request_t *req)
Returns a pointer to the request&#39;s data.
Definition: foe_request.c:191
Values read by the master.
Definition: ecrt.h:438
FoE defines.
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:67
FoE request.
Definition: foe_request.h:50
Invalid direction.
Definition: ecrt.h:436
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition: globals.h:230
void ec_foe_request_clear_data(ec_foe_request_t *)
FoE request destructor.
Definition: foe_request.c:90
unsigned long jiffies_start
Jiffies, when the request was issued.
Definition: foe_request.h:64
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:215
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:70
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:63
uint32_t password
Password needed for FoE.
Definition: foe_request.h:68
Values written by the master.
Definition: ecrt.h:437
uint32_t issue_timeout
Maximum time in ms, the processing of the request may take.
Definition: foe_request.h:56
size_t ec_foe_request_data_size(const ec_foe_request_t *req)
Returns the data size.
Definition: foe_request.c:204
struct list_head list
List item.
Definition: foe_request.h:51