IgH EtherCAT Master  1.6.0
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 
27 /****************************************************************************/
28 
29 #include <linux/module.h>
30 #include <linux/jiffies.h>
31 #include <linux/slab.h>
32 #include <linux/vmalloc.h>
33 
34 #include "foe_request.h"
35 #include "foe.h"
36 
37 /****************************************************************************/
38 
41 #define EC_FOE_REQUEST_RESPONSE_TIMEOUT 3000
42 
43 /****************************************************************************/
44 
46 
47 /****************************************************************************/
48 
52  ec_foe_request_t *req,
53  uint8_t* file_name )
54 {
55  INIT_LIST_HEAD(&req->list);
56  req->buffer = NULL;
57  req->file_name = file_name;
58  req->buffer_size = 0;
59  req->data_size = 0;
60  req->dir = EC_DIR_INVALID;
61  req->issue_timeout = 0; // no timeout
63  req->state = EC_INT_REQUEST_INIT;
64  req->result = FOE_BUSY;
65  req->error_code = 0x00000000;
66 }
67 
68 /****************************************************************************/
69 
73  ec_foe_request_t *req
74  )
75 {
77 }
78 
79 /****************************************************************************/
80 
84  ec_foe_request_t *req
85  )
86 {
87  if (req->buffer) {
88  vfree(req->buffer);
89  req->buffer = NULL;
90  }
91 
92  req->buffer_size = 0;
93  req->data_size = 0;
94 }
95 
96 /****************************************************************************/
97 
106  ec_foe_request_t *req,
107  size_t size
108  )
109 {
110  if (size <= req->buffer_size) {
111  return 0;
112  }
113 
115 
116  if (!(req->buffer = (uint8_t *) vmalloc(size))) {
117  EC_ERR("Failed to allocate %zu bytes of FoE memory.\n", size);
118  return -ENOMEM;
119  }
120 
121  req->buffer_size = size;
122  req->data_size = 0;
123  return 0;
124 }
125 
126 /****************************************************************************/
127 
135  ec_foe_request_t *req,
136  const uint8_t *source,
137  size_t size
138  )
139 {
140  int ret;
141 
142  ret = ec_foe_request_alloc(req, size);
143  if (ret) {
144  return ret;
145  }
146 
147  memcpy(req->buffer, source, size);
148  req->data_size = size;
149  return 0;
150 }
151 
152 /****************************************************************************/
153 
159  const ec_foe_request_t *req
160  )
161 {
162  return req->issue_timeout
163  && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000;
164 }
165 
166 /****************************************************************************/
167 
171  ec_foe_request_t *req,
172  uint32_t timeout
173  )
174 {
175  req->issue_timeout = timeout;
176 }
177 
178 /****************************************************************************/
179 
185  ec_foe_request_t *req
186  )
187 {
188  return req->buffer;
189 }
190 
191 /****************************************************************************/
192 
198  const ec_foe_request_t *req
199  )
200 {
201  return req->data_size;
202 }
203 
204 /****************************************************************************/
205 
209  ec_foe_request_t *req
210  )
211 {
212  req->dir = EC_DIR_INPUT;
213  req->state = EC_INT_REQUEST_QUEUED;
214  req->result = FOE_BUSY;
215  req->jiffies_start = jiffies;
216 }
217 
218 /****************************************************************************/
219 
223  ec_foe_request_t *req
224  )
225 {
226  req->dir = EC_DIR_OUTPUT;
227  req->state = EC_INT_REQUEST_QUEUED;
228  req->result = FOE_BUSY;
229  req->jiffies_start = jiffies;
230 }
231 
232 /****************************************************************************/
ec_direction_t dir
Direction.
Definition: foe_request.h:52
int ec_foe_request_timed_out(const ec_foe_request_t *req)
Checks, if the timeout was exceeded.
Definition: foe_request.c:158
void ec_foe_request_write(ec_foe_request_t *req)
Prepares a write request (master to slave).
Definition: foe_request.c:222
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:105
uint32_t result
FoE request abort code.
Definition: foe_request.h:60
uint32_t response_timeout
Maximum time in ms, the transfer is retried, if the slave does not respond.
Definition: foe_request.h:50
void ec_foe_request_timeout(ec_foe_request_t *req, uint32_t timeout)
Set the request timeout.
Definition: foe_request.c:170
void ec_foe_request_clear_data(ec_foe_request_t *)
FoE request destructor.
Definition: foe_request.c:83
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:72
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:45
#define EC_FOE_REQUEST_RESPONSE_TIMEOUT
Default timeout in ms to wait for FoE transfer responses.
Definition: foe_request.c:41
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:44
Busy.
Definition: foe.h:34
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:51
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:134
uint8_t * ec_foe_request_data(ec_foe_request_t *req)
Returns a pointer to the request&#39;s data.
Definition: foe_request.c:184
Values read by the master.
Definition: ecrt.h:504
FoE defines.
size_t data_size
Size of FoE data.
Definition: foe_request.h:46
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:59
FoE request.
Definition: foe_request.h:42
Invalid direction.
Definition: ecrt.h:502
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition: globals.h:224
unsigned long jiffies_start
Jiffies, when the request was issued.
Definition: foe_request.h:56
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:208
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:61
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:55
Values written by the master.
Definition: ecrt.h:503
uint32_t issue_timeout
Maximum time in ms, the processing of the request may take.
Definition: foe_request.h:48
size_t ec_foe_request_data_size(const ec_foe_request_t *req)
Returns the data size.
Definition: foe_request.c:197
struct list_head list
List item.
Definition: foe_request.h:43