fp@1831: /****************************************************************************** fp@1831: * fp@1831: * $Id$ fp@1831: * fp@1831: * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH fp@1831: * fp@1831: * This file is part of the IgH EtherCAT Master. fp@1831: * fp@1831: * The IgH EtherCAT Master is free software; you can redistribute it and/or fp@1831: * modify it under the terms of the GNU General Public License version 2, as fp@1831: * published by the Free Software Foundation. fp@1831: * fp@1831: * The IgH EtherCAT Master is distributed in the hope that it will be useful, fp@1831: * but WITHOUT ANY WARRANTY; without even the implied warranty of fp@1831: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General fp@1831: * Public License for more details. fp@1831: * fp@1831: * You should have received a copy of the GNU General Public License along fp@1831: * with the IgH EtherCAT Master; if not, write to the Free Software fp@1831: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA fp@1831: * fp@1831: * --- fp@1831: * fp@1831: * The license mentioned above concerns the source code only. Using the fp@1831: * EtherCAT technology and brand is only permitted in compliance with the fp@1831: * industrial property and similar rights of Beckhoff Automation GmbH. fp@1831: * fp@1831: *****************************************************************************/ fp@1831: fp@1831: /** \file fp@1831: * Sercos-over-EtherCAT request functions. fp@1831: */ fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: #include fp@1831: #include fp@1831: fp@1831: #include "soe_request.h" fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: /** Default timeout in ms to wait for SoE responses. fp@1831: */ fp@1831: #define EC_SOE_REQUEST_RESPONSE_TIMEOUT 1000 fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: void ec_soe_request_clear_data(ec_soe_request_t *); fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: /** SoE request constructor. fp@1831: */ fp@1831: void ec_soe_request_init( fp@1831: ec_soe_request_t *req /**< SoE request. */ fp@1831: ) fp@1831: { fp@1831: req->data = NULL; fp@1831: req->mem_size = 0; fp@1831: req->data_size = 0; fp@1831: req->dir = EC_DIR_INVALID; fp@1831: req->state = EC_INT_REQUEST_INIT; fp@1831: //req->jiffies_start = 0U; fp@1831: req->jiffies_sent = 0U; fp@1831: req->error_code = 0x0000; fp@1831: } fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: /** SoE request destructor. fp@1831: */ fp@1831: void ec_soe_request_clear( fp@1831: ec_soe_request_t *req /**< SoE request. */ fp@1831: ) fp@1831: { fp@1831: ec_soe_request_clear_data(req); fp@1831: } fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: /** Set IDN. fp@1831: */ fp@1831: void ec_soe_request_set_idn( fp@1831: ec_soe_request_t *req, /**< SoE request. */ fp@1831: uint16_t idn /** IDN. */ fp@1831: ) fp@1831: { fp@1831: req->idn = idn; fp@1831: } fp@1831: fp@1831: #if 0 fp@1831: /*****************************************************************************/ fp@1831: fp@1831: /** Copy another SoE request. fp@1831: * fp@1831: * \attention Only the index subindex and data are copied. fp@1831: */ fp@1831: int ec_soe_request_copy( fp@1831: ec_soe_request_t *req, /**< SoE request. */ fp@1831: const ec_soe_request_t *other /**< Other SoE request to copy from. */ fp@1831: ) fp@1831: { fp@1831: req->complete_access = other->complete_access; fp@1831: req->index = other->index; fp@1831: req->subindex = other->subindex; fp@1831: return ec_soe_request_copy_data(req, other->data, other->data_size); fp@1831: } fp@1831: #endif fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: /** Free allocated memory. fp@1831: */ fp@1831: void ec_soe_request_clear_data( fp@1831: ec_soe_request_t *req /**< SoE request. */ fp@1831: ) fp@1831: { fp@1831: if (req->data) { fp@1831: kfree(req->data); fp@1831: req->data = NULL; fp@1831: } fp@1831: fp@1831: req->mem_size = 0; fp@1831: req->data_size = 0; fp@1831: } fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: /** Pre-allocates the data memory. fp@1831: * fp@1831: * If the \a mem_size is already bigger than \a size, nothing is done. fp@1831: * fp@1831: * \return 0 on success, otherwise -ENOMEM. fp@1831: */ fp@1831: int ec_soe_request_alloc( fp@1831: ec_soe_request_t *req, /**< SoE request. */ fp@1831: size_t size /**< Data size to allocate. */ fp@1831: ) fp@1831: { fp@1831: if (size <= req->mem_size) fp@1831: return 0; fp@1831: fp@1831: ec_soe_request_clear_data(req); fp@1831: fp@1831: if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) { fp@1831: EC_ERR("Failed to allocate %zu bytes of SoE memory.\n", size); fp@1831: return -ENOMEM; fp@1831: } fp@1831: fp@1831: req->mem_size = size; fp@1831: req->data_size = 0; fp@1831: return 0; fp@1831: } fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: /** Copies SoE data from an external source. fp@1831: * fp@1831: * If the \a mem_size is to small, new memory is allocated. fp@1831: * fp@1831: * \retval 0 Success. fp@1831: * \retval <0 Error code. fp@1831: */ fp@1831: int ec_soe_request_copy_data( fp@1831: ec_soe_request_t *req, /**< SoE request. */ fp@1831: const uint8_t *source, /**< Source data. */ fp@1831: size_t size /**< Number of bytes in \a source. */ fp@1831: ) fp@1831: { fp@1831: int ret = ec_soe_request_alloc(req, size); fp@1831: if (ret < 0) fp@1831: return ret; fp@1831: fp@1831: memcpy(req->data, source, size); fp@1831: req->data_size = size; fp@1831: return 0; fp@1831: } fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: void ec_soe_request_read(ec_soe_request_t *req) fp@1831: { fp@1831: req->dir = EC_DIR_INPUT; fp@1831: req->state = EC_INT_REQUEST_QUEUED; fp@1831: req->error_code = 0x0000; fp@1831: } fp@1831: fp@1831: /*****************************************************************************/ fp@1831: fp@1831: void ec_soe_request_write(ec_soe_request_t *req) fp@1831: { fp@1831: req->dir = EC_DIR_OUTPUT; fp@1831: req->state = EC_INT_REQUEST_QUEUED; fp@1831: req->error_code = 0x0000; fp@1831: } fp@1831: fp@1831: /*****************************************************************************/