00001 /****************************************************************************** 00002 * 00003 * $Id$ 00004 * 00005 * Copyright (C) 2012 Florian Pose, Ingenieurgemeinschaft IgH 00006 * 00007 * This file is part of the IgH EtherCAT Master. 00008 * 00009 * The IgH EtherCAT Master is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License version 2, as 00011 * published by the Free Software Foundation. 00012 * 00013 * The IgH EtherCAT Master is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 00016 * Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with the IgH EtherCAT Master; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 * --- 00023 * 00024 * The license mentioned above concerns the source code only. Using the 00025 * EtherCAT technology and brand is only permitted in compliance with the 00026 * industrial property and similar rights of Beckhoff Automation GmbH. 00027 * 00028 * vim: expandtab 00029 * 00030 *****************************************************************************/ 00031 00036 /*****************************************************************************/ 00037 00038 #include <linux/slab.h> 00039 00040 #include "coe_emerg_ring.h" 00041 00042 /*****************************************************************************/ 00043 00046 void ec_coe_emerg_ring_init( 00047 ec_coe_emerg_ring_t *ring, 00048 ec_slave_config_t *sc 00049 ) 00050 { 00051 ring->sc = sc; 00052 ring->msgs = NULL; 00053 ring->size = 0; 00054 ring->read_index = 0; 00055 ring->write_index = 0; 00056 ring->overruns = 0; 00057 } 00058 00059 /*****************************************************************************/ 00060 00063 void ec_coe_emerg_ring_clear( 00064 ec_coe_emerg_ring_t *ring 00065 ) 00066 { 00067 if (ring->msgs) { 00068 kfree(ring->msgs); 00069 } 00070 } 00071 00072 /*****************************************************************************/ 00073 00078 int ec_coe_emerg_ring_size( 00079 ec_coe_emerg_ring_t *ring, 00080 size_t size 00081 ) 00082 { 00083 ring->size = 0; 00084 00085 if (size < 0) { 00086 size = 0; 00087 } 00088 00089 ring->read_index = ring->write_index = 0; 00090 00091 if (ring->msgs) { 00092 kfree(ring->msgs); 00093 } 00094 ring->msgs = NULL; 00095 00096 if (size == 0) { 00097 return 0; 00098 } 00099 00100 ring->msgs = kmalloc(sizeof(ec_coe_emerg_msg_t) * (size + 1), GFP_KERNEL); 00101 if (!ring->msgs) { 00102 return -ENOMEM; 00103 } 00104 00105 ring->size = size; 00106 return 0; 00107 } 00108 00109 /*****************************************************************************/ 00110 00113 void ec_coe_emerg_ring_push( 00114 ec_coe_emerg_ring_t *ring, 00115 const u8 *msg 00116 ) 00117 { 00118 if (!ring->size || 00119 (ring->write_index + 1) % (ring->size + 1) == ring->read_index) { 00120 ring->overruns++; 00121 return; 00122 } 00123 00124 memcpy(ring->msgs[ring->write_index].data, msg, 00125 EC_COE_EMERGENCY_MSG_SIZE); 00126 ring->write_index = (ring->write_index + 1) % (ring->size + 1); 00127 } 00128 00129 /*****************************************************************************/ 00130 00135 int ec_coe_emerg_ring_pop( 00136 ec_coe_emerg_ring_t *ring, 00137 u8 *msg 00138 ) 00139 { 00140 if (ring->read_index == ring->write_index) { 00141 return -ENOENT; 00142 } 00143 00144 memcpy(msg, ring->msgs[ring->read_index].data, EC_COE_EMERGENCY_MSG_SIZE); 00145 ring->read_index = (ring->read_index + 1) % (ring->size + 1); 00146 return 0; 00147 } 00148 00149 /*****************************************************************************/ 00150 00155 int ec_coe_emerg_ring_clear_ring( 00156 ec_coe_emerg_ring_t *ring 00157 ) 00158 { 00159 ring->read_index = ring->write_index; 00160 ring->overruns = 0; 00161 return 0; 00162 } 00163 00164 /*****************************************************************************/ 00165 00170 int ec_coe_emerg_ring_overruns( 00171 ec_coe_emerg_ring_t *ring 00172 ) 00173 { 00174 return ring->overruns; 00175 } 00176 00177 /*****************************************************************************/
1.5.6