00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039
00040
00041 #include <linux/slab.h>
00042
00043 #include "datagram.h"
00044 #include "master.h"
00045
00046
00047
00050 #define EC_FUNC_HEADER \
00051 if (unlikely(ec_datagram_prealloc(datagram, data_size))) \
00052 return -1; \
00053 datagram->index = 0; \
00054 datagram->working_counter = 0; \
00055 datagram->state = EC_CMD_INIT;
00056
00057 #define EC_FUNC_FOOTER \
00058 datagram->data_size = data_size; \
00059 memset(datagram->data, 0x00, data_size); \
00060 return 0;
00061
00064
00065
00070 void ec_datagram_init(ec_datagram_t *datagram )
00071 {
00072 datagram->type = EC_CMD_NONE;
00073 datagram->address.logical = 0x00000000;
00074 datagram->data = NULL;
00075 datagram->mem_size = 0;
00076 datagram->data_size = 0;
00077 datagram->index = 0x00;
00078 datagram->working_counter = 0x00;
00079 datagram->state = EC_CMD_INIT;
00080 datagram->t_sent = 0;
00081 }
00082
00083
00084
00089 void ec_datagram_clear(ec_datagram_t *datagram )
00090 {
00091 if (datagram->data) kfree(datagram->data);
00092 }
00093
00094
00095
00102 int ec_datagram_prealloc(ec_datagram_t *datagram,
00103 size_t size
00104 )
00105 {
00106 if (size <= datagram->mem_size) return 0;
00107
00108 if (datagram->data) {
00109 kfree(datagram->data);
00110 datagram->data = NULL;
00111 datagram->mem_size = 0;
00112 }
00113
00114 if (!(datagram->data = kmalloc(size, GFP_KERNEL))) {
00115 EC_ERR("Failed to allocate %i bytes of datagram memory!\n", size);
00116 return -1;
00117 }
00118
00119 datagram->mem_size = size;
00120 return 0;
00121 }
00122
00123
00124
00131 int ec_datagram_nprd(ec_datagram_t *datagram,
00133 uint16_t node_address,
00135 uint16_t offset,
00137 size_t data_size
00139 )
00140 {
00141 if (unlikely(node_address == 0x0000))
00142 EC_WARN("Using node address 0x0000!\n");
00143
00144 EC_FUNC_HEADER;
00145 datagram->type = EC_CMD_NPRD;
00146 datagram->address.physical.slave = node_address;
00147 datagram->address.physical.mem = offset;
00148 EC_FUNC_FOOTER;
00149 }
00150
00151
00152
00159 int ec_datagram_npwr(ec_datagram_t *datagram,
00161 uint16_t node_address,
00163 uint16_t offset,
00165 size_t data_size
00167 )
00168 {
00169 if (unlikely(node_address == 0x0000))
00170 EC_WARN("Using node address 0x0000!\n");
00171
00172 EC_FUNC_HEADER;
00173 datagram->type = EC_CMD_NPWR;
00174 datagram->address.physical.slave = node_address;
00175 datagram->address.physical.mem = offset;
00176 EC_FUNC_FOOTER;
00177 }
00178
00179
00180
00187 int ec_datagram_aprd(ec_datagram_t *datagram,
00189 uint16_t ring_position,
00191 uint16_t offset,
00193 size_t data_size
00195 )
00196 {
00197 EC_FUNC_HEADER;
00198 datagram->type = EC_CMD_APRD;
00199 datagram->address.physical.slave = (int16_t) ring_position * (-1);
00200 datagram->address.physical.mem = offset;
00201 EC_FUNC_FOOTER;
00202 }
00203
00204
00205
00212 int ec_datagram_apwr(ec_datagram_t *datagram,
00214 uint16_t ring_position,
00216 uint16_t offset,
00218 size_t data_size
00220 )
00221 {
00222 EC_FUNC_HEADER;
00223 datagram->type = EC_CMD_APWR;
00224 datagram->address.physical.slave = (int16_t) ring_position * (-1);
00225 datagram->address.physical.mem = offset;
00226 EC_FUNC_FOOTER;
00227 }
00228
00229
00230
00237 int ec_datagram_brd(ec_datagram_t *datagram,
00239 uint16_t offset,
00241 size_t data_size
00243 )
00244 {
00245 EC_FUNC_HEADER;
00246 datagram->type = EC_CMD_BRD;
00247 datagram->address.physical.slave = 0x0000;
00248 datagram->address.physical.mem = offset;
00249 EC_FUNC_FOOTER;
00250 }
00251
00252
00253
00260 int ec_datagram_bwr(ec_datagram_t *datagram,
00262 uint16_t offset,
00264 size_t data_size
00266 )
00267 {
00268 EC_FUNC_HEADER;
00269 datagram->type = EC_CMD_BWR;
00270 datagram->address.physical.slave = 0x0000;
00271 datagram->address.physical.mem = offset;
00272 EC_FUNC_FOOTER;
00273 }
00274
00275
00276
00283 int ec_datagram_lrw(ec_datagram_t *datagram,
00285 uint32_t offset,
00287 size_t data_size
00289 )
00290 {
00291 EC_FUNC_HEADER;
00292 datagram->type = EC_CMD_LRW;
00293 datagram->address.logical = offset;
00294 EC_FUNC_FOOTER;
00295 }
00296
00297