fp@1209: /****************************************************************************** fp@1209: * fp@1209: * $Id$ fp@1209: * fp@1326: * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH fp@1209: * fp@1209: * This file is part of the IgH EtherCAT Master. fp@1209: * fp@1326: * The IgH EtherCAT Master is free software; you can redistribute it and/or fp@1326: * modify it under the terms of the GNU General Public License version 2, as fp@1326: * published by the Free Software Foundation. fp@1326: * fp@1326: * The IgH EtherCAT Master is distributed in the hope that it will be useful, fp@1326: * but WITHOUT ANY WARRANTY; without even the implied warranty of fp@1326: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General fp@1326: * Public License for more details. fp@1326: * fp@1326: * You should have received a copy of the GNU General Public License along fp@1326: * with the IgH EtherCAT Master; if not, write to the Free Software fp@1209: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA fp@1209: * fp@1363: * --- fp@1363: * fp@1363: * The license mentioned above concerns the source code only. Using the fp@1363: * EtherCAT technology and brand is only permitted in compliance with the fp@1363: * industrial property and similar rights of Beckhoff Automation GmbH. fp@1209: * fp@1209: *****************************************************************************/ fp@1209: fp@1209: /** \file fp@1327: * Vendor specific over EtherCAT protocol handler functions. fp@1209: */ fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1209: #include fp@1209: fp@1209: #include "master.h" fp@1209: #include "slave_config.h" fp@1209: #include "mailbox.h" fp@1209: #include "voe_handler.h" fp@1209: fp@1216: /** VoE mailbox type. fp@1216: */ fp@1224: #define EC_MBOX_TYPE_VOE 0x0f fp@1216: fp@1218: /** VoE header size. fp@1218: */ fp@1218: #define EC_VOE_HEADER_SIZE 6 fp@1218: fp@1209: /** VoE response timeout in [ms]. fp@1209: */ fp@1209: #define EC_VOE_RESPONSE_TIMEOUT 500 fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1209: void ec_voe_handler_state_write_start(ec_voe_handler_t *); fp@1209: void ec_voe_handler_state_write_response(ec_voe_handler_t *); fp@1209: fp@1209: void ec_voe_handler_state_read_start(ec_voe_handler_t *); fp@1209: void ec_voe_handler_state_read_check(ec_voe_handler_t *); fp@1209: void ec_voe_handler_state_read_response(ec_voe_handler_t *); fp@1209: fp@1314: void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *); fp@1314: void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *); fp@1314: fp@1209: void ec_voe_handler_state_end(ec_voe_handler_t *); fp@1209: void ec_voe_handler_state_error(ec_voe_handler_t *); fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1209: /** VoE handler constructor. fp@1312: * fp@1312: * \return Return value of ec_datagram_prealloc(). fp@1209: */ fp@1209: int ec_voe_handler_init( fp@1209: ec_voe_handler_t *voe, /**< VoE handler. */ fp@1209: ec_slave_config_t *sc, /**< Parent slave configuration. */ fp@1209: size_t size /**< Size of memory to reserve. */ fp@1209: ) fp@1209: { fp@1209: voe->config = sc; fp@1218: voe->vendor_id = 0x00000000; fp@1218: voe->vendor_type = 0x0000; fp@1209: voe->data_size = 0; fp@1209: voe->dir = EC_DIR_INVALID; fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_INIT; fp@1209: fp@1209: ec_datagram_init(&voe->datagram); fp@1312: return ec_datagram_prealloc(&voe->datagram, fp@1312: size + EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE); fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1209: /** VoE handler destructor. fp@1209: */ fp@1209: void ec_voe_handler_clear( fp@1209: ec_voe_handler_t *voe /**< VoE handler. */ fp@1209: ) fp@1209: { fp@1209: ec_datagram_clear(&voe->datagram); fp@1209: } fp@1209: fp@1264: /*****************************************************************************/ fp@1264: fp@1264: /** Get usable memory size. fp@2522: * fp@2522: * \return Memory size. fp@1264: */ fp@1264: size_t ec_voe_handler_mem_size( fp@1507: const ec_voe_handler_t *voe /**< VoE handler. */ fp@1507: ) fp@1507: { fp@1507: if (voe->datagram.mem_size >= EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE) fp@1507: return voe->datagram.mem_size - fp@1507: (EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE); fp@1507: else fp@1507: return 0; fp@1264: } fp@1264: fp@1209: /***************************************************************************** fp@1209: * Application interface. fp@1209: ****************************************************************************/ fp@1209: fp@1226: void ecrt_voe_handler_send_header(ec_voe_handler_t *voe, uint32_t vendor_id, fp@1218: uint16_t vendor_type) fp@1218: { fp@1218: voe->vendor_id = vendor_id; fp@1218: voe->vendor_type = vendor_type; fp@1218: } fp@1218: fp@1218: /*****************************************************************************/ fp@1218: fp@1226: void ecrt_voe_handler_received_header(const ec_voe_handler_t *voe, fp@1226: uint32_t *vendor_id, uint16_t *vendor_type) fp@1226: { fp@1226: uint8_t *header = voe->datagram.data + EC_MBOX_HEADER_SIZE; fp@1226: fp@1226: if (vendor_id) fp@1226: *vendor_id = EC_READ_U32(header); fp@1226: if (vendor_type) fp@1226: *vendor_type = EC_READ_U16(header + 4); fp@1226: } fp@1226: fp@1226: /*****************************************************************************/ fp@1226: fp@1209: uint8_t *ecrt_voe_handler_data(ec_voe_handler_t *voe) fp@1209: { fp@1218: return voe->datagram.data + EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE; fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1209: size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe) fp@1209: { fp@1209: return voe->data_size; fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1209: void ecrt_voe_handler_read(ec_voe_handler_t *voe) fp@1209: { fp@1209: voe->dir = EC_DIR_INPUT; fp@1209: voe->state = ec_voe_handler_state_read_start; fp@1348: voe->request_state = EC_INT_REQUEST_BUSY; fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1314: void ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe) fp@1314: { fp@1314: voe->dir = EC_DIR_INPUT; fp@1314: voe->state = ec_voe_handler_state_read_nosync_start; fp@1348: voe->request_state = EC_INT_REQUEST_BUSY; fp@1314: } fp@1314: fp@1314: /*****************************************************************************/ fp@1314: fp@1209: void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size) fp@1209: { fp@1209: voe->dir = EC_DIR_OUTPUT; fp@1218: voe->data_size = size; fp@1209: voe->state = ec_voe_handler_state_write_start; fp@1348: voe->request_state = EC_INT_REQUEST_BUSY; fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1209: ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe) fp@1209: { fp@1348: if (voe->config->slave) { // FIXME locking? fp@1209: voe->state(voe); fp@2374: if (voe->request_state == EC_INT_REQUEST_BUSY) { fp@2374: ec_master_queue_datagram(voe->config->master, &voe->datagram); fp@2374: } fp@1209: } else { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1209: } fp@1209: fp@1209: return ec_request_state_translation_table[voe->request_state]; fp@1209: } fp@1209: fp@1209: /****************************************************************************** fp@1209: * State functions. fp@1209: *****************************************************************************/ fp@1209: fp@1268: /** Start writing VoE data. fp@1268: */ fp@1209: void ec_voe_handler_state_write_start(ec_voe_handler_t *voe) fp@1209: { fp@1209: ec_slave_t *slave = voe->config->slave; fp@1209: uint8_t *data; fp@1209: fp@1209: if (slave->master->debug_level) { fp@1921: EC_SLAVE_DBG(slave, 0, "Writing %zu bytes of VoE data.\n", fp@1921: voe->data_size); fp@1209: ec_print_data(ecrt_voe_handler_data(voe), voe->data_size); fp@1209: } fp@1209: fp@1209: if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) { fp@1921: EC_SLAVE_ERR(slave, "Slave does not support VoE!\n"); fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1209: return; fp@1209: } fp@1507: fp@1313: data = ec_slave_mbox_prepare_send(slave, &voe->datagram, fp@1313: EC_MBOX_TYPE_VOE, EC_VOE_HEADER_SIZE + voe->data_size); fp@1313: if (IS_ERR(data)) { fp@1218: voe->state = ec_voe_handler_state_error; fp@1218: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1218: return; fp@1218: } fp@1218: fp@1218: EC_WRITE_U32(data, voe->vendor_id); fp@1218: EC_WRITE_U16(data + 4, voe->vendor_type); fp@1550: /* data already in datagram */ fp@1209: fp@1209: voe->retries = EC_FSM_RETRIES; fp@1209: voe->jiffies_start = jiffies; fp@1209: voe->state = ec_voe_handler_state_write_response; fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1268: /** Wait for the mailbox response. fp@1268: */ fp@1209: void ec_voe_handler_state_write_response(ec_voe_handler_t *voe) fp@1209: { fp@1209: ec_datagram_t *datagram = &voe->datagram; fp@1209: ec_slave_t *slave = voe->config->slave; fp@1209: fp@1209: if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--) fp@1209: return; fp@1209: fp@1209: if (datagram->state != EC_DATAGRAM_RECEIVED) { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Failed to receive VoE write request datagram: "); fp@1822: ec_datagram_print_state(datagram); fp@1209: return; fp@1209: } fp@1209: fp@1209: if (datagram->working_counter != 1) { fp@1209: if (!datagram->working_counter) { fp@1209: unsigned long diff_ms = fp@1209: (jiffies - voe->jiffies_start) * 1000 / HZ; fp@1209: if (diff_ms < EC_VOE_RESPONSE_TIMEOUT) { fp@1921: EC_SLAVE_DBG(slave, 1, "Slave did not respond to" fp@1931: " VoE write request. Retrying after %lu ms...\n", fp@1931: diff_ms); fp@1209: // no response; send request datagram again fp@1209: return; fp@1209: } fp@1209: } fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Reception of VoE write request failed: "); fp@1209: ec_datagram_print_wc_error(datagram); fp@1209: return; fp@1209: } fp@1209: fp@1921: EC_CONFIG_DBG(voe->config, 1, "VoE write request successful.\n"); fp@1209: fp@1209: voe->request_state = EC_INT_REQUEST_SUCCESS; fp@1209: voe->state = ec_voe_handler_state_end; fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1268: /** Start reading VoE data. fp@1268: */ fp@1209: void ec_voe_handler_state_read_start(ec_voe_handler_t *voe) fp@1209: { fp@1209: ec_datagram_t *datagram = &voe->datagram; fp@1209: ec_slave_t *slave = voe->config->slave; fp@1209: fp@1921: EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n"); fp@1209: fp@1209: if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) { fp@1921: EC_SLAVE_ERR(slave, "Slave does not support VoE!\n"); fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1209: return; fp@1209: } fp@1507: fp@1209: ec_slave_mbox_prepare_check(slave, datagram); // can not fail. fp@1209: fp@1209: voe->jiffies_start = jiffies; fp@1209: voe->retries = EC_FSM_RETRIES; fp@1209: voe->state = ec_voe_handler_state_read_check; fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1268: /** Check for new data in the mailbox. fp@1268: */ fp@1209: void ec_voe_handler_state_read_check(ec_voe_handler_t *voe) fp@1209: { fp@1209: ec_datagram_t *datagram = &voe->datagram; fp@1209: ec_slave_t *slave = voe->config->slave; fp@1209: fp@1209: if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--) fp@1209: return; fp@1209: fp@1209: if (datagram->state != EC_DATAGRAM_RECEIVED) { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Failed to receive VoE mailbox check datagram: "); fp@1822: ec_datagram_print_state(datagram); fp@1209: return; fp@1209: } fp@1209: fp@1209: if (datagram->working_counter != 1) { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Reception of VoE mailbox check" fp@1921: " datagram failed: "); fp@1209: ec_datagram_print_wc_error(datagram); fp@1209: return; fp@1209: } fp@1209: fp@1209: if (!ec_slave_mbox_check(datagram)) { fp@1209: unsigned long diff_ms = fp@1209: (datagram->jiffies_received - voe->jiffies_start) * 1000 / HZ; fp@1209: if (diff_ms >= EC_VOE_RESPONSE_TIMEOUT) { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Timeout while waiting for VoE data.\n"); fp@1209: return; fp@1209: } fp@1209: fp@1209: ec_slave_mbox_prepare_check(slave, datagram); // can not fail. fp@1209: voe->retries = EC_FSM_RETRIES; fp@1209: return; fp@1209: } fp@1209: fp@1209: // Fetch response fp@1209: ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. fp@1209: voe->retries = EC_FSM_RETRIES; fp@1209: voe->state = ec_voe_handler_state_read_response; fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1268: /** Read the pending mailbox data. fp@1268: */ fp@1209: void ec_voe_handler_state_read_response(ec_voe_handler_t *voe) fp@1209: { fp@1209: ec_datagram_t *datagram = &voe->datagram; fp@1209: ec_slave_t *slave = voe->config->slave; fp@1209: ec_master_t *master = voe->config->master; fp@1209: uint8_t *data, mbox_prot; fp@1209: size_t rec_size; fp@1209: fp@1209: if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--) fp@1209: return; fp@1209: fp@1209: if (datagram->state != EC_DATAGRAM_RECEIVED) { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: "); fp@1822: ec_datagram_print_state(datagram); fp@1209: return; fp@1209: } fp@1209: fp@1209: if (datagram->working_counter != 1) { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Reception of VoE read response failed: "); fp@1209: ec_datagram_print_wc_error(datagram); fp@1209: return; fp@1209: } fp@1209: fp@1313: data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); fp@1313: if (IS_ERR(data)) { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1209: return; fp@1209: } fp@1209: fp@1216: if (mbox_prot != EC_MBOX_TYPE_VOE) { fp@1209: voe->state = ec_voe_handler_state_error; fp@1209: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X" fp@1921: " as response.\n", mbox_prot); fp@1209: ec_print_data(data, rec_size); fp@1209: return; fp@1209: } fp@1209: fp@1218: if (rec_size < EC_VOE_HEADER_SIZE) { fp@1218: voe->state = ec_voe_handler_state_error; fp@1218: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Received VoE header is" fp@1921: " incomplete (%zu bytes)!\n", rec_size); fp@1218: return; fp@1218: } fp@1218: fp@1209: if (master->debug_level) { fp@1921: EC_CONFIG_DBG(voe->config, 0, "VoE data:\n"); fp@1209: ec_print_data(data, rec_size); fp@1209: } fp@1209: fp@1218: voe->data_size = rec_size - EC_VOE_HEADER_SIZE; fp@1209: voe->request_state = EC_INT_REQUEST_SUCCESS; fp@1209: voe->state = ec_voe_handler_state_end; // success fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1314: /** Start reading VoE data without sending a sync message before. fp@1314: */ fp@1314: void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *voe) fp@1314: { fp@1314: ec_datagram_t *datagram = &voe->datagram; fp@1314: ec_slave_t *slave = voe->config->slave; fp@1314: fp@1921: EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n"); fp@1314: fp@1314: if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) { fp@1921: EC_SLAVE_ERR(slave, "Slave does not support VoE!\n"); fp@1314: voe->state = ec_voe_handler_state_error; fp@1314: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1314: return; fp@1314: } fp@1507: fp@1314: ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. fp@1314: fp@1314: voe->jiffies_start = jiffies; fp@1314: voe->retries = EC_FSM_RETRIES; fp@1314: voe->state = ec_voe_handler_state_read_nosync_response; fp@1314: } fp@1314: fp@1314: /*****************************************************************************/ fp@1314: fp@1314: /** Read the pending mailbox data without sending a sync message before. This fp@1314: * might lead to an empty reponse from the client. fp@1314: */ fp@1314: void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *voe) fp@1314: { fp@1314: ec_datagram_t *datagram = &voe->datagram; fp@1314: ec_slave_t *slave = voe->config->slave; fp@1314: ec_master_t *master = voe->config->master; fp@1314: uint8_t *data, mbox_prot; fp@1314: size_t rec_size; fp@1314: fp@1314: if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--) fp@1314: return; fp@1314: fp@1314: if (datagram->state != EC_DATAGRAM_RECEIVED) { fp@1314: voe->state = ec_voe_handler_state_error; fp@1314: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: "); fp@1822: ec_datagram_print_state(datagram); fp@1314: return; fp@1314: } fp@1314: fp@1314: if (datagram->working_counter == 0) { fp@1314: voe->state = ec_voe_handler_state_error; fp@1314: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_DBG(slave, 1, "Slave did not send VoE data.\n"); fp@1314: return; fp@1314: } fp@1314: fp@1314: if (datagram->working_counter != 1) { fp@1314: voe->state = ec_voe_handler_state_error; fp@1314: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_WARN(slave, "Reception of VoE read response failed: "); fp@1314: ec_datagram_print_wc_error(datagram); fp@1314: return; fp@1314: } fp@1314: fp@1314: if (!(data = ec_slave_mbox_fetch(slave, datagram, fp@1507: &mbox_prot, &rec_size))) { fp@1314: voe->state = ec_voe_handler_state_error; fp@1314: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1314: return; fp@1314: } fp@1314: fp@1314: if (mbox_prot != EC_MBOX_TYPE_VOE) { fp@1314: voe->state = ec_voe_handler_state_error; fp@1314: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X" fp@1921: " as response.\n", mbox_prot); fp@1314: ec_print_data(data, rec_size); fp@1314: return; fp@1314: } fp@1314: fp@1314: if (rec_size < EC_VOE_HEADER_SIZE) { fp@1314: voe->state = ec_voe_handler_state_error; fp@1314: voe->request_state = EC_INT_REQUEST_FAILURE; fp@1921: EC_SLAVE_ERR(slave, "Received VoE header is" fp@1921: " incomplete (%zu bytes)!\n", rec_size); fp@1314: return; fp@1314: } fp@1314: fp@1314: if (master->debug_level) { fp@1921: EC_CONFIG_DBG(voe->config, 1, "VoE data:\n"); fp@1314: ec_print_data(data, rec_size); fp@1314: } fp@1314: fp@1314: voe->data_size = rec_size - EC_VOE_HEADER_SIZE; fp@1314: voe->request_state = EC_INT_REQUEST_SUCCESS; fp@1314: voe->state = ec_voe_handler_state_end; // success fp@1314: } fp@1314: fp@1314: /*****************************************************************************/ fp@1314: fp@1268: /** Successful termination state function. fp@1268: */ fp@1209: void ec_voe_handler_state_end(ec_voe_handler_t *voe) fp@1209: { fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1268: /** Failure termination state function. fp@1268: */ fp@1209: void ec_voe_handler_state_error(ec_voe_handler_t *voe) fp@1209: { fp@1209: } fp@1209: fp@1209: /*****************************************************************************/ fp@1209: fp@1209: /** \cond */ fp@1209: fp@1226: EXPORT_SYMBOL(ecrt_voe_handler_send_header); fp@1226: EXPORT_SYMBOL(ecrt_voe_handler_received_header); fp@1209: EXPORT_SYMBOL(ecrt_voe_handler_data); fp@1209: EXPORT_SYMBOL(ecrt_voe_handler_data_size); fp@1209: EXPORT_SYMBOL(ecrt_voe_handler_read); fp@1209: EXPORT_SYMBOL(ecrt_voe_handler_write); fp@1209: EXPORT_SYMBOL(ecrt_voe_handler_execute); fp@1209: fp@1209: /** \endcond */ fp@1209: fp@1209: /*****************************************************************************/