master/fsm_foe.c
changeset 2589 2b9c78543663
parent 2259 5538f60ea32c
child 2591 23b360e4a530
equal deleted inserted replaced
2415:af21f0bdc7c9 2589:2b9c78543663
     1 /******************************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  *  $Id$
     3  *  $Id$
     4  *
     4  *
     5  *  Copyright (C) 2008  Olav Zarges, imc Messsysteme GmbH
     5  *  Copyright (C) 2008  Olav Zarges, imc Messsysteme GmbH
       
     6  *                2013  Florian Pose <fp@igh-essen.com>
     6  *
     7  *
     7  *  This file is part of the IgH EtherCAT Master.
     8  *  This file is part of the IgH EtherCAT Master.
     8  *
     9  *
     9  *  The IgH EtherCAT Master is free software; you can redistribute it and/or
    10  *  The IgH EtherCAT Master is free software; you can redistribute it and/or
    10  *  modify it under the terms of the GNU General Public License version 2, as
    11  *  modify it under the terms of the GNU General Public License version 2, as
    25  *  EtherCAT technology and brand is only permitted in compliance with the
    26  *  EtherCAT technology and brand is only permitted in compliance with the
    26  *  industrial property and similar rights of Beckhoff Automation GmbH.
    27  *  industrial property and similar rights of Beckhoff Automation GmbH.
    27  *
    28  *
    28  *****************************************************************************/
    29  *****************************************************************************/
    29 
    30 
    30 /**
    31 /** \file
    31    \file
    32  * EtherCAT FoE state machines.
    32    EtherCAT FoE state machines.
    33  */
    33 */
       
    34 
    34 
    35 /*****************************************************************************/
    35 /*****************************************************************************/
    36 
    36 
    37 #include "globals.h"
    37 #include "globals.h"
    38 #include "master.h"
    38 #include "master.h"
    72     EC_FOE_OPCODE_BUSY = 6  /**< Busy. */
    72     EC_FOE_OPCODE_BUSY = 6  /**< Busy. */
    73 } ec_foe_opcode_t;
    73 } ec_foe_opcode_t;
    74 
    74 
    75 /*****************************************************************************/
    75 /*****************************************************************************/
    76 
    76 
    77 int ec_foe_prepare_data_send(ec_fsm_foe_t *);
    77 int ec_foe_prepare_data_send(ec_fsm_foe_t *, ec_datagram_t *);
    78 int ec_foe_prepare_wrq_send(ec_fsm_foe_t *);
    78 int ec_foe_prepare_wrq_send(ec_fsm_foe_t *, ec_datagram_t *);
    79 int ec_foe_prepare_rrq_send(ec_fsm_foe_t *);
    79 int ec_foe_prepare_rrq_send(ec_fsm_foe_t *, ec_datagram_t *);
    80 int ec_foe_prepare_send_ack(ec_fsm_foe_t *);
    80 int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *);
    81 
    81 
    82 void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
    82 void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
    83 void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t);
    83 void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t);
    84 
    84 
    85 void ec_fsm_foe_write(ec_fsm_foe_t *);
    85 void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *);
    86 void ec_fsm_foe_read(ec_fsm_foe_t *);
    86 void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *);
    87 void ec_fsm_foe_end(ec_fsm_foe_t *);
    87 
    88 void ec_fsm_foe_error(ec_fsm_foe_t *);
    88 void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *, ec_datagram_t *);
    89 
    89 void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *);
    90 void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *);
    90 
    91 void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *);
    91 void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *);
    92 
    92 void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *);
    93 void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *);
    93 
    94 void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *);
    94 void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *);
    95 
    95 
    96 void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *);
    96 void ec_fsm_foe_state_data_check(ec_fsm_foe_t *, ec_datagram_t *);
    97 
    97 void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *);
    98 void ec_fsm_foe_state_data_check(ec_fsm_foe_t *);
    98 void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *);
    99 void ec_fsm_foe_state_data_read(ec_fsm_foe_t *);
    99 
   100 void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *);
   100 void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *);
   101 
   101 void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *);
   102 void ec_fsm_foe_write_start(ec_fsm_foe_t *);
       
   103 void ec_fsm_foe_read_start(ec_fsm_foe_t *);
       
   104 
   102 
   105 /*****************************************************************************/
   103 /*****************************************************************************/
   106 
   104 
   107 /** Constructor.
   105 /** Constructor.
   108  */
   106  */
   109 void ec_fsm_foe_init(ec_fsm_foe_t *fsm, /**< finite state machine */
   107 void ec_fsm_foe_init(
   110                      ec_mailbox_t *mbox /**< mailbox */
   108         ec_fsm_foe_t *fsm /**< finite state machine */
   111                      )
   109         )
   112 {
   110 {
   113     fsm->state = NULL;
   111     fsm->state = NULL;
   114     fsm->mbox  = mbox;
   112     fsm->datagram = NULL;
   115 }
   113 }
   116 
   114 
   117 /*****************************************************************************/
   115 /*****************************************************************************/
   118 
   116 
   119 /** Destructor.
   117 /** Destructor.
   123 }
   121 }
   124 
   122 
   125 /*****************************************************************************/
   123 /*****************************************************************************/
   126 
   124 
   127 /** Executes the current state of the state machine.
   125 /** Executes the current state of the state machine.
   128  * \return false, if state machine has terminated
   126  *
   129  */
   127  * \return 1, if the datagram was used, else 0.
   130 int ec_fsm_foe_exec(ec_fsm_foe_t *fsm /**< finite state machine */)
   128  */
   131 {
   129 int ec_fsm_foe_exec(
   132     fsm->state(fsm);
   130         ec_fsm_foe_t *fsm, /**< finite state machine */
   133 
   131         ec_datagram_t *datagram /**< Datagram to use. */
   134     return fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error;
   132         )
       
   133 {
       
   134     int datagram_used = 0;
       
   135 
       
   136     if (fsm->datagram &&
       
   137             (fsm->datagram->state == EC_DATAGRAM_INIT ||
       
   138              fsm->datagram->state == EC_DATAGRAM_QUEUED ||
       
   139              fsm->datagram->state == EC_DATAGRAM_SENT)) {
       
   140         // datagram not received yet
       
   141         return datagram_used;
       
   142     }
       
   143 
       
   144     fsm->state(fsm, datagram);
       
   145 
       
   146     datagram_used =
       
   147         fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error;
       
   148 
       
   149     if (datagram_used) {
       
   150         fsm->datagram = datagram;
       
   151     } else {
       
   152         fsm->datagram = NULL;
       
   153     }
       
   154 
       
   155     return datagram_used;
   135 }
   156 }
   136 
   157 
   137 /*****************************************************************************/
   158 /*****************************************************************************/
   138 
   159 
   139 /** Returns, if the state machine terminated with success.
   160 /** Returns, if the state machine terminated with success.
   140  * \return non-zero if successful.
   161  * \return non-zero if successful.
   141  */
   162  */
   142 int ec_fsm_foe_success(ec_fsm_foe_t *fsm /**< Finite state machine */)
   163 int ec_fsm_foe_success(const ec_fsm_foe_t *fsm /**< Finite state machine */)
   143 {
   164 {
   144     return fsm->state == ec_fsm_foe_end;
   165     return fsm->state == ec_fsm_foe_end;
   145 }
   166 }
   146 
   167 
   147 /*****************************************************************************/
   168 /*****************************************************************************/
   154         ec_foe_request_t *request /**< Sdo request. */
   175         ec_foe_request_t *request /**< Sdo request. */
   155         )
   176         )
   156 {
   177 {
   157     fsm->slave = slave;
   178     fsm->slave = slave;
   158     fsm->request = request;
   179     fsm->request = request;
       
   180 
   159     if (request->dir == EC_DIR_OUTPUT) {
   181     if (request->dir == EC_DIR_OUTPUT) {
   160         fsm->state = ec_fsm_foe_write;
   182         fsm->tx_buffer = fsm->request->buffer;
       
   183         fsm->tx_buffer_size = fsm->request->data_size;
       
   184         fsm->tx_buffer_offset = 0;
       
   185 
       
   186         fsm->tx_filename = fsm->request->file_name;
       
   187         fsm->tx_filename_len = strlen(fsm->tx_filename);
       
   188 
       
   189         fsm->state = ec_fsm_foe_write_start;
   161     }
   190     }
   162     else {
   191     else {
   163         fsm->state = ec_fsm_foe_read;
   192         fsm->rx_buffer = fsm->request->buffer;
       
   193         fsm->rx_buffer_size = fsm->request->buffer_size;
       
   194 
       
   195         fsm->rx_filename = fsm->request->file_name;
       
   196         fsm->rx_filename_len = strlen(fsm->rx_filename);
       
   197 
       
   198         fsm->state = ec_fsm_foe_read_start;
   164     }
   199     }
   165 }
   200 }
   166 
   201 
   167 /*****************************************************************************/
   202 /*****************************************************************************/
   168 
   203 
   169 /** State: ERROR.
   204 /** State: ERROR.
   170  */
   205  */
   171 void ec_fsm_foe_error(ec_fsm_foe_t *fsm /**< finite state machine */)
   206 void ec_fsm_foe_error(
   172 {
   207         ec_fsm_foe_t *fsm, /**< finite state machine */
   173 #ifdef DEBUG_FOE
   208         ec_datagram_t *datagram /**< Datagram to use. */
   174     printk("ec_fsm_foe_error()\n");
   209         )
       
   210 {
       
   211 #ifdef DEBUG_FOE
       
   212     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   175 #endif
   213 #endif
   176 }
   214 }
   177 
   215 
   178 /*****************************************************************************/
   216 /*****************************************************************************/
   179 
   217 
   180 /** State: END.
   218 /** State: END.
   181  */
   219  */
   182 void ec_fsm_foe_end(ec_fsm_foe_t *fsm /**< finite state machine */)
   220 void ec_fsm_foe_end(
   183 {
   221         ec_fsm_foe_t *fsm, /**< finite state machine */
   184 #ifdef DEBUG_FOE
   222         ec_datagram_t *datagram /**< Datagram to use. */
   185     printk("ec_fsm_foe_end\n");
   223         )
       
   224 {
       
   225 #ifdef DEBUG_FOE
       
   226     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   186 #endif
   227 #endif
   187 }
   228 }
   188 
   229 
   189 /*****************************************************************************/
   230 /*****************************************************************************/
   190 
   231 
   191 /** Sends a file or the next fragment.
   232 /** Sends a file or the next fragment.
   192  */
   233  *
   193 int ec_foe_prepare_data_send(ec_fsm_foe_t *fsm)
   234  * \return Zero on success, otherwise a negative error code.
       
   235  */
       
   236 int ec_foe_prepare_data_send(
       
   237         ec_fsm_foe_t *fsm, /**< Finite state machine. */
       
   238         ec_datagram_t *datagram /**< Datagram to use. */
       
   239         )
   194 {
   240 {
   195     size_t remaining_size, current_size;
   241     size_t remaining_size, current_size;
   196     uint8_t *data;
   242     uint8_t *data;
   197 
   243 
   198     remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;
   244     remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;
   205         current_size = fsm->slave->configured_tx_mailbox_size
   251         current_size = fsm->slave->configured_tx_mailbox_size
   206             - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE;
   252             - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE;
   207     }
   253     }
   208 
   254 
   209     data = ec_slave_mbox_prepare_send(fsm->slave,
   255     data = ec_slave_mbox_prepare_send(fsm->slave,
   210             fsm->mbox, EC_MBOX_TYPE_FILEACCESS,
   256             datagram, EC_MBOX_TYPE_FILEACCESS,
   211             current_size + EC_FOE_HEADER_SIZE);
   257             current_size + EC_FOE_HEADER_SIZE);
   212     if (IS_ERR(data))
   258     if (IS_ERR(data)) {
   213         return -1;
   259         return -1;
   214 
   260     }
   215     EC_WRITE_U8 ( data, EC_FOE_OPCODE_DATA );    // OpCode = DataBlock req.
   261 
   216     EC_WRITE_U32( data + 2, fsm->tx_packet_no ); // PacketNo, Password
   262     EC_WRITE_U16(data, EC_FOE_OPCODE_DATA);    // OpCode = DataBlock req.
       
   263     EC_WRITE_U32(data + 2, fsm->tx_packet_no); // PacketNo, Password
   217 
   264 
   218     memcpy(data + EC_FOE_HEADER_SIZE,
   265     memcpy(data + EC_FOE_HEADER_SIZE,
   219             fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
   266             fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
   220     fsm->tx_current_size = current_size;
   267     fsm->tx_current_size = current_size;
   221 
   268 
   223 }
   270 }
   224 
   271 
   225 /*****************************************************************************/
   272 /*****************************************************************************/
   226 
   273 
   227 /** Prepare a write request (WRQ) with filename
   274 /** Prepare a write request (WRQ) with filename
   228  */
   275  *
   229 int ec_foe_prepare_wrq_send(ec_fsm_foe_t *fsm)
   276  * \return Zero on success, otherwise a negative error code.
       
   277  */
       
   278 int ec_foe_prepare_wrq_send(
       
   279         ec_fsm_foe_t *fsm, /**< Finite state machine. */
       
   280         ec_datagram_t *datagram /**< Datagram to use. */
       
   281         )
   230 {
   282 {
   231     size_t current_size;
   283     size_t current_size;
   232     uint8_t *data;
   284     uint8_t *data;
   233 
   285 
   234     fsm->tx_buffer_offset = 0;
   286     fsm->tx_buffer_offset = 0;
   236     fsm->tx_packet_no = 0;
   288     fsm->tx_packet_no = 0;
   237     fsm->tx_last_packet = 0;
   289     fsm->tx_last_packet = 0;
   238 
   290 
   239     current_size = fsm->tx_filename_len;
   291     current_size = fsm->tx_filename_len;
   240 
   292 
   241     data = ec_slave_mbox_prepare_send(fsm->slave, fsm->mbox,
   293     data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
   242             EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
   294             EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
   243     if (IS_ERR(data))
   295     if (IS_ERR(data)) {
   244         return -1;
   296         return -1;
       
   297     }
   245 
   298 
   246     EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
   299     EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
   247     EC_WRITE_U32( data + 2, fsm->tx_packet_no );
   300     EC_WRITE_U32( data + 2, fsm->tx_packet_no );
   248 
   301 
   249     memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);
   302     memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);
   251     return 0;
   304     return 0;
   252 }
   305 }
   253 
   306 
   254 /*****************************************************************************/
   307 /*****************************************************************************/
   255 
   308 
   256 /** Start a write operation.
       
   257  */
       
   258 void ec_fsm_foe_write(
       
   259         ec_fsm_foe_t *fsm /**< FoE statemachine. */
       
   260         )
       
   261 {
       
   262     fsm->tx_buffer = fsm->request->buffer;
       
   263     fsm->tx_buffer_size = fsm->request->data_size;
       
   264     fsm->tx_buffer_offset = 0;
       
   265 
       
   266     fsm->tx_filename = fsm->request->file_name;
       
   267     fsm->tx_filename_len = strlen(fsm->tx_filename);
       
   268 
       
   269     fsm->state = ec_fsm_foe_write_start;
       
   270 }
       
   271 
       
   272 /*****************************************************************************/
       
   273 
       
   274 /** Initializes the FoE write state machine.
   309 /** Initializes the FoE write state machine.
   275  */
   310  */
   276 void ec_fsm_foe_write_start(ec_fsm_foe_t *fsm /**< finite state machine */)
   311 void ec_fsm_foe_write_start(
       
   312         ec_fsm_foe_t *fsm, /**< finite state machine */
       
   313         ec_datagram_t *datagram /**< Datagram to use. */
       
   314         )
   277 {
   315 {
   278     ec_slave_t *slave = fsm->slave;
   316     ec_slave_t *slave = fsm->slave;
   279 
   317 
   280     fsm->tx_buffer_offset = 0;
   318     fsm->tx_buffer_offset = 0;
   281     fsm->tx_current_size = 0;
   319     fsm->tx_current_size = 0;
   282     fsm->tx_packet_no = 0;
   320     fsm->tx_packet_no = 0;
   283     fsm->tx_last_packet = 0;
   321     fsm->tx_last_packet = 0;
   284 
   322 
   285 #ifdef DEBUG_FOE
   323 #ifdef DEBUG_FOE
   286     printk("ec_fsm_foe_write_start()\n");
   324     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   287 #endif
   325 #endif
   288 
   326 
   289     if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
   327     if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
   290         ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
   328         ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
   291         EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
   329         EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
   292         return;
   330         return;
   293     }
   331     }
   294 
   332 
   295     if (ec_foe_prepare_wrq_send(fsm)) {
   333     if (ec_foe_prepare_wrq_send(fsm, datagram)) {
   296         ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   334         ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   297         return;
   335         return;
   298     }
   336     }
   299 
   337 
   300     fsm->state = ec_fsm_foe_state_wrq_sent;
   338     fsm->state = ec_fsm_foe_state_wrq_sent;
   303 /*****************************************************************************/
   341 /*****************************************************************************/
   304 
   342 
   305 /** Check for acknowledge.
   343 /** Check for acknowledge.
   306  */
   344  */
   307 void ec_fsm_foe_state_ack_check(
   345 void ec_fsm_foe_state_ack_check(
   308         ec_fsm_foe_t *fsm /**< FoE statemachine. */
   346         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
   309         )
   347         ec_datagram_t *datagram /**< Datagram to use. */
   310 {
   348         )
   311     ec_mailbox_t *mbox = fsm->mbox;
   349 {
   312     ec_datagram_t *datagram = mbox->datagram;
       
   313     ec_slave_t *slave = fsm->slave;
   350     ec_slave_t *slave = fsm->slave;
   314 
   351 
   315 #ifdef DEBUG_FOE
   352 #ifdef DEBUG_FOE
   316     printk("ec_fsm_foe_ack_check()\n");
   353     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   317 #endif
   354 #endif
   318 
   355 
   319     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   356     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   320         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   357         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   321         EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: ");
   358         EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: ");
   322         ec_datagram_print_state(datagram);
   359         ec_datagram_print_state(fsm->datagram);
   323         return;
   360         return;
   324     }
   361     }
   325 
   362 
   326     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   363     if (fsm->datagram->working_counter != 1) {
   327         // slave did not put anything in the mailbox yet
       
   328         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   364         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   329         EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram"
   365         EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram"
   330                 " failed: ");
   366                 " failed: ");
   331         ec_datagram_print_wc_error(datagram);
   367         ec_datagram_print_wc_error(fsm->datagram);
   332         return;
   368         return;
   333     }
   369     }
   334 
   370 
   335     if (!ec_slave_mbox_check(mbox)) {
   371     if (!ec_slave_mbox_check(fsm->datagram)) {
   336         unsigned long diff_ms =
   372         // slave did not put anything in the mailbox yet
   337             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
   373         unsigned long diff_ms = (fsm->datagram->jiffies_received -
       
   374                 fsm->jiffies_start) * 1000 / HZ;
   338         if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
   375         if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
   339             ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR);
   376             ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR);
   340             EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
   377             EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
   341             return;
   378             return;
   342         }
   379         }
   343 
   380 
   344         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   381         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   345         fsm->retries = EC_FSM_RETRIES;
   382         fsm->retries = EC_FSM_RETRIES;
   346         return;
   383         return;
   347     }
   384     }
   348 
   385 
   349     // Fetch response
   386     // Fetch response
   350     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
   387     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   351 
   388 
   352     fsm->retries = EC_FSM_RETRIES;
   389     fsm->retries = EC_FSM_RETRIES;
   353     fsm->state = ec_fsm_foe_state_ack_read;
   390     fsm->state = ec_fsm_foe_state_ack_read;
   354 }
   391 }
   355 
   392 
   356 /*****************************************************************************/
   393 /*****************************************************************************/
   357 
   394 
   358 /** Acknowledge a read operation.
   395 /** Acknowledge a read operation.
   359  */
   396  */
   360 void ec_fsm_foe_state_ack_read(
   397 void ec_fsm_foe_state_ack_read(
   361         ec_fsm_foe_t *fsm /**< FoE statemachine. */
   398         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
   362         )
   399         ec_datagram_t *datagram /**< Datagram to use. */
   363 {
   400         )
   364     ec_mailbox_t *mbox = fsm->mbox;
   401 {
   365     ec_datagram_t *datagram = mbox->datagram;
       
   366     ec_slave_t *slave = fsm->slave;
   402     ec_slave_t *slave = fsm->slave;
   367     uint8_t *data, mbox_prot;
   403     uint8_t *data, mbox_prot;
   368     uint8_t opCode;
   404     uint8_t opCode;
   369     size_t rec_size;
   405     size_t rec_size;
   370 
   406 
   371 #ifdef DEBUG_FOE
   407 #ifdef DEBUG_FOE
   372     printk("ec_fsm_foe_ack_read()\n");
   408     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   373 #endif
   409 #endif
   374 
   410 
   375     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   411     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   376         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   412         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   377         EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
   413         EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
   378         ec_datagram_print_state(datagram);
   414         ec_datagram_print_state(fsm->datagram);
   379         return;
   415         return;
   380     }
   416     }
   381 
   417 
   382     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   418     if (fsm->datagram->working_counter != 1) {
   383         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   419         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   384         EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: ");
   420         EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: ");
   385         ec_datagram_print_wc_error(datagram);
   421         ec_datagram_print_wc_error(fsm->datagram);
   386         return;
   422         return;
   387     }
   423     }
   388 
   424 
   389     if (!(data = ec_slave_mbox_fetch(fsm->slave, fsm->mbox,
   425     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
   390                     &mbox_prot, &rec_size))) {
   426     if (IS_ERR(data)) {
   391         ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   427         ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   392         return;
   428         return;
   393     }
   429     }
   394 
   430 
   395     if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE
   431     if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE
   401 
   437 
   402     opCode = EC_READ_U8(data);
   438     opCode = EC_READ_U8(data);
   403 
   439 
   404     if (opCode == EC_FOE_OPCODE_BUSY) {
   440     if (opCode == EC_FOE_OPCODE_BUSY) {
   405         // slave not ready
   441         // slave not ready
   406         if (ec_foe_prepare_data_send(fsm)) {
   442         if (ec_foe_prepare_data_send(fsm, datagram)) {
   407             ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   443             ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   408             EC_SLAVE_ERR(slave, "Slave is busy.\n");
   444             EC_SLAVE_ERR(slave, "Slave is busy.\n");
   409             return;
   445             return;
   410         }
   446         }
   411         fsm->state = ec_fsm_foe_state_data_sent;
   447         fsm->state = ec_fsm_foe_state_data_sent;
   419         if (fsm->tx_last_packet) {
   455         if (fsm->tx_last_packet) {
   420             fsm->state = ec_fsm_foe_end;
   456             fsm->state = ec_fsm_foe_end;
   421             return;
   457             return;
   422         }
   458         }
   423 
   459 
   424         if (ec_foe_prepare_data_send(fsm)) {
   460         if (ec_foe_prepare_data_send(fsm, datagram)) {
   425             ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   461             ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   426             return;
   462             return;
   427         }
   463         }
   428         fsm->state = ec_fsm_foe_state_data_sent;
   464         fsm->state = ec_fsm_foe_state_data_sent;
   429         return;
   465         return;
   437  *
   473  *
   438  * Checks is the previous transmit datagram succeded and sends the next
   474  * Checks is the previous transmit datagram succeded and sends the next
   439  * fragment, if necessary.
   475  * fragment, if necessary.
   440  */
   476  */
   441 void ec_fsm_foe_state_wrq_sent(
   477 void ec_fsm_foe_state_wrq_sent(
   442         ec_fsm_foe_t *fsm /**< FoE statemachine. */
   478         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
   443         )
   479         ec_datagram_t *datagram /**< Datagram to use. */
   444 {
   480         )
   445     ec_mailbox_t *mbox = fsm->mbox;
   481 {
   446     ec_datagram_t *datagram = mbox->datagram;
       
   447     ec_slave_t *slave = fsm->slave;
   482     ec_slave_t *slave = fsm->slave;
   448 
   483 
   449 #ifdef DEBUG_FOE
   484 #ifdef DEBUG_FOE
   450     printk("ec_foe_state_sent_wrq()\n");
   485     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   451 #endif
   486 #endif
   452 
   487 
   453     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   488     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   454         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   489         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   455         EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
   490         EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
   456         ec_datagram_print_state(datagram);
   491         ec_datagram_print_state(fsm->datagram);
   457         return;
   492         return;
   458     }
   493     }
   459 
   494 
   460     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   495     if (fsm->datagram->working_counter != 1) {
   461         // slave did not put anything in the mailbox yet
   496         // slave did not put anything in the mailbox yet
   462         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   497         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   463         EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
   498         EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
   464         ec_datagram_print_wc_error(datagram);
   499         ec_datagram_print_wc_error(fsm->datagram);
   465         return;
   500         return;
   466     }
   501     }
   467 
   502 
   468     fsm->jiffies_start = datagram->jiffies_sent;
   503     fsm->jiffies_start = fsm->datagram->jiffies_sent;
   469 
   504 
   470     ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
   505     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   471 
   506 
   472     fsm->retries = EC_FSM_RETRIES;
   507     fsm->retries = EC_FSM_RETRIES;
   473     fsm->state = ec_fsm_foe_state_ack_check;
   508     fsm->state = ec_fsm_foe_state_ack_check;
   474 }
   509 }
   475 
   510 
   479  *
   514  *
   480  * Checks is the previous transmit datagram succeded and sends the next
   515  * Checks is the previous transmit datagram succeded and sends the next
   481  * fragment, if necessary.
   516  * fragment, if necessary.
   482  */
   517  */
   483 void ec_fsm_foe_state_data_sent(
   518 void ec_fsm_foe_state_data_sent(
   484         ec_fsm_foe_t *fsm /**< Foe statemachine. */
   519         ec_fsm_foe_t *fsm, /**< Foe statemachine. */
   485         )
   520         ec_datagram_t *datagram /**< Datagram to use. */
   486 {
   521         )
   487     ec_mailbox_t *mbox = fsm->mbox;
   522 {
   488     ec_datagram_t *datagram = mbox->datagram;
       
   489     ec_slave_t *slave = fsm->slave;
   523     ec_slave_t *slave = fsm->slave;
   490 
   524 
   491 #ifdef DEBUG_FOE
   525 #ifdef DEBUG_FOE
   492     printk("ec_fsm_foe_state_data_sent()\n");
   526     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   493 #endif
   527 #endif
   494 
   528 
   495     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   529     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   496         ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR);
   530         ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR);
   497         EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
   531         EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
   498         ec_datagram_print_state(datagram);
   532         ec_datagram_print_state(fsm->datagram);
   499         return;
   533         return;
   500     }
   534     }
   501 
   535 
   502     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   536     if (fsm->datagram->working_counter != 1) {
   503         ec_foe_set_tx_error(fsm, FOE_WC_ERROR);
   537         ec_foe_set_tx_error(fsm, FOE_WC_ERROR);
   504         EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
   538         EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
   505         ec_datagram_print_wc_error(datagram);
   539         ec_datagram_print_wc_error(fsm->datagram);
   506         return;
   540         return;
   507     }
   541     }
   508 
   542 
   509     ec_slave_mbox_prepare_check(slave, mbox);
   543     ec_slave_mbox_prepare_check(slave, datagram);
   510     fsm->jiffies_start = jiffies;
   544     fsm->jiffies_start = jiffies;
   511     fsm->retries = EC_FSM_RETRIES;
   545     fsm->retries = EC_FSM_RETRIES;
   512     fsm->state = ec_fsm_foe_state_ack_check;
   546     fsm->state = ec_fsm_foe_state_ack_check;
   513 }
   547 }
   514 
   548 
   515 /*****************************************************************************/
   549 /*****************************************************************************/
   516 
   550 
   517 /** Prepare a read request (RRQ) with filename
   551 /** Prepare a read request (RRQ) with filename
   518  */
   552  *
   519 int ec_foe_prepare_rrq_send(ec_fsm_foe_t *fsm)
   553  * \return Zero on success, otherwise a negative error code.
       
   554  */
       
   555 int ec_foe_prepare_rrq_send(
       
   556         ec_fsm_foe_t *fsm, /**< Finite state machine. */
       
   557         ec_datagram_t *datagram /**< Datagram to use. */
       
   558         )
   520 {
   559 {
   521     size_t current_size;
   560     size_t current_size;
   522     uint8_t *data;
   561     uint8_t *data;
   523 
   562 
   524     current_size = fsm->rx_filename_len;
   563     current_size = fsm->rx_filename_len;
   525 
   564 
   526     data = ec_slave_mbox_prepare_send(fsm->slave, fsm->mbox,
   565     data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
   527             EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
   566             EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
   528     if (IS_ERR(data))
   567     if (IS_ERR(data)) {
   529         return -1;
   568         return -1;
       
   569     }
   530 
   570 
   531     EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
   571     EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
   532     EC_WRITE_U32(data + 2, 0x00000000); // no passwd
   572     EC_WRITE_U32(data + 2, 0x00000000); // no passwd
   533     memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
   573     memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
   534 
   574 
   541 }
   581 }
   542 
   582 
   543 /*****************************************************************************/
   583 /*****************************************************************************/
   544 
   584 
   545 /** Prepare to send an acknowledge.
   585 /** Prepare to send an acknowledge.
       
   586  *
       
   587  * \return Zero on success, otherwise a negative error code.
   546  */
   588  */
   547 int ec_foe_prepare_send_ack(
   589 int ec_foe_prepare_send_ack(
   548         ec_fsm_foe_t *foe /**< FoE statemachine. */
   590         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
       
   591         ec_datagram_t *datagram /**< Datagram to use. */
   549         )
   592         )
   550 {
   593 {
   551     uint8_t *data;
   594     uint8_t *data;
   552 
   595 
   553     data = ec_slave_mbox_prepare_send(foe->slave, foe->mbox,
   596     data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
   554             EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE);
   597             EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE);
   555     if (IS_ERR(data))
   598     if (IS_ERR(data)) {
   556         return -1;
   599         return -1;
       
   600     }
   557 
   601 
   558     EC_WRITE_U16(data, EC_FOE_OPCODE_ACK);
   602     EC_WRITE_U16(data, EC_FOE_OPCODE_ACK);
   559     EC_WRITE_U32(data + 2, foe->rx_expected_packet_no);
   603     EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no);
   560 
   604 
   561     return 0;
   605     return 0;
   562 }
   606 }
   563 
   607 
   564 /*****************************************************************************/
   608 /*****************************************************************************/
   565 
   609 
   566 /** State: RRQ SENT.
   610 /** State: RRQ SENT.
   567  *
   611  *
   568  * Checks is the previous transmit datagram succeded and sends the next
   612  * Checks is the previous transmit datagram succeeded and sends the next
   569  * fragment, if necessary.
   613  * fragment, if necessary.
   570  */
   614  */
   571 void ec_fsm_foe_state_rrq_sent(
   615 void ec_fsm_foe_state_rrq_sent(
   572         ec_fsm_foe_t *fsm /**< FoE statemachine. */
   616         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
   573         )
   617         ec_datagram_t *datagram /**< Datagram to use. */
   574 {
   618         )
   575     ec_mailbox_t *mbox = fsm->mbox;
   619 {
   576     ec_datagram_t *datagram = mbox->datagram;
       
   577     ec_slave_t *slave = fsm->slave;
   620     ec_slave_t *slave = fsm->slave;
   578 
   621 
   579 #ifdef DEBUG_FOE
   622 #ifdef DEBUG_FOE
   580     printk("ec_foe_state_rrq_sent()\n");
   623     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   581 #endif
   624 #endif
   582 
   625 
   583     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   626     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   584         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   627         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   585         EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
   628         EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
   586         ec_datagram_print_state(datagram);
   629         ec_datagram_print_state(fsm->datagram);
   587         return;
   630         return;
   588     }
   631     }
   589 
   632 
   590     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   633     if (fsm->datagram->working_counter != 1) {
   591         // slave did not put anything in the mailbox yet
   634         // slave did not put anything in the mailbox yet
   592         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   635         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   593         EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
   636         EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
   594         ec_datagram_print_wc_error(datagram);
   637         ec_datagram_print_wc_error(fsm->datagram);
   595         return;
   638         return;
   596     }
   639     }
   597 
   640 
   598     fsm->jiffies_start = datagram->jiffies_sent;
   641     fsm->jiffies_start = fsm->datagram->jiffies_sent;
   599 
   642 
   600     ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
   643     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   601 
   644 
   602     fsm->retries = EC_FSM_RETRIES;
   645     fsm->retries = EC_FSM_RETRIES;
   603     fsm->state = ec_fsm_foe_state_data_check;
   646     fsm->state = ec_fsm_foe_state_data_check;
   604 }
   647 }
   605 
   648 
   606 /*****************************************************************************/
   649 /*****************************************************************************/
   607 
   650 
   608 /** Start a read operation.
       
   609  */
       
   610 void ec_fsm_foe_read(
       
   611         ec_fsm_foe_t *fsm /**< FoE state machine. */
       
   612         )
       
   613 {
       
   614     fsm->state = ec_fsm_foe_read_start;
       
   615     fsm->rx_filename = fsm->request->file_name;
       
   616     fsm->rx_filename_len = strlen(fsm->rx_filename);
       
   617 
       
   618     fsm->rx_buffer = fsm->request->buffer;
       
   619     fsm->rx_buffer_size = fsm->request->buffer_size;
       
   620 }
       
   621 
       
   622 /*****************************************************************************/
       
   623 
       
   624 /** Starting state for read operations.
   651 /** Starting state for read operations.
   625  */
   652  */
   626 void ec_fsm_foe_read_start(
   653 void ec_fsm_foe_read_start(
   627         ec_fsm_foe_t *fsm /**< FoE statemachine. */
   654         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
       
   655         ec_datagram_t *datagram /**< Datagram to use. */
   628         )
   656         )
   629 {
   657 {
   630     ec_slave_t *slave = fsm->slave;
   658     ec_slave_t *slave = fsm->slave;
   631 
   659 
   632     fsm->rx_buffer_offset = 0;
   660     fsm->rx_buffer_offset = 0;
   633     fsm->rx_expected_packet_no = 1;
   661     fsm->rx_expected_packet_no = 1;
   634     fsm->rx_last_packet = 0;
   662     fsm->rx_last_packet = 0;
   635 
   663 
   636 #ifdef DEBUG_FOE
   664 #ifdef DEBUG_FOE
   637     printk("ec_fsm_foe_read_start()\n");
   665     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   638 #endif
   666 #endif
   639 
   667 
   640     if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
   668     if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
   641         ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
   669         ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
   642         EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
   670         EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
   643         return;
   671         return;
   644     }
   672     }
   645 
   673 
   646     if (ec_foe_prepare_rrq_send(fsm)) {
   674     if (ec_foe_prepare_rrq_send(fsm, datagram)) {
   647         ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
   675         ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
   648         return;
   676         return;
   649     }
   677     }
   650 
   678 
   651     fsm->state = ec_fsm_foe_state_rrq_sent;
   679     fsm->state = ec_fsm_foe_state_rrq_sent;
   654 /*****************************************************************************/
   682 /*****************************************************************************/
   655 
   683 
   656 /** Check for data.
   684 /** Check for data.
   657  */
   685  */
   658 void ec_fsm_foe_state_data_check(
   686 void ec_fsm_foe_state_data_check(
   659         ec_fsm_foe_t *fsm /**< FoE statemachine. */
   687         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
   660         )
   688         ec_datagram_t *datagram /**< Datagram to use. */
   661 {
   689         )
   662     ec_mailbox_t *mbox = fsm->mbox;
   690 {
   663     ec_datagram_t *datagram = mbox->datagram;
       
   664     ec_slave_t *slave = fsm->slave;
   691     ec_slave_t *slave = fsm->slave;
   665 
   692 
   666 #ifdef DEBUG_FOE
   693 #ifdef DEBUG_FOE
   667     printk("ec_fsm_foe_state_data_check()\n");
   694     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   668 #endif
   695 #endif
   669 
   696 
   670     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   697     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   671         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   698         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   672         EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: ");
   699         EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: ");
   673         ec_datagram_print_state(datagram);
   700         ec_datagram_print_state(fsm->datagram);
   674         return;
   701         return;
   675     }
   702     }
   676 
   703 
   677     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   704     if (fsm->datagram->working_counter != 1) {
   678         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   705         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   679         EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: ");
   706         EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: ");
   680         ec_datagram_print_wc_error(datagram);
   707         ec_datagram_print_wc_error(fsm->datagram);
   681         return;
   708         return;
   682     }
   709     }
   683 
   710 
   684     if (!ec_slave_mbox_check(mbox)) {
   711     if (!ec_slave_mbox_check(fsm->datagram)) {
   685         unsigned long diff_ms =
   712         unsigned long diff_ms = (fsm->datagram->jiffies_received -
   686             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
   713                 fsm->jiffies_start) * 1000 / HZ;
   687         if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
   714         if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
   688             ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR);
   715             ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR);
   689             EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
   716             EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
   690             return;
   717             return;
   691         }
   718         }
   692 
   719 
   693         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   720         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   694         fsm->retries = EC_FSM_RETRIES;
   721         fsm->retries = EC_FSM_RETRIES;
   695         return;
   722         return;
   696     }
   723     }
   697 
   724 
   698     // Fetch response
   725     // Fetch response
   699     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
   726     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   700 
   727 
   701     fsm->retries = EC_FSM_RETRIES;
   728     fsm->retries = EC_FSM_RETRIES;
   702     fsm->state = ec_fsm_foe_state_data_read;
   729     fsm->state = ec_fsm_foe_state_data_read;
   703 
       
   704 }
   730 }
   705 
   731 
   706 /*****************************************************************************/
   732 /*****************************************************************************/
   707 
   733 
   708 /** Start reading data.
   734 /** Start reading data.
   709  */
   735  */
   710 void ec_fsm_foe_state_data_read(
   736 void ec_fsm_foe_state_data_read(
   711         ec_fsm_foe_t *fsm /**< FoE statemachine. */
   737         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
       
   738         ec_datagram_t *datagram /**< Datagram to use. */
   712         )
   739         )
   713 {
   740 {
   714     size_t rec_size;
   741     size_t rec_size;
   715     uint8_t *data, opCode, packet_no, mbox_prot;
   742     uint8_t *data, opCode, packet_no, mbox_prot;
   716 
   743 
   717     ec_mailbox_t *mbox = fsm->mbox;
       
   718     ec_datagram_t *datagram = mbox->datagram;
       
   719     ec_slave_t *slave = fsm->slave;
   744     ec_slave_t *slave = fsm->slave;
   720 
   745 
   721 #ifdef DEBUG_FOE
   746 #ifdef DEBUG_FOE
   722     printk("ec_fsm_foe_state_data_read()\n");
   747     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   723 #endif
   748 #endif
   724 
   749 
   725     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   750     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   726         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   751         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   727         EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: ");
   752         EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: ");
   728         ec_datagram_print_state(datagram);
   753         ec_datagram_print_state(fsm->datagram);
   729         return;
   754         return;
   730     }
   755     }
   731 
   756 
   732     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   757     if (fsm->datagram->working_counter != 1) {
   733         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   758         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   734         EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: ");
   759         EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: ");
   735         ec_datagram_print_wc_error(datagram);
   760         ec_datagram_print_wc_error(fsm->datagram);
   736         return;
   761         return;
   737     }
   762     }
   738 
   763 
   739     if (!(data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size))) {
   764     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
       
   765     if (IS_ERR(data)) {
   740         ec_foe_set_rx_error(fsm, FOE_MBOX_FETCH_ERROR);
   766         ec_foe_set_rx_error(fsm, FOE_MBOX_FETCH_ERROR);
   741         return;
   767         return;
   742     }
   768     }
   743 
   769 
   744     if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE
   770     if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE
   749     }
   775     }
   750 
   776 
   751     opCode = EC_READ_U8(data);
   777     opCode = EC_READ_U8(data);
   752 
   778 
   753     if (opCode == EC_FOE_OPCODE_BUSY) {
   779     if (opCode == EC_FOE_OPCODE_BUSY) {
   754         if (ec_foe_prepare_send_ack(fsm)) {
   780         if (ec_foe_prepare_send_ack(fsm, datagram)) {
   755             ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
   781             ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
   756         }
   782         }
   757         return;
   783         return;
   758     }
   784     }
   759 
   785 
   793         fsm->rx_buffer_offset += rec_size;
   819         fsm->rx_buffer_offset += rec_size;
   794     }
   820     }
   795 
   821 
   796     fsm->rx_last_packet =
   822     fsm->rx_last_packet =
   797         (rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE
   823         (rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE
   798          != fsm->slave->configured_rx_mailbox_size);
   824          != slave->configured_rx_mailbox_size);
   799 
   825 
   800     if (fsm->rx_last_packet ||
   826     if (fsm->rx_last_packet ||
   801             (slave->configured_rx_mailbox_size - EC_MBOX_HEADER_SIZE
   827             (slave->configured_rx_mailbox_size - EC_MBOX_HEADER_SIZE
   802              - EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset)
   828              - EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset)
   803             <= fsm->rx_buffer_size) {
   829             <= fsm->rx_buffer_size) {
   804         // either it was the last packet or a new packet will fit into the
   830         // either it was the last packet or a new packet will fit into the
   805         // delivered buffer
   831         // delivered buffer
   806 #ifdef DEBUG_FOE
   832 #ifdef DEBUG_FOE
   807         printk ("last_packet=true\n");
   833         EC_SLAVE_DBG(fsm->slave, 0, "last_packet=true\n");
   808 #endif
   834 #endif
   809         if (ec_foe_prepare_send_ack(fsm)) {
   835         if (ec_foe_prepare_send_ack(fsm, datagram)) {
   810             ec_foe_set_rx_error(fsm, FOE_RX_DATA_ACK_ERROR);
   836             ec_foe_set_rx_error(fsm, FOE_RX_DATA_ACK_ERROR);
   811             return;
   837             return;
   812         }
   838         }
   813 
   839 
   814         fsm->state = ec_fsm_foe_state_sent_ack;
   840         fsm->state = ec_fsm_foe_state_sent_ack;
   815     }
   841     }
   816     else {
   842     else {
   817         // no more data fits into the delivered buffer
   843         // no more data fits into the delivered buffer
   818         // ... wait for new read request
   844         // ... wait for new read request
   819         printk ("ERROR: data doesn't fit in receive buffer\n");
   845         EC_SLAVE_ERR(slave, "Data do not fit in receive buffer!\n");
   820         printk ("       rx_buffer_size  = %d\n", fsm->rx_buffer_size);
   846         printk("  rx_buffer_size = %d\n", fsm->rx_buffer_size);
   821         printk ("       rx_buffer_offset= %d\n", fsm->rx_buffer_offset);
   847         printk("rx_buffer_offset = %d\n", fsm->rx_buffer_offset);
   822         printk ("       rec_size        = %zd\n", rec_size);
   848         printk("        rec_size = %zd\n", rec_size);
   823         printk ("       rx_mailbox_size = %d\n",
   849         printk(" rx_mailbox_size = %d\n", slave->configured_rx_mailbox_size);
   824                 slave->configured_rx_mailbox_size);
   850         printk("  rx_last_packet = %d\n", fsm->rx_last_packet);
   825         printk ("       rx_last_packet  = %d\n", fsm->rx_last_packet);
       
   826         fsm->request->result = FOE_READY;
   851         fsm->request->result = FOE_READY;
   827     }
   852     }
   828 }
   853 }
   829 
   854 
   830 /*****************************************************************************/
   855 /*****************************************************************************/
   831 
   856 
   832 /** Sent an acknowledge.
   857 /** Sent an acknowledge.
   833  */
   858  */
   834 void ec_fsm_foe_state_sent_ack(
   859 void ec_fsm_foe_state_sent_ack(
   835         ec_fsm_foe_t *fsm /**< FoE statemachine. */
   860         ec_fsm_foe_t *fsm, /**< FoE statemachine. */
   836         )
   861         ec_datagram_t *datagram /**< Datagram to use. */
   837 {
   862         )
   838     ec_mailbox_t *mbox = fsm->mbox;
   863 {
   839     ec_datagram_t *datagram = mbox->datagram;
       
   840     ec_slave_t *slave = fsm->slave;
   864     ec_slave_t *slave = fsm->slave;
   841 
   865 
   842 #ifdef DEBUG_FOE
   866 #ifdef DEBUG_FOE
   843     printk("ec_foe_state_sent_ack()\n");
   867     EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
   844 #endif
   868 #endif
   845 
   869 
   846     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   870     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   847         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   871         ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   848         EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
   872         EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
   849         ec_datagram_print_state(datagram);
   873         ec_datagram_print_state(fsm->datagram);
   850         return;
   874         return;
   851     }
   875     }
   852 
   876 
   853     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   877     if (fsm->datagram->working_counter != 1) {
   854         // slave did not put anything into the mailbox yet
   878         // slave did not put anything into the mailbox yet
   855         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   879         ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
   856         EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
   880         EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
   857         ec_datagram_print_wc_error(datagram);
   881         ec_datagram_print_wc_error(fsm->datagram);
   858         return;
   882         return;
   859     }
   883     }
   860 
   884 
   861     fsm->jiffies_start = datagram->jiffies_sent;
   885     fsm->jiffies_start = fsm->datagram->jiffies_sent;
   862 
   886 
   863     ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
   887     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   864 
   888 
   865     if (fsm->rx_last_packet) {
   889     if (fsm->rx_last_packet) {
   866         fsm->rx_expected_packet_no = 0;
   890         fsm->rx_expected_packet_no = 0;
   867         fsm->request->data_size = fsm->rx_buffer_offset;
   891         fsm->request->data_size = fsm->rx_buffer_offset;
   868         fsm->state = ec_fsm_foe_end;
   892         fsm->state = ec_fsm_foe_end;