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_DATAGRAM_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 INIT_LIST_HEAD(&datagram->queue);
00073 datagram->type = EC_DATAGRAM_NONE;
00074 datagram->address.logical = 0x00000000;
00075 datagram->data = NULL;
00076 datagram->mem_size = 0;
00077 datagram->data_size = 0;
00078 datagram->index = 0x00;
00079 datagram->working_counter = 0x00;
00080 datagram->state = EC_DATAGRAM_INIT;
00081 datagram->cycles_queued = 0;
00082 datagram->cycles_sent = 0;
00083 datagram->jiffies_sent = 0;
00084 datagram->cycles_received = 0;
00085 datagram->jiffies_received = 0;
00086 }
00087
00088
00089
00094 void ec_datagram_clear(ec_datagram_t *datagram )
00095 {
00096 if (datagram->data) kfree(datagram->data);
00097 }
00098
00099
00100
00107 int ec_datagram_prealloc(ec_datagram_t *datagram,
00108 size_t size
00109 )
00110 {
00111 if (size <= datagram->mem_size) return 0;
00112
00113 if (datagram->data) {
00114 kfree(datagram->data);
00115 datagram->data = NULL;
00116 datagram->mem_size = 0;
00117 }
00118
00119 if (!(datagram->data = kmalloc(size, GFP_KERNEL))) {
00120 EC_ERR("Failed to allocate %i bytes of datagram memory!\n", size);
00121 return -1;
00122 }
00123
00124 datagram->mem_size = size;
00125 return 0;
00126 }
00127
00128
00129
00136 int ec_datagram_nprd(ec_datagram_t *datagram,
00138 uint16_t node_address,
00140 uint16_t offset,
00142 size_t data_size
00144 )
00145 {
00146 if (unlikely(node_address == 0x0000))
00147 EC_WARN("Using node address 0x0000!\n");
00148
00149 EC_FUNC_HEADER;
00150 datagram->type = EC_DATAGRAM_NPRD;
00151 datagram->address.physical.slave = node_address;
00152 datagram->address.physical.mem = offset;
00153 EC_FUNC_FOOTER;
00154 }
00155
00156
00157
00164 int ec_datagram_npwr(ec_datagram_t *datagram,
00166 uint16_t node_address,
00168 uint16_t offset,
00170 size_t data_size
00172 )
00173 {
00174 if (unlikely(node_address == 0x0000))
00175 EC_WARN("Using node address 0x0000!\n");
00176
00177 EC_FUNC_HEADER;
00178 datagram->type = EC_DATAGRAM_NPWR;
00179 datagram->address.physical.slave = node_address;
00180 datagram->address.physical.mem = offset;
00181 EC_FUNC_FOOTER;
00182 }
00183
00184
00185
00192 int ec_datagram_aprd(ec_datagram_t *datagram,
00194 uint16_t ring_position,
00196 uint16_t offset,
00198 size_t data_size
00200 )
00201 {
00202 EC_FUNC_HEADER;
00203 datagram->type = EC_DATAGRAM_APRD;
00204 datagram->address.physical.slave = (int16_t) ring_position * (-1);
00205 datagram->address.physical.mem = offset;
00206 EC_FUNC_FOOTER;
00207 }
00208
00209
00210
00217 int ec_datagram_apwr(ec_datagram_t *datagram,
00219 uint16_t ring_position,
00221 uint16_t offset,
00223 size_t data_size
00225 )
00226 {
00227 EC_FUNC_HEADER;
00228 datagram->type = EC_DATAGRAM_APWR;
00229 datagram->address.physical.slave = (int16_t) ring_position * (-1);
00230 datagram->address.physical.mem = offset;
00231 EC_FUNC_FOOTER;
00232 }
00233
00234
00235
00242 int ec_datagram_brd(ec_datagram_t *datagram,
00244 uint16_t offset,
00246 size_t data_size
00248 )
00249 {
00250 EC_FUNC_HEADER;
00251 datagram->type = EC_DATAGRAM_BRD;
00252 datagram->address.physical.slave = 0x0000;
00253 datagram->address.physical.mem = offset;
00254 EC_FUNC_FOOTER;
00255 }
00256
00257
00258
00265 int ec_datagram_bwr(ec_datagram_t *datagram,
00267 uint16_t offset,
00269 size_t data_size
00271 )
00272 {
00273 EC_FUNC_HEADER;
00274 datagram->type = EC_DATAGRAM_BWR;
00275 datagram->address.physical.slave = 0x0000;
00276 datagram->address.physical.mem = offset;
00277 EC_FUNC_FOOTER;
00278 }
00279
00280
00281
00288 int ec_datagram_lrw(ec_datagram_t *datagram,
00290 uint32_t offset,
00292 size_t data_size
00294 )
00295 {
00296 EC_FUNC_HEADER;
00297 datagram->type = EC_DATAGRAM_LRW;
00298 datagram->address.logical = offset;
00299 EC_FUNC_FOOTER;
00300 }
00301
00302