IgH EtherCAT Master  1.5.2
soe_request.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
6 *
7 * This file is part of the IgH EtherCAT Master.
8 *
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 * Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with the IgH EtherCAT Master; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * ---
23 *
24 * The license mentioned above concerns the source code only. Using the
25 * EtherCAT technology and brand is only permitted in compliance with the
26 * industrial property and similar rights of Beckhoff Automation GmbH.
27 *
28 *****************************************************************************/
29
34/*****************************************************************************/
35
36#include <linux/module.h>
37#include <linux/jiffies.h>
38#include <linux/slab.h>
39
40#include "soe_request.h"
41
42/*****************************************************************************/
43
46#define EC_SOE_REQUEST_RESPONSE_TIMEOUT 1000
47
48/*****************************************************************************/
49
51
52/*****************************************************************************/
53
58 )
59{
60 INIT_LIST_HEAD(&req->list);
61 req->drive_no = 0x00;
62 req->idn = 0x0000;
64 req->data = NULL;
65 req->mem_size = 0;
66 req->data_size = 0;
67 req->dir = EC_DIR_INVALID;
68 req->state = EC_INT_REQUEST_INIT;
69 req->jiffies_sent = 0U;
70 req->error_code = 0x0000;
71}
72
73/*****************************************************************************/
74
79 )
80{
82}
83
84/*****************************************************************************/
85
91 ec_soe_request_t *req,
92 const ec_soe_request_t *other
93 )
94{
95 req->drive_no = other->drive_no;
96 req->idn = other->idn;
97 req->al_state = other->al_state;
98 return ec_soe_request_copy_data(req, other->data, other->data_size);
99}
100
101/*****************************************************************************/
102
106 ec_soe_request_t *req,
107 uint8_t drive_no
108 )
109{
110 req->drive_no = drive_no;
111}
112
113/*****************************************************************************/
114
118 ec_soe_request_t *req,
119 uint16_t idn
120 )
121{
122 req->idn = idn;
123}
124
125/*****************************************************************************/
126
130 ec_soe_request_t *req
131 )
132{
133 if (req->data) {
134 kfree(req->data);
135 req->data = NULL;
136 }
137
138 req->mem_size = 0;
139 req->data_size = 0;
140}
141
142/*****************************************************************************/
143
151 ec_soe_request_t *req,
152 size_t size
153 )
154{
155 if (size <= req->mem_size)
156 return 0;
157
159
160 if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) {
161 EC_ERR("Failed to allocate %zu bytes of SoE memory.\n", size);
162 return -ENOMEM;
163 }
164
165 req->mem_size = size;
166 req->data_size = 0;
167 return 0;
168}
169
170/*****************************************************************************/
171
180 ec_soe_request_t *req,
181 const uint8_t *source,
182 size_t size
183 )
184{
185 int ret = ec_soe_request_alloc(req, size);
186 if (ret < 0)
187 return ret;
188
189 memcpy(req->data, source, size);
190 req->data_size = size;
191 return 0;
192}
193
194/*****************************************************************************/
195
204 ec_soe_request_t *req,
205 const uint8_t *source,
206 size_t size
207 )
208{
209 if (req->data_size + size > req->mem_size) {
210 size_t new_size = req->mem_size ? req->mem_size * 2 : size;
211 uint8_t *new_data = (uint8_t *) kmalloc(new_size, GFP_KERNEL);
212 if (!new_data) {
213 EC_ERR("Failed to allocate %zu bytes of SoE memory.\n",
214 new_size);
215 return -ENOMEM;
216 }
217 memcpy(new_data, req->data, req->data_size);
218 kfree(req->data);
219 req->data = new_data;
220 req->mem_size = new_size;
221 }
222
223 memcpy(req->data + req->data_size, source, size);
224 req->data_size += size;
225 return 0;
226}
227
228/*****************************************************************************/
229
233 ec_soe_request_t *req
234 )
235{
236 req->dir = EC_DIR_INPUT;
237 req->state = EC_INT_REQUEST_QUEUED;
238 req->error_code = 0x0000;
239}
240
241/*****************************************************************************/
242
246 ec_soe_request_t *req
247 )
248{
249 req->dir = EC_DIR_OUTPUT;
250 req->state = EC_INT_REQUEST_QUEUED;
251 req->error_code = 0x0000;
252}
253
254/*****************************************************************************/
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition: globals.h:215
@ EC_AL_STATE_INIT
Init.
Definition: ecrt.h:542
@ 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
void ec_soe_request_write(ec_soe_request_t *req)
Request a write operation.
Definition: soe_request.c:245
void ec_soe_request_clear_data(ec_soe_request_t *)
Free allocated memory.
Definition: soe_request.c:129
int ec_soe_request_copy(ec_soe_request_t *req, const ec_soe_request_t *other)
Copy another SoE request.
Definition: soe_request.c:90
void ec_soe_request_set_idn(ec_soe_request_t *req, uint16_t idn)
Set IDN.
Definition: soe_request.c:117
void ec_soe_request_set_drive_no(ec_soe_request_t *req, uint8_t drive_no)
Set drive number.
Definition: soe_request.c:105
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.
Definition: soe_request.c:179
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.
Definition: soe_request.c:203
void ec_soe_request_read(ec_soe_request_t *req)
Request a read operation.
Definition: soe_request.c:232
void ec_soe_request_init(ec_soe_request_t *req)
SoE request constructor.
Definition: soe_request.c:56
int ec_soe_request_alloc(ec_soe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: soe_request.c:150
void ec_soe_request_clear(ec_soe_request_t *req)
SoE request destructor.
Definition: soe_request.c:77
EtherCAT SoE request structure.
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
struct list_head list
List item.
Definition: soe_request.h:49
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
uint16_t error_code
SoE error code.
Definition: soe_request.h:61
ec_al_state_t al_state
AL state (only valid for IDN config).
Definition: soe_request.h:52
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
Definition: soe_request.h:59
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58
ec_direction_t dir
Direction.
Definition: soe_request.h:56
size_t mem_size
Size of SDO data memory.
Definition: soe_request.h:54
size_t data_size
Size of SDO data.
Definition: soe_request.h:55