master/foe_request.c
changeset 1335 09c6fce1ae45
child 1336 e27b37e80a99
equal deleted inserted replaced
1334:da3d22a27500 1335:09c6fce1ae45
       
     1 /******************************************************************************
       
     2  *
       
     3  *  $Id$
       
     4  *
       
     5  *  Copyright (C) 2008  Olav Zarges, imc Meßsysteme GmbH
       
     6  *
       
     7  *  This file is part of the IgH EtherCAT Master.
       
     8  *
       
     9  *  The IgH EtherCAT Master is free software; you can redistribute it
       
    10  *  and/or modify it under the terms of the GNU General Public License
       
    11  *  as published by the Free Software Foundation; either version 2 of the
       
    12  *  License, or (at your option) any later version.
       
    13  *
       
    14  *  The IgH EtherCAT Master is distributed in the hope that it will be
       
    15  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    17  *  GNU General Public License for more details.
       
    18  *
       
    19  *  You should have received a copy of the GNU General Public License
       
    20  *  along with the IgH EtherCAT Master; if not, write to the Free Software
       
    21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    22  *
       
    23  *  The right to use EtherCAT Technology is granted and comes free of
       
    24  *  charge under condition of compatibility of product made by
       
    25  *  Licensee. People intending to distribute/sell products based on the
       
    26  *  code, have to sign an agreement to guarantee that products using
       
    27  *  software based on IgH EtherCAT master stay compatible with the actual
       
    28  *  EtherCAT specification (which are released themselves as an open
       
    29  *  standard) as the (only) precondition to have the right to use EtherCAT
       
    30  *  Technology, IP and trade marks.
       
    31  *
       
    32  *****************************************************************************/
       
    33 
       
    34 /** \file
       
    35  * File-over-EtherCAT request functions.
       
    36  */
       
    37 
       
    38 /*****************************************************************************/
       
    39 
       
    40 #include <linux/module.h>
       
    41 #include <linux/jiffies.h>
       
    42 
       
    43 #include "foe_request.h"
       
    44 
       
    45 /*****************************************************************************/
       
    46 
       
    47 /** Default timeout in ms to wait for FoE transfer responses.
       
    48  */
       
    49 #define EC_FOE_REQUEST_RESPONSE_TIMEOUT 3000
       
    50 
       
    51 /*****************************************************************************/
       
    52 
       
    53 void ec_foe_request_clear_data(ec_foe_request_t *);
       
    54 
       
    55 /*****************************************************************************/
       
    56 
       
    57 /** FoE request constructor.
       
    58  */
       
    59 void ec_foe_request_init(
       
    60         ec_foe_request_t *req, /**< FoE request. */
       
    61         uint8_t* file_name /** filename */)
       
    62 {
       
    63     req->buffer = NULL;
       
    64     req->file_name = file_name;
       
    65     req->buffer_size = 0;
       
    66     req->data_size = 0;
       
    67     req->dir = EC_DIR_INVALID;
       
    68     req->issue_timeout = 0; // no timeout
       
    69     req->response_timeout = EC_FOE_REQUEST_RESPONSE_TIMEOUT;
       
    70     req->state = EC_INT_REQUEST_INIT;
       
    71     req->abort_code = 0x00000000;
       
    72 }
       
    73 
       
    74 /*****************************************************************************/
       
    75 
       
    76 /** FoE request destructor.
       
    77  */
       
    78 void ec_foe_request_clear(
       
    79         ec_foe_request_t *req /**< FoE request. */
       
    80         )
       
    81 {
       
    82     ec_foe_request_clear_data(req);
       
    83 }
       
    84 
       
    85 /*****************************************************************************/
       
    86 
       
    87 /** FoE request destructor.
       
    88  */
       
    89 void ec_foe_request_clear_data(
       
    90         ec_foe_request_t *req /**< FoE request. */
       
    91         )
       
    92 {
       
    93     if (req->buffer) {
       
    94         kfree(req->buffer);
       
    95         req->buffer = NULL;
       
    96     }
       
    97 
       
    98     req->buffer_size = 0;
       
    99     req->data_size = 0;
       
   100 }
       
   101 
       
   102 /*****************************************************************************/
       
   103 
       
   104 /** Pre-allocates the data memory.
       
   105  *
       
   106  * If the \a buffer_size is already bigger than \a size, nothing is done.
       
   107  */
       
   108 int ec_foe_request_alloc(
       
   109         ec_foe_request_t *req, /**< FoE request. */
       
   110         size_t size /**< Data size to allocate. */
       
   111         )
       
   112 {
       
   113     if (size <= req->buffer_size)
       
   114         return 0;
       
   115 
       
   116     ec_foe_request_clear_data(req);
       
   117 
       
   118     if (!(req->buffer = (uint8_t *) kmalloc(size, GFP_KERNEL))) {
       
   119         EC_ERR("Failed to allocate %u bytes of FoE memory.\n", size);
       
   120         return -1;
       
   121     }
       
   122 
       
   123     req->buffer_size = size;
       
   124     req->data_size = 0;
       
   125     return 0;
       
   126 }
       
   127 
       
   128 /*****************************************************************************/
       
   129 
       
   130 /** Copies FoE data from an external source.
       
   131  *
       
   132  * If the \a buffer_size is to small, new memory is allocated.
       
   133  */
       
   134 int ec_foe_request_copy_data(
       
   135         ec_foe_request_t *req, /**< FoE request. */
       
   136         const uint8_t *source, /**< Source data. */
       
   137         size_t size /**< Number of bytes in \a source. */
       
   138         )
       
   139 {
       
   140     if (ec_foe_request_alloc(req, size))
       
   141         return -1;
       
   142 
       
   143     memcpy(req->buffer, source, size);
       
   144     req->data_size = size;
       
   145     return 0;
       
   146 }
       
   147 
       
   148 /*****************************************************************************/
       
   149 
       
   150 /** Checks, if the timeout was exceeded.
       
   151  *
       
   152  * \return non-zero if the timeout was exceeded, else zero.
       
   153  */
       
   154 int ec_foe_request_timed_out(const ec_foe_request_t *req /**< FoE request. */)
       
   155 {
       
   156     return req->issue_timeout
       
   157         && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000;
       
   158 }
       
   159 
       
   160 /*****************************************************************************/
       
   161 
       
   162 void ec_foe_request_timeout(ec_foe_request_t *req, uint32_t timeout)
       
   163 {
       
   164     req->issue_timeout = timeout;
       
   165 }
       
   166 
       
   167 /*****************************************************************************/
       
   168 
       
   169 uint8_t *ec_foe_request_data(ec_foe_request_t *req)
       
   170 {
       
   171     return req->buffer;
       
   172 }
       
   173 
       
   174 /*****************************************************************************/
       
   175 
       
   176 size_t ec_foe_request_data_size(const ec_foe_request_t *req)
       
   177 {
       
   178     return req->data_size;
       
   179 }
       
   180 
       
   181 /*****************************************************************************/
       
   182 
       
   183 void ec_foe_request_read(ec_foe_request_t *req)
       
   184 {
       
   185     req->dir = EC_DIR_INPUT;
       
   186     req->state = EC_INT_REQUEST_QUEUED;
       
   187     req->abort_code = 0x00000000;
       
   188     req->jiffies_start = jiffies;
       
   189 }
       
   190 
       
   191 /*****************************************************************************/
       
   192 
       
   193 void ec_foe_request_write(ec_foe_request_t *req)
       
   194 {
       
   195     req->dir = EC_DIR_OUTPUT;
       
   196     req->state = EC_INT_REQUEST_QUEUED;
       
   197     req->abort_code = 0x00000000;
       
   198     req->jiffies_start = jiffies;
       
   199 }
       
   200 
       
   201 /*****************************************************************************/