master/fsm_coe.c
changeset 2589 2b9c78543663
parent 2195 d9146c0ff00f
child 2591 23b360e4a530
equal deleted inserted replaced
2415:af21f0bdc7c9 2589:2b9c78543663
    25  *  EtherCAT technology and brand is only permitted in compliance with the
    25  *  EtherCAT technology and brand is only permitted in compliance with the
    26  *  industrial property and similar rights of Beckhoff Automation GmbH.
    26  *  industrial property and similar rights of Beckhoff Automation GmbH.
    27  *
    27  *
    28  *****************************************************************************/
    28  *****************************************************************************/
    29 
    29 
    30 /**
    30 /** \file
    31    \file
    31  * EtherCAT CoE state machines.
    32    EtherCAT CoE state machines.
    32  */
    33 */
       
    34 
    33 
    35 /*****************************************************************************/
    34 /*****************************************************************************/
    36 
    35 
    37 #include "globals.h"
    36 #include "globals.h"
    38 #include "master.h"
    37 #include "master.h"
    39 #include "mailbox.h"
    38 #include "mailbox.h"
    40 #include "fsm_coe.h"
    39 #include "fsm_coe.h"
       
    40 #include "slave_config.h"
    41 
    41 
    42 /*****************************************************************************/
    42 /*****************************************************************************/
    43 
    43 
    44 /** Maximum time in ms to wait for responses when reading out the dictionary.
    44 /** Maximum time in ms to wait for responses when reading out the dictionary.
    45  */
    45  */
    65  */
    65  */
    66 #define DEBUG_LONG 0
    66 #define DEBUG_LONG 0
    67 
    67 
    68 /*****************************************************************************/
    68 /*****************************************************************************/
    69 
    69 
    70 void ec_fsm_coe_dict_start(ec_fsm_coe_t *);
    70 void ec_fsm_coe_dict_start(ec_fsm_coe_t *, ec_datagram_t *);
    71 void ec_fsm_coe_dict_request(ec_fsm_coe_t *);
    71 void ec_fsm_coe_dict_request(ec_fsm_coe_t *, ec_datagram_t *);
    72 void ec_fsm_coe_dict_check(ec_fsm_coe_t *);
    72 void ec_fsm_coe_dict_check(ec_fsm_coe_t *, ec_datagram_t *);
    73 void ec_fsm_coe_dict_response(ec_fsm_coe_t *);
    73 void ec_fsm_coe_dict_response(ec_fsm_coe_t *, ec_datagram_t *);
    74 void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *);
    74 void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *, ec_datagram_t *);
    75 void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *);
    75 void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *, ec_datagram_t *);
    76 void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *);
    76 void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *);
    77 void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *);
    77 void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *, ec_datagram_t *);
    78 void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *);
    78 void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *);
    79 void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *);
    79 void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *, ec_datagram_t *);
    80 
    80 
    81 void ec_fsm_coe_down_start(ec_fsm_coe_t *);
    81 void ec_fsm_coe_down_start(ec_fsm_coe_t *, ec_datagram_t *);
    82 void ec_fsm_coe_down_request(ec_fsm_coe_t *);
    82 void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *);
    83 void ec_fsm_coe_down_check(ec_fsm_coe_t *);
    83 void ec_fsm_coe_down_check(ec_fsm_coe_t *, ec_datagram_t *);
    84 void ec_fsm_coe_down_response(ec_fsm_coe_t *);
    84 void ec_fsm_coe_down_response(ec_fsm_coe_t *, ec_datagram_t *);
    85 void ec_fsm_coe_down_seg_check(ec_fsm_coe_t *);
    85 void ec_fsm_coe_down_seg_check(ec_fsm_coe_t *, ec_datagram_t *);
    86 void ec_fsm_coe_down_seg_response(ec_fsm_coe_t *);
    86 void ec_fsm_coe_down_seg_response(ec_fsm_coe_t *, ec_datagram_t *);
    87 
    87 
    88 void ec_fsm_coe_up_start(ec_fsm_coe_t *);
    88 void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *);
    89 void ec_fsm_coe_up_request(ec_fsm_coe_t *);
    89 void ec_fsm_coe_up_request(ec_fsm_coe_t *, ec_datagram_t *);
    90 void ec_fsm_coe_up_check(ec_fsm_coe_t *);
    90 void ec_fsm_coe_up_check(ec_fsm_coe_t *, ec_datagram_t *);
    91 void ec_fsm_coe_up_response(ec_fsm_coe_t *);
    91 void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *);
    92 void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *);
    92 void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *);
    93 void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *);
    93 void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *, ec_datagram_t *);
    94 void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *);
    94 void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *, ec_datagram_t *);
    95 
    95 
    96 void ec_fsm_coe_end(ec_fsm_coe_t *);
    96 void ec_fsm_coe_end(ec_fsm_coe_t *, ec_datagram_t *);
    97 void ec_fsm_coe_error(ec_fsm_coe_t *);
    97 void ec_fsm_coe_error(ec_fsm_coe_t *, ec_datagram_t *);
    98 
    98 
    99 /*****************************************************************************/
    99 /*****************************************************************************/
   100 
   100 
   101 /**
   101 /** SDO abort messages.
   102    SDO abort messages.
   102  *
   103    The "abort SDO transfer request" supplies an abort code,
   103  * The "abort SDO transfer request" supplies an abort code, which can be
   104    which can be translated to clear text. This table does
   104  * translated to clear text. This table does the mapping of the codes and
   105    the mapping of the codes and messages.
   105  * messages.
   106 */
   106  */
   107 
       
   108 const ec_code_msg_t sdo_abort_messages[] = {
   107 const ec_code_msg_t sdo_abort_messages[] = {
   109     {0x05030000, "Toggle bit not changed"},
   108     {0x05030000, "Toggle bit not changed"},
   110     {0x05040000, "SDO protocol timeout"},
   109     {0x05040000, "SDO protocol timeout"},
   111     {0x05040001, "Client/Server command specifier not valid or unknown"},
   110     {0x05040001, "Client/Server command specifier not valid or unknown"},
   112     {0x05040005, "Out of memory"},
   111     {0x05040005, "Out of memory"},
   144 
   143 
   145 /*****************************************************************************/
   144 /*****************************************************************************/
   146 
   145 
   147 /** Outputs an SDO abort message.
   146 /** Outputs an SDO abort message.
   148  */
   147  */
   149 void ec_canopen_abort_msg(const ec_slave_t *slave, uint32_t abort_code)
   148 void ec_canopen_abort_msg(
       
   149         const ec_slave_t *slave, /**< Slave. */
       
   150         uint32_t abort_code /**< Abort code to search for. */
       
   151         )
   150 {
   152 {
   151     const ec_code_msg_t *abort_msg;
   153     const ec_code_msg_t *abort_msg;
   152 
   154 
   153     for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
   155     for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
   154         if (abort_msg->code == abort_code) {
   156         if (abort_msg->code == abort_code) {
   161     EC_SLAVE_ERR(slave, "Unknown SDO abort code 0x%08X.\n", abort_code);
   163     EC_SLAVE_ERR(slave, "Unknown SDO abort code 0x%08X.\n", abort_code);
   162 }
   164 }
   163 
   165 
   164 /*****************************************************************************/
   166 /*****************************************************************************/
   165 
   167 
   166 /**
   168 /** Constructor.
   167    Constructor.
   169  */
   168 */
   170 void ec_fsm_coe_init(
   169 
   171         ec_fsm_coe_t *fsm /**< Finite state machine */
   170 void ec_fsm_coe_init(ec_fsm_coe_t *fsm, /**< finite state machine */
   172         )
   171                      ec_mailbox_t *mbox /**< mailbox */
       
   172                      )
       
   173 {
   173 {
   174     fsm->state = NULL;
   174     fsm->state = NULL;
   175     fsm->mbox = mbox;
   175     fsm->datagram = NULL;
   176 }
   176 }
   177 
   177 
   178 /*****************************************************************************/
   178 /*****************************************************************************/
   179 
   179 
   180 /**
   180 /** Destructor.
   181    Destructor.
   181  */
   182 */
   182 void ec_fsm_coe_clear(
   183 
   183         ec_fsm_coe_t *fsm /**< Finite state machine */
   184 void ec_fsm_coe_clear(ec_fsm_coe_t *fsm /**< finite state machine */)
   184         )
   185 {
   185 {
   186 }
   186 }
   187 
   187 
   188 /*****************************************************************************/
   188 /*****************************************************************************/
   189 
   189 
   190 /**
   190 /** Starts reading a slaves' SDO dictionary.
   191    Starts reading a slaves' SDO dictionary.
   191  */
   192 */
   192 void ec_fsm_coe_dictionary(
   193 
   193         ec_fsm_coe_t *fsm, /**< Finite state machine */
   194 void ec_fsm_coe_dictionary(ec_fsm_coe_t *fsm, /**< finite state machine */
   194         ec_slave_t *slave /**< EtherCAT slave */
   195                            ec_slave_t *slave /**< EtherCAT slave */
   195         )
   196                            )
       
   197 {
   196 {
   198     fsm->slave = slave;
   197     fsm->slave = slave;
   199     fsm->state = ec_fsm_coe_dict_start;
   198     fsm->state = ec_fsm_coe_dict_start;
   200 }
   199 }
   201 
   200 
   202 /*****************************************************************************/
   201 /*****************************************************************************/
   203 
   202 
   204 /**
   203 /** Starts to transfer an SDO to/from a slave.
   205    Starts to transfer an SDO to/from a slave.
   204  */
   206 */
       
   207 
       
   208 void ec_fsm_coe_transfer(
   205 void ec_fsm_coe_transfer(
   209         ec_fsm_coe_t *fsm, /**< State machine. */
   206         ec_fsm_coe_t *fsm, /**< State machine. */
   210         ec_slave_t *slave, /**< EtherCAT slave. */
   207         ec_slave_t *slave, /**< EtherCAT slave. */
   211         ec_sdo_request_t *request /**< SDO request. */
   208         ec_sdo_request_t *request /**< SDO request. */
   212         )
   209         )
   213 {
   210 {
   214     fsm->slave = slave;
   211     fsm->slave = slave;
   215     fsm->request = request;
   212     fsm->request = request;
   216     if (request->dir == EC_DIR_OUTPUT)
   213 
       
   214     if (request->dir == EC_DIR_OUTPUT) {
   217         fsm->state = ec_fsm_coe_down_start;
   215         fsm->state = ec_fsm_coe_down_start;
   218     else
   216     }
       
   217     else {
   219         fsm->state = ec_fsm_coe_up_start;
   218         fsm->state = ec_fsm_coe_up_start;
   220 }
   219     }
   221 
   220 }
   222 /*****************************************************************************/
   221 
   223 
   222 /*****************************************************************************/
   224 /**
   223 
   225    Executes the current state of the state machine.
   224 /** Executes the current state of the state machine.
   226    \return false, if state machine has terminated
   225  *
   227 */
   226  * \return 1 if the datagram was used, else 0.
   228 
   227  */
   229 int ec_fsm_coe_exec(ec_fsm_coe_t *fsm /**< finite state machine */)
   228 int ec_fsm_coe_exec(
   230 {
   229         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   231     fsm->state(fsm);
   230         ec_datagram_t *datagram /**< Datagram to use. */
   232 
   231         )
   233     return fsm->state != ec_fsm_coe_end && fsm->state != ec_fsm_coe_error;
   232 {
   234 }
   233     int datagram_used = 0;
   235 
   234 
   236 /*****************************************************************************/
   235     if (fsm->datagram &&
   237 
   236             (fsm->datagram->state == EC_DATAGRAM_INIT ||
   238 /**
   237              fsm->datagram->state == EC_DATAGRAM_QUEUED ||
   239    Returns, if the state machine terminated with success.
   238              fsm->datagram->state == EC_DATAGRAM_SENT)) {
   240    \return non-zero if successful.
   239         // datagram not received yet
   241 */
   240         return datagram_used;
   242 
   241     }
   243 int ec_fsm_coe_success(ec_fsm_coe_t *fsm /**< Finite state machine */)
   242 
       
   243     fsm->state(fsm, datagram);
       
   244 
       
   245     datagram_used =
       
   246         fsm->state != ec_fsm_coe_end && fsm->state != ec_fsm_coe_error;
       
   247 
       
   248     if (datagram_used) {
       
   249         fsm->datagram = datagram;
       
   250     } else {
       
   251         fsm->datagram = NULL;
       
   252     }
       
   253 
       
   254     return datagram_used;
       
   255 }
       
   256 
       
   257 /*****************************************************************************/
       
   258 
       
   259 /** Returns, if the state machine terminated with success.
       
   260  * \return non-zero if successful.
       
   261  */
       
   262 int ec_fsm_coe_success(
       
   263         const ec_fsm_coe_t *fsm /**< Finite state machine */
       
   264         )
   244 {
   265 {
   245     return fsm->state == ec_fsm_coe_end;
   266     return fsm->state == ec_fsm_coe_end;
   246 }
   267 }
   247 
   268 
   248 /*****************************************************************************/
   269 /*****************************************************************************/
   266         EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency"
   287         EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency"
   267                 " request:\n");
   288                 " request:\n");
   268         ec_print_data(data, size);
   289         ec_print_data(data, size);
   269         return 1;
   290         return 1;
   270     }
   291     }
   271     
   292 
       
   293     {
       
   294         ec_slave_config_t *sc = fsm->slave->config;
       
   295         if (sc) {
       
   296             ec_coe_emerg_ring_push(&sc->emerg_ring, data + 2);
       
   297         }
       
   298     }
       
   299 
   272     EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n"
   300     EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n"
   273             "Error code 0x%04X, Error register 0x%02X, data:\n",
   301             "Error code 0x%04X, Error register 0x%02X, data:\n",
   274             EC_READ_U16(data + 2), EC_READ_U8(data + 4));
   302             EC_READ_U16(data + 2), EC_READ_U8(data + 4));
   275     ec_print_data(data + 5, 5);
   303     ec_print_data(data + 5, 5);
   276     return 1;
   304     return 1;
   278 
   306 
   279 /******************************************************************************
   307 /******************************************************************************
   280  *  CoE dictionary state machine
   308  *  CoE dictionary state machine
   281  *****************************************************************************/
   309  *****************************************************************************/
   282 
   310 
   283 /**
   311 /** Prepare a dictionary request.
   284    CoE state: DICT START.
   312  *
   285 */
   313  * \return Zero on success, otherwise a negative error code.
   286 
   314  */
   287 void ec_fsm_coe_dict_start(ec_fsm_coe_t *fsm /**< finite state machine */)
   315 int ec_fsm_coe_prepare_dict(
   288 {
   316         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   289     ec_mailbox_t *mbox = fsm->mbox;
   317         ec_datagram_t *datagram /**< Datagram to use. */
   290     ec_slave_t *slave = fsm->slave;
   318         )
   291     uint8_t *data;
   319 {
   292 
   320     ec_slave_t *slave = fsm->slave;
   293     if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
   321     uint8_t *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
   294         EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
       
   295         fsm->state = ec_fsm_coe_error;
       
   296         return;
       
   297     }
       
   298 
       
   299     if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) {
       
   300         EC_SLAVE_ERR(slave, "Slave does not support"
       
   301                 " SDO information service!\n");
       
   302         fsm->state = ec_fsm_coe_error;
       
   303         return;
       
   304     }
       
   305 
       
   306     data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 8);
       
   307     if (IS_ERR(data)) {
   322     if (IS_ERR(data)) {
   308         fsm->state = ec_fsm_coe_error;
   323         return PTR_ERR(data);
   309         return;
       
   310     }
   324     }
   311 
   325 
   312     EC_WRITE_U16(data, 0x8 << 12); // SDO information
   326     EC_WRITE_U16(data, 0x8 << 12); // SDO information
   313     EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
   327     EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
   314     EC_WRITE_U8 (data + 3, 0x00);
   328     EC_WRITE_U8 (data + 3, 0x00);
   315     EC_WRITE_U16(data + 4, 0x0000);
   329     EC_WRITE_U16(data + 4, 0x0000);
   316     EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
   330     EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
   317 
   331 
       
   332     fsm->state = ec_fsm_coe_dict_request;
       
   333     return 0;
       
   334 }
       
   335 
       
   336 /*****************************************************************************/
       
   337 
       
   338 /** CoE state: DICT START.
       
   339  */
       
   340 void ec_fsm_coe_dict_start(
       
   341         ec_fsm_coe_t *fsm, /**< Finite state machine. */
       
   342         ec_datagram_t *datagram /**< Datagram to use. */
       
   343         )
       
   344 {
       
   345     ec_slave_t *slave = fsm->slave;
       
   346 
       
   347     if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
       
   348         EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
       
   349         fsm->state = ec_fsm_coe_error;
       
   350         return;
       
   351     }
       
   352 
       
   353     if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) {
       
   354         EC_SLAVE_ERR(slave, "Slave does not support"
       
   355                 " SDO information service!\n");
       
   356         fsm->state = ec_fsm_coe_error;
       
   357         return;
       
   358     }
       
   359 
   318     fsm->retries = EC_FSM_RETRIES;
   360     fsm->retries = EC_FSM_RETRIES;
   319     fsm->state = ec_fsm_coe_dict_request;
   361 
   320 }
   362     if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
   321 
   363         fsm->state = ec_fsm_coe_error;
   322 /*****************************************************************************/
   364     }
   323 
   365 }
   324 /**
   366 
   325    CoE state: DICT REQUEST.
   367 /*****************************************************************************/
   326    \todo Timeout behavior
   368 
   327 */
   369 /** CoE state: DICT REQUEST.
   328 
   370  * \todo Timeout behavior
   329 void ec_fsm_coe_dict_request(ec_fsm_coe_t *fsm /**< finite state machine */)
   371  */
   330 {
   372 void ec_fsm_coe_dict_request(
   331     ec_mailbox_t *mbox = fsm->mbox;
   373         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   332     ec_datagram_t *datagram = mbox->datagram;
   374         ec_datagram_t *datagram /**< Datagram to use. */
   333     ec_slave_t *slave = fsm->slave;
   375         )
   334 
   376 {
   335     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
   377     ec_slave_t *slave = fsm->slave;
   336             && fsm->retries--) {
   378 
   337         return; // FIXME: request again?
   379     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   338     }
   380         if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
   339 
   381             fsm->state = ec_fsm_coe_error;
   340     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   382         }
       
   383         return;
       
   384     }
       
   385 
       
   386     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   341         fsm->state = ec_fsm_coe_error;
   387         fsm->state = ec_fsm_coe_error;
   342         EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
   388         EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
   343                 " request datagram: ");
   389                 " request datagram: ");
   344         ec_datagram_print_state(datagram);
   390         ec_datagram_print_state(fsm->datagram);
   345         return;
   391         return;
   346     }
   392     }
   347 
   393 
   348     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   394     if (fsm->datagram->working_counter != 1) {
   349         fsm->state = ec_fsm_coe_error;
   395         fsm->state = ec_fsm_coe_error;
   350         EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
   396         EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
   351         ec_datagram_print_wc_error(datagram);
   397         ec_datagram_print_wc_error(fsm->datagram);
   352         return;
   398         return;
   353     }
   399     }
   354 
   400 
   355     fsm->jiffies_start = datagram->jiffies_sent;
   401     fsm->jiffies_start = fsm->datagram->jiffies_sent;
   356 
   402 
   357     ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   403     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   358     fsm->retries = EC_FSM_RETRIES;
   404     fsm->retries = EC_FSM_RETRIES;
   359     fsm->state = ec_fsm_coe_dict_check;
   405     fsm->state = ec_fsm_coe_dict_check;
   360 }
   406 }
   361 
   407 
   362 /*****************************************************************************/
   408 /*****************************************************************************/
   363 
   409 
   364 /**
   410 /** CoE state: DICT CHECK.
   365    CoE state: DICT CHECK.
   411  */
   366 */
   412 void ec_fsm_coe_dict_check(
   367 
   413         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   368 void ec_fsm_coe_dict_check(ec_fsm_coe_t *fsm /**< finite state machine */)
   414         ec_datagram_t *datagram /**< Datagram to use. */
   369 {
   415         )
   370     ec_mailbox_t *mbox = fsm->mbox;
   416 {
   371     ec_datagram_t *datagram = mbox->datagram;
   417     ec_slave_t *slave = fsm->slave;
   372     ec_slave_t *slave = fsm->slave;
   418 
   373 
   419     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   374     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
   420         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   375             && fsm->retries--) {
   421         return;
   376         return;
   422     }
   377     }
   423 
   378 
   424     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   379     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
       
   380         fsm->state = ec_fsm_coe_error;
   425         fsm->state = ec_fsm_coe_error;
   381         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
   426         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
   382         ec_datagram_print_state(datagram);
   427         ec_datagram_print_state(fsm->datagram);
   383         return;
   428         return;
   384     }
   429     }
   385 
   430 
   386     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   431     if (fsm->datagram->working_counter != 1) {
   387         fsm->state = ec_fsm_coe_error;
   432         fsm->state = ec_fsm_coe_error;
   388         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
   433         EC_SLAVE_ERR(slave,"Reception of CoE mailbox check"
   389                 " datagram failed: ");
   434                 " datagram failed: ");
   390         ec_datagram_print_wc_error(datagram);
   435         ec_datagram_print_wc_error(fsm->datagram);
   391         return;
   436         return;
   392     }
   437     }
   393 
   438 
   394     if (!ec_slave_mbox_check(mbox)) {
   439     if (!ec_slave_mbox_check(fsm->datagram)) {
   395         unsigned long diff_ms =
   440         unsigned long diff_ms =
   396             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
   441             (fsm->datagram->jiffies_received - fsm->jiffies_start) *
       
   442             1000 / HZ;
   397         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
   443         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
   398             fsm->state = ec_fsm_coe_error;
   444             fsm->state = ec_fsm_coe_error;
   399             EC_SLAVE_ERR(slave, "Timeout while waiting for"
   445             EC_SLAVE_ERR(slave, "Timeout while waiting for"
   400                     " SDO dictionary list response.\n");
   446                     " SDO dictionary list response.\n");
   401             return;
   447             return;
   402         }
   448         }
   403 
   449 
   404         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   450         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   405         fsm->retries = EC_FSM_RETRIES;
   451         fsm->retries = EC_FSM_RETRIES;
   406         return;
   452         return;
   407     }
   453     }
   408 
   454 
   409     // Fetch response
   455     // Fetch response
   410     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
   456     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   411     fsm->retries = EC_FSM_RETRIES;
   457     fsm->retries = EC_FSM_RETRIES;
   412     fsm->state = ec_fsm_coe_dict_response;
   458     fsm->state = ec_fsm_coe_dict_response;
       
   459 }
       
   460 
       
   461 /*****************************************************************************/
       
   462 
       
   463 /** Prepare an object description request.
       
   464  *
       
   465  * \return Zero on success, otherwise a negative error code.
       
   466  */
       
   467 int ec_fsm_coe_dict_prepare_desc(
       
   468         ec_fsm_coe_t *fsm, /**< Finite state machine. */
       
   469         ec_datagram_t *datagram /**< Datagram to use. */
       
   470         )
       
   471 {
       
   472     ec_slave_t *slave = fsm->slave;
       
   473     u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
       
   474     if (IS_ERR(data)) {
       
   475         return PTR_ERR(data);
       
   476     }
       
   477 
       
   478     EC_WRITE_U16(data, 0x8 << 12); // SDO information
       
   479     EC_WRITE_U8 (data + 2, 0x03); // Get object description request
       
   480     EC_WRITE_U8 (data + 3, 0x00);
       
   481     EC_WRITE_U16(data + 4, 0x0000);
       
   482     EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
       
   483 
       
   484     fsm->state = ec_fsm_coe_dict_desc_request;
       
   485     return 0;
   413 }
   486 }
   414 
   487 
   415 /*****************************************************************************/
   488 /*****************************************************************************/
   416 
   489 
   417 /**
   490 /**
   418    CoE state: DICT RESPONSE.
   491    CoE state: DICT RESPONSE.
   419    \todo Timeout behavior
   492    \todo Timeout behavior
   420 */
   493 */
   421 
   494 
   422 void ec_fsm_coe_dict_response(ec_fsm_coe_t *fsm /**< finite state machine */)
   495 void ec_fsm_coe_dict_response(
   423 {
   496         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   424     ec_mailbox_t *mbox = fsm->mbox;
   497         ec_datagram_t *datagram /**< Datagram to use. */
   425     ec_datagram_t *datagram = mbox->datagram;
   498         )
       
   499 {
   426     ec_slave_t *slave = fsm->slave;
   500     ec_slave_t *slave = fsm->slave;
   427     uint8_t *data, mbox_prot;
   501     uint8_t *data, mbox_prot;
   428     size_t rec_size;
   502     size_t rec_size;
   429     unsigned int sdo_count, i;
   503     unsigned int sdo_count, i;
   430     uint16_t sdo_index, fragments_left;
   504     uint16_t sdo_index, fragments_left;
   431     ec_sdo_t *sdo;
   505     ec_sdo_t *sdo;
   432     bool first_segment;
   506     bool first_segment;
   433     size_t index_list_offset;
   507     size_t index_list_offset;
   434 
   508 
   435     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
   509     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   436             && fsm->retries--) {
   510         ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   437         return; // FIXME: request again?
   511         return;
   438     }
   512     }
   439 
   513 
   440     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   514     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   441         fsm->state = ec_fsm_coe_error;
   515         fsm->state = ec_fsm_coe_error;
   442         EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
   516         EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
   443                 " response datagram: ");
   517                 " response datagram: ");
   444         ec_datagram_print_state(datagram);
   518         ec_datagram_print_state(fsm->datagram);
   445         return;
   519         return;
   446     }
   520     }
   447 
   521 
   448     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   522     if (fsm->datagram->working_counter != 1) {
   449         fsm->state = ec_fsm_coe_error;
   523         fsm->state = ec_fsm_coe_error;
   450         EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
   524         EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
   451         ec_datagram_print_wc_error(datagram);
   525         ec_datagram_print_wc_error(fsm->datagram);
   452         return;
   526         return;
   453     }
   527     }
   454 
   528 
   455     data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
   529     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
   456     if (IS_ERR(data)) {
   530     if (IS_ERR(data)) {
   457         fsm->state = ec_fsm_coe_error;
   531         fsm->state = ec_fsm_coe_error;
   458         return;
   532         return;
   459     }
   533     }
   460 
   534 
   465         return;
   539         return;
   466     }
   540     }
   467 
   541 
   468     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
   542     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
   469         // check for CoE response again
   543         // check for CoE response again
   470         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   544         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   471         fsm->retries = EC_FSM_RETRIES;
   545         fsm->retries = EC_FSM_RETRIES;
   472         fsm->state = ec_fsm_coe_dict_check;
   546         fsm->state = ec_fsm_coe_dict_check;
   473         return;
   547         return;
   474     }
   548     }
   475 
   549 
   499         if (fsm->slave->master->debug_level) {
   573         if (fsm->slave->master->debug_level) {
   500             EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
   574             EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
   501                     " Retrying...\n");
   575                     " Retrying...\n");
   502             ec_print_data(data, rec_size);
   576             ec_print_data(data, rec_size);
   503         }
   577         }
   504         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   578         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   505         fsm->retries = EC_FSM_RETRIES;
   579         fsm->retries = EC_FSM_RETRIES;
   506         fsm->state = ec_fsm_coe_dict_check;
   580         fsm->state = ec_fsm_coe_dict_check;
   507         return;
   581         return;
   508     }
   582     }
   509 
   583 
   510     first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
   584     first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
   511     index_list_offset = first_segment ? 8 : 6;
   585     index_list_offset = first_segment ? 8 : 6;
   512 
   586 
   513     if (rec_size < index_list_offset || rec_size % 2) {
   587     if (rec_size < index_list_offset || rec_size % 2) {
   514         EC_SLAVE_ERR(slave, "Invalid data size %zu !\n", rec_size);
   588         EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
   515         ec_print_data(data, rec_size);
   589         ec_print_data(data, rec_size);
   516         fsm->state = ec_fsm_coe_error;
   590         fsm->state = ec_fsm_coe_error;
   517         return;
   591         return;
   518     }
   592     }
   519 
   593 
   542                 fragments_left);
   616                 fragments_left);
   543     }
   617     }
   544 
   618 
   545     if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
   619     if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
   546         // more messages waiting. check again.
   620         // more messages waiting. check again.
   547         fsm->jiffies_start = datagram->jiffies_sent;
   621         fsm->jiffies_start = fsm->datagram->jiffies_sent;
   548         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   622         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   549         fsm->retries = EC_FSM_RETRIES;
   623         fsm->retries = EC_FSM_RETRIES;
   550         fsm->state = ec_fsm_coe_dict_check;
   624         fsm->state = ec_fsm_coe_dict_check;
   551         return;
   625         return;
   552     }
   626     }
   553 
   627 
   558     }
   632     }
   559 
   633 
   560     // fetch SDO descriptions
   634     // fetch SDO descriptions
   561     fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
   635     fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);
   562 
   636 
   563     data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 8);
       
   564     if (IS_ERR(data)) {
       
   565         fsm->state = ec_fsm_coe_error;
       
   566         return;
       
   567     }
       
   568 
       
   569     EC_WRITE_U16(data, 0x8 << 12); // SDO information
       
   570     EC_WRITE_U8 (data + 2, 0x03); // Get object description request
       
   571     EC_WRITE_U8 (data + 3, 0x00);
       
   572     EC_WRITE_U16(data + 4, 0x0000);
       
   573     EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
       
   574 
       
   575     fsm->retries = EC_FSM_RETRIES;
   637     fsm->retries = EC_FSM_RETRIES;
   576     fsm->state = ec_fsm_coe_dict_desc_request;
   638     if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
       
   639         fsm->state = ec_fsm_coe_error;
       
   640     }
   577 }
   641 }
   578 
   642 
   579 /*****************************************************************************/
   643 /*****************************************************************************/
   580 
   644 
   581 /**
   645 /**
   582    CoE state: DICT DESC REQUEST.
   646    CoE state: DICT DESC REQUEST.
   583    \todo Timeout behavior
   647    \todo Timeout behavior
   584 */
   648 */
   585 
   649 
   586 void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *fsm /**< finite state machine */)
   650 void ec_fsm_coe_dict_desc_request(
   587 {
   651         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   588     ec_mailbox_t *mbox = fsm->mbox;
   652         ec_datagram_t *datagram /**< Datagram to use. */
   589     ec_datagram_t *datagram = mbox->datagram;
   653         )
   590     ec_slave_t *slave = fsm->slave;
   654 {
   591 
   655     ec_slave_t *slave = fsm->slave;
   592     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
   656 
   593             && fsm->retries--)
   657     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   594         return; // FIXME: check for response first?
   658         if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
   595 
   659             fsm->state = ec_fsm_coe_error;
   596     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   660         }
       
   661         return;
       
   662     }
       
   663 
       
   664     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   597         fsm->state = ec_fsm_coe_error;
   665         fsm->state = ec_fsm_coe_error;
   598         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
   666         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
   599                 " description request datagram: ");
   667                 " description request datagram: ");
   600         ec_datagram_print_state(datagram);
   668         ec_datagram_print_state(fsm->datagram);
   601         return;
   669         return;
   602     }
   670     }
   603 
   671 
   604     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   672     if (fsm->datagram->working_counter != 1) {
   605         fsm->state = ec_fsm_coe_error;
   673         fsm->state = ec_fsm_coe_error;
   606         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
   674         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
   607                 " request failed: ");
   675                 " request failed: ");
   608         ec_datagram_print_wc_error(datagram);
   676         ec_datagram_print_wc_error(fsm->datagram);
   609         return;
   677         return;
   610     }
   678     }
   611 
   679 
   612     fsm->jiffies_start = datagram->jiffies_sent;
   680     fsm->jiffies_start = fsm->datagram->jiffies_sent;
   613 
   681 
   614     ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   682     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   615     fsm->retries = EC_FSM_RETRIES;
   683     fsm->retries = EC_FSM_RETRIES;
   616     fsm->state = ec_fsm_coe_dict_desc_check;
   684     fsm->state = ec_fsm_coe_dict_desc_check;
   617 }
   685 }
   618 
   686 
   619 /*****************************************************************************/
   687 /*****************************************************************************/
   620 
   688 
   621 /**
   689 /**
   622    CoE state: DICT DESC CHECK.
   690    CoE state: DICT DESC CHECK.
   623 */
   691 */
   624 
   692 
   625 void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *fsm /**< finite state machine */)
   693 void ec_fsm_coe_dict_desc_check(
   626 {
   694         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   627     ec_mailbox_t *mbox = fsm->mbox;
   695         ec_datagram_t *datagram /**< Datagram to use. */
   628     ec_datagram_t *datagram = mbox->datagram;
   696         )
   629     ec_slave_t *slave = fsm->slave;
   697 {
   630 
   698     ec_slave_t *slave = fsm->slave;
   631     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
   699 
   632             && fsm->retries--) {
   700     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   633         return;
   701         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   634     }
   702         return;
   635 
   703     }
   636     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   704 
       
   705     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   637         fsm->state = ec_fsm_coe_error;
   706         fsm->state = ec_fsm_coe_error;
   638         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
   707         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
   639         ec_datagram_print_state(datagram);
   708         ec_datagram_print_state(fsm->datagram);
   640         return;
   709         return;
   641     }
   710     }
   642 
   711 
   643     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   712     if (fsm->datagram->working_counter != 1) {
   644         fsm->state = ec_fsm_coe_error;
   713         fsm->state = ec_fsm_coe_error;
   645         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
   714         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
   646                 " datagram failed: ");
   715                 " datagram failed: ");
   647         ec_datagram_print_wc_error(datagram);
   716         ec_datagram_print_wc_error(fsm->datagram);
   648         return;
   717         return;
   649     }
   718     }
   650 
   719 
   651     if (!ec_slave_mbox_check(mbox)) {
   720     if (!ec_slave_mbox_check(fsm->datagram)) {
   652         unsigned long diff_ms =
   721         unsigned long diff_ms =
   653             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
   722             (fsm->datagram->jiffies_received - fsm->jiffies_start) *
       
   723             1000 / HZ;
   654         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
   724         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
   655             fsm->state = ec_fsm_coe_error;
   725             fsm->state = ec_fsm_coe_error;
   656             EC_SLAVE_ERR(slave, "Timeout while waiting for"
   726             EC_SLAVE_ERR(slave, "Timeout while waiting for"
   657                     " SDO 0x%04x object description response.\n",
   727                     " SDO 0x%04x object description response.\n",
   658                     fsm->sdo->index);
   728                     fsm->sdo->index);
   659             return;
   729             return;
   660         }
   730         }
   661 
   731 
   662         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   732         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   663         fsm->retries = EC_FSM_RETRIES;
   733         fsm->retries = EC_FSM_RETRIES;
   664         return;
   734         return;
   665     }
   735     }
   666 
   736 
   667     // Fetch response
   737     // Fetch response
   668     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
   738     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   669     fsm->retries = EC_FSM_RETRIES;
   739     fsm->retries = EC_FSM_RETRIES;
   670     fsm->state = ec_fsm_coe_dict_desc_response;
   740     fsm->state = ec_fsm_coe_dict_desc_response;
       
   741 }
       
   742 
       
   743 /*****************************************************************************/
       
   744 
       
   745 /** Prepare an entry description request.
       
   746  *
       
   747  * \return Zero on success, otherwise a negative error code.
       
   748  */
       
   749 int ec_fsm_coe_dict_prepare_entry(
       
   750         ec_fsm_coe_t *fsm, /**< Finite state machine */
       
   751         ec_datagram_t *datagram /**< Datagram to use. */
       
   752         )
       
   753 {
       
   754     ec_slave_t *slave = fsm->slave;
       
   755     u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
       
   756     if (IS_ERR(data)) {
       
   757         return PTR_ERR(data);
       
   758     }
       
   759 
       
   760     EC_WRITE_U16(data, 0x8 << 12); // SDO information
       
   761     EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
       
   762     EC_WRITE_U8 (data + 3, 0x00);
       
   763     EC_WRITE_U16(data + 4, 0x0000);
       
   764     EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
       
   765     EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
       
   766     EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
       
   767 
       
   768     fsm->state = ec_fsm_coe_dict_entry_request;
       
   769     return 0;
   671 }
   770 }
   672 
   771 
   673 /*****************************************************************************/
   772 /*****************************************************************************/
   674 
   773 
   675 /**
   774 /**
   676    CoE state: DICT DESC RESPONSE.
   775    CoE state: DICT DESC RESPONSE.
   677    \todo Timeout behavior
   776    \todo Timeout behavior
   678 */
   777 */
   679 
   778 
   680 void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *fsm
   779 void ec_fsm_coe_dict_desc_response(
   681                                    /**< finite state machine */)
   780         ec_fsm_coe_t *fsm, /**< Finite state machine */
   682 {
   781         ec_datagram_t *datagram /**< Datagram to use. */
   683     ec_mailbox_t *mbox = fsm->mbox;
   782         )
   684     ec_datagram_t *datagram = mbox->datagram;
   783 {
   685     ec_slave_t *slave = fsm->slave;
   784     ec_slave_t *slave = fsm->slave;
   686     ec_sdo_t *sdo = fsm->sdo;
   785     ec_sdo_t *sdo = fsm->sdo;
   687     uint8_t *data, mbox_prot;
   786     uint8_t *data, mbox_prot;
   688     size_t rec_size, name_size;
   787     size_t rec_size, name_size;
   689 
   788 
   690     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
   789     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   691             && fsm->retries--) {
   790         ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   692         return; // FIXME: request again?
   791         return;
   693     }
   792     }
   694 
   793 
   695     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   794     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   696         fsm->state = ec_fsm_coe_error;
   795         fsm->state = ec_fsm_coe_error;
   697         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
   796         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
   698                 " response datagram: ");
   797                 " response datagram: ");
   699         ec_datagram_print_state(datagram);
   798         ec_datagram_print_state(fsm->datagram);
   700         return;
   799         return;
   701     }
   800     }
   702 
   801 
   703     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   802     if (fsm->datagram->working_counter != 1) {
   704         fsm->state = ec_fsm_coe_error;
   803         fsm->state = ec_fsm_coe_error;
   705         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
   804         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
   706                 " response failed: ");
   805                 " response failed: ");
   707         ec_datagram_print_wc_error(datagram);
   806         ec_datagram_print_wc_error(fsm->datagram);
   708         return;
   807         return;
   709     }
   808     }
   710 
   809 
   711     data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
   810     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
   712     if (IS_ERR(data)) {
   811     if (IS_ERR(data)) {
   713         fsm->state = ec_fsm_coe_error;
   812         fsm->state = ec_fsm_coe_error;
   714         return;
   813         return;
   715     }
   814     }
   716 
   815 
   721         return;
   820         return;
   722     }
   821     }
   723 
   822 
   724     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
   823     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
   725         // check for CoE response again
   824         // check for CoE response again
   726         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   825         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   727         fsm->retries = EC_FSM_RETRIES;
   826         fsm->retries = EC_FSM_RETRIES;
   728         fsm->state = ec_fsm_coe_dict_desc_check;
   827         fsm->state = ec_fsm_coe_dict_desc_check;
   729         return;
   828         return;
   730     }
   829     }
   731 
   830 
   759             EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
   858             EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
   760                     " fetching SDO 0x%04X!\n", sdo->index);
   859                     " fetching SDO 0x%04X!\n", sdo->index);
   761             ec_print_data(data, rec_size);
   860             ec_print_data(data, rec_size);
   762         }
   861         }
   763         // check for CoE response again
   862         // check for CoE response again
   764         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   863         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   765         fsm->retries = EC_FSM_RETRIES;
   864         fsm->retries = EC_FSM_RETRIES;
   766         fsm->state = ec_fsm_coe_dict_desc_check;
   865         fsm->state = ec_fsm_coe_dict_desc_check;
   767         return;
   866         return;
   768     }
   867     }
   769 
   868 
   796     }
   895     }
   797 
   896 
   798     // start fetching entries
   897     // start fetching entries
   799 
   898 
   800     fsm->subindex = 0;
   899     fsm->subindex = 0;
   801 
       
   802     data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 10);
       
   803     if (IS_ERR(data)) {
       
   804         fsm->state = ec_fsm_coe_error;
       
   805         return;
       
   806     }
       
   807 
       
   808     EC_WRITE_U16(data, 0x8 << 12); // SDO information
       
   809     EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
       
   810     EC_WRITE_U8 (data + 3, 0x00);
       
   811     EC_WRITE_U16(data + 4, 0x0000);
       
   812     EC_WRITE_U16(data + 6, sdo->index); // SDO index
       
   813     EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
       
   814     EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)
       
   815 
       
   816     fsm->retries = EC_FSM_RETRIES;
   900     fsm->retries = EC_FSM_RETRIES;
   817     fsm->state = ec_fsm_coe_dict_entry_request;
   901 
       
   902     if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
       
   903         fsm->state = ec_fsm_coe_error;
       
   904     }
   818 }
   905 }
   819 
   906 
   820 /*****************************************************************************/
   907 /*****************************************************************************/
   821 
   908 
   822 /**
   909 /**
   823    CoE state: DICT ENTRY REQUEST.
   910    CoE state: DICT ENTRY REQUEST.
   824    \todo Timeout behavior
   911    \todo Timeout behavior
   825 */
   912 */
   826 
   913 
   827 void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *fsm
   914 void ec_fsm_coe_dict_entry_request(
   828                                    /**< finite state machine */)
   915         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   829 {
   916         ec_datagram_t *datagram /**< Datagram to use. */
   830     ec_mailbox_t *mbox = fsm->mbox;
   917         )
   831     ec_datagram_t *datagram = mbox->datagram;
   918 {
   832     ec_slave_t *slave = fsm->slave;
   919     ec_slave_t *slave = fsm->slave;
   833 
   920 
   834     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
   921     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   835             && fsm->retries--) {
   922         if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
   836         return; // FIXME: check for response first?
   923             fsm->state = ec_fsm_coe_error;
   837     }
   924         }
   838 
   925         return;
   839     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   926     }
       
   927 
       
   928     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   840         fsm->state = ec_fsm_coe_error;
   929         fsm->state = ec_fsm_coe_error;
   841         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
   930         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
   842                 " request datagram: ");
   931                 " request datagram: ");
   843         ec_datagram_print_state(datagram);
   932         ec_datagram_print_state(fsm->datagram);
   844         return;
   933         return;
   845     }
   934     }
   846 
   935 
   847     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   936     if (fsm->datagram->working_counter != 1) {
   848         fsm->state = ec_fsm_coe_error;
   937         fsm->state = ec_fsm_coe_error;
   849         EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
   938         EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
   850         ec_datagram_print_wc_error(datagram);
   939         ec_datagram_print_wc_error(fsm->datagram);
   851         return;
   940         return;
   852     }
   941     }
   853 
   942 
   854     fsm->jiffies_start = datagram->jiffies_sent;
   943     fsm->jiffies_start = fsm->datagram->jiffies_sent;
   855 
   944 
   856     ec_slave_mbox_prepare_check(slave, mbox); // can not fail
   945     ec_slave_mbox_prepare_check(slave, datagram); // can not fail
   857     fsm->retries = EC_FSM_RETRIES;
   946     fsm->retries = EC_FSM_RETRIES;
   858     fsm->state = ec_fsm_coe_dict_entry_check;
   947     fsm->state = ec_fsm_coe_dict_entry_check;
   859 }
   948 }
   860 
   949 
   861 /*****************************************************************************/
   950 /*****************************************************************************/
   862 
   951 
   863 /**
   952 /**
   864    CoE state: DICT ENTRY CHECK.
   953    CoE state: DICT ENTRY CHECK.
   865 */
   954 */
   866 
   955 
   867 void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *fsm
   956 void ec_fsm_coe_dict_entry_check(
   868                                  /**< finite state machine */)
   957         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   869 {
   958         ec_datagram_t *datagram /**< Datagram to use. */
   870     ec_mailbox_t *mbox = fsm->mbox;
   959         )
   871     ec_datagram_t *datagram = mbox->datagram;
   960 {
   872     ec_slave_t *slave = fsm->slave;
   961     ec_slave_t *slave = fsm->slave;
   873 
   962 
   874     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
   963     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   875             && fsm->retries--) {
   964         ec_slave_mbox_prepare_check(slave, datagram); // can not fail
   876         return;
   965         return;
   877     }
   966     }
   878 
   967 
   879     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
   968     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   880         fsm->state = ec_fsm_coe_error;
   969         fsm->state = ec_fsm_coe_error;
   881         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
   970         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
   882         ec_datagram_print_state(datagram);
   971         ec_datagram_print_state(fsm->datagram);
   883         return;
   972         return;
   884     }
   973     }
   885 
   974 
   886     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
   975     if (fsm->datagram->working_counter != 1) {
   887         fsm->state = ec_fsm_coe_error;
   976         fsm->state = ec_fsm_coe_error;
   888         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
   977         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
   889                 " datagram failed: ");
   978                 " datagram failed: ");
   890         ec_datagram_print_wc_error(datagram);
   979         ec_datagram_print_wc_error(fsm->datagram);
   891         return;
   980         return;
   892     }
   981     }
   893 
   982 
   894     if (!ec_slave_mbox_check(mbox)) {
   983     if (!ec_slave_mbox_check(fsm->datagram)) {
   895         unsigned long diff_ms =
   984         unsigned long diff_ms =
   896             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
   985             (fsm->datagram->jiffies_received - fsm->jiffies_start) *
       
   986             1000 / HZ;
   897         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
   987         if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
   898             fsm->state = ec_fsm_coe_error;
   988             fsm->state = ec_fsm_coe_error;
   899             EC_SLAVE_ERR(slave, "Timeout while waiting for"
   989             EC_SLAVE_ERR(slave, "Timeout while waiting for"
   900                     " SDO entry 0x%04x:%x description response.\n",
   990                     " SDO entry 0x%04x:%x description response.\n",
   901                     fsm->sdo->index, fsm->subindex);
   991                     fsm->sdo->index, fsm->subindex);
   902             return;
   992             return;
   903         }
   993         }
   904 
   994 
   905         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   995         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   906         fsm->retries = EC_FSM_RETRIES;
   996         fsm->retries = EC_FSM_RETRIES;
   907         return;
   997         return;
   908     }
   998     }
   909 
   999 
   910     // Fetch response
  1000     // Fetch response
   911     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
  1001     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   912     fsm->retries = EC_FSM_RETRIES;
  1002     fsm->retries = EC_FSM_RETRIES;
   913     fsm->state = ec_fsm_coe_dict_entry_response;
  1003     fsm->state = ec_fsm_coe_dict_entry_response;
   914 }
  1004 }
   915 
  1005 
   916 /*****************************************************************************/
  1006 /*****************************************************************************/
   918 /**
  1008 /**
   919    CoE state: DICT ENTRY RESPONSE.
  1009    CoE state: DICT ENTRY RESPONSE.
   920    \todo Timeout behavior
  1010    \todo Timeout behavior
   921 */
  1011 */
   922 
  1012 
   923 void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *fsm
  1013 void ec_fsm_coe_dict_entry_response(
   924                                     /**< finite state machine */)
  1014         ec_fsm_coe_t *fsm, /**< Finite state machine. */
   925 {
  1015         ec_datagram_t *datagram /**< Datagram to use. */
   926     ec_mailbox_t *mbox = fsm->mbox;
  1016         )
   927     ec_datagram_t *datagram = mbox->datagram;
  1017 {
   928     ec_slave_t *slave = fsm->slave;
  1018     ec_slave_t *slave = fsm->slave;
   929     ec_sdo_t *sdo = fsm->sdo;
  1019     ec_sdo_t *sdo = fsm->sdo;
   930     uint8_t *data, mbox_prot;
  1020     uint8_t *data, mbox_prot;
   931     size_t rec_size, data_size;
  1021     size_t rec_size, data_size;
   932     ec_sdo_entry_t *entry;
  1022     ec_sdo_entry_t *entry;
   933     u16 word;
  1023     u16 word;
   934 
  1024 
   935     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  1025     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   936             && fsm->retries--) {
  1026         ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   937         return; // FIXME: request again?
  1027         return;
   938     }
  1028     }
   939 
  1029 
   940     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  1030     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
   941         fsm->state = ec_fsm_coe_error;
  1031         fsm->state = ec_fsm_coe_error;
   942         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
  1032         EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
   943                 " description response datagram: ");
  1033                 " description response datagram: ");
   944         ec_datagram_print_state(datagram);
  1034         ec_datagram_print_state(fsm->datagram);
   945         return;
  1035         return;
   946     }
  1036     }
   947 
  1037 
   948     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  1038     if (fsm->datagram->working_counter != 1) {
   949         fsm->state = ec_fsm_coe_error;
  1039         fsm->state = ec_fsm_coe_error;
   950         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
  1040         EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
   951                 " response failed: ");
  1041                 " response failed: ");
   952         ec_datagram_print_wc_error(datagram);
  1042         ec_datagram_print_wc_error(fsm->datagram);
   953         return;
  1043         return;
   954     }
  1044     }
   955 
  1045 
   956     data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
  1046     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
   957     if (IS_ERR(data)) {
  1047     if (IS_ERR(data)) {
   958         fsm->state = ec_fsm_coe_error;
  1048         fsm->state = ec_fsm_coe_error;
   959         return;
  1049         return;
   960     }
  1050     }
   961 
  1051 
   966         return;
  1056         return;
   967     }
  1057     }
   968 
  1058 
   969     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  1059     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
   970         // check for CoE response again
  1060         // check for CoE response again
   971         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1061         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   972         fsm->retries = EC_FSM_RETRIES;
  1062         fsm->retries = EC_FSM_RETRIES;
   973         fsm->state = ec_fsm_coe_dict_entry_check;
  1063         fsm->state = ec_fsm_coe_dict_entry_check;
   974         return;
  1064         return;
   975     }
  1065     }
   976 
  1066 
   999             fsm->state = ec_fsm_coe_error;
  1089             fsm->state = ec_fsm_coe_error;
  1000             return;
  1090             return;
  1001         }
  1091         }
  1002 
  1092 
  1003         if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
  1093         if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
  1004                 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. resp.
  1094             (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
  1005                 EC_READ_U16(data + 6) != sdo->index || // SDO index
  1095             EC_READ_U16(data + 6) != sdo->index || // SDO index
  1006                 EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
  1096             EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
  1007             if (fsm->slave->master->debug_level) {
  1097             if (fsm->slave->master->debug_level) {
  1008                 EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
  1098                 EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
  1009                         " while fetching SDO entry 0x%04X:%02X!\n",
  1099                         " while fetching SDO entry 0x%04X:%02X!\n",
  1010                         sdo->index, fsm->subindex);
  1100                         sdo->index, fsm->subindex);
  1011                 ec_print_data(data, rec_size);
  1101                 ec_print_data(data, rec_size);
  1012             }
  1102             }
  1013             // check for CoE response again
  1103             // check for CoE response again
  1014             ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1104             ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1015             fsm->retries = EC_FSM_RETRIES;
  1105             fsm->retries = EC_FSM_RETRIES;
  1016             fsm->state = ec_fsm_coe_dict_entry_check;
  1106             fsm->state = ec_fsm_coe_dict_entry_check;
  1017             return;
  1107             return;
  1018         }
  1108         }
  1019 
  1109 
  1025         }
  1115         }
  1026 
  1116 
  1027         data_size = rec_size - 16;
  1117         data_size = rec_size - 16;
  1028 
  1118 
  1029         if (!(entry = (ec_sdo_entry_t *)
  1119         if (!(entry = (ec_sdo_entry_t *)
  1030                     kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
  1120               kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
  1031             EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
  1121             EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
  1032             fsm->state = ec_fsm_coe_error;
  1122             fsm->state = ec_fsm_coe_error;
  1033             return;
  1123             return;
  1034         }
  1124         }
  1035 
  1125 
  1038         entry->bit_length = EC_READ_U16(data + 12);
  1128         entry->bit_length = EC_READ_U16(data + 12);
  1039 
  1129 
  1040         // read access rights
  1130         // read access rights
  1041         word = EC_READ_U16(data + 14);
  1131         word = EC_READ_U16(data + 14);
  1042         entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
  1132         entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
  1043         entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 1)  & 0x0001;
  1133         entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
       
  1134             (word >> 1)  & 0x0001;
  1044         entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2)  & 0x0001;
  1135         entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2)  & 0x0001;
  1045         entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
  1136         entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
  1046         entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 4)  & 0x0001;
  1137         entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
       
  1138             (word >> 4)  & 0x0001;
  1047         entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5)  & 0x0001;
  1139         entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5)  & 0x0001;
  1048 
  1140 
  1049         if (data_size) {
  1141         if (data_size) {
  1050             uint8_t *desc;
  1142             uint8_t *desc;
  1051             if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
  1143             if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
  1060 
  1152 
  1061         list_add_tail(&entry->list, &sdo->entries);
  1153         list_add_tail(&entry->list, &sdo->entries);
  1062     }
  1154     }
  1063 
  1155 
  1064     if (fsm->subindex < sdo->max_subindex) {
  1156     if (fsm->subindex < sdo->max_subindex) {
       
  1157 
  1065         fsm->subindex++;
  1158         fsm->subindex++;
  1066 
  1159         fsm->retries = EC_FSM_RETRIES;
  1067         data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 10);
  1160 
  1068         if (IS_ERR(data)) {
  1161         if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
  1069             fsm->state = ec_fsm_coe_error;
  1162             fsm->state = ec_fsm_coe_error;
  1070             return;
  1163         }
  1071         }
  1164 
  1072 
       
  1073         EC_WRITE_U16(data, 0x8 << 12); // SDO information
       
  1074         EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
       
  1075         EC_WRITE_U8 (data + 3, 0x00);
       
  1076         EC_WRITE_U16(data + 4, 0x0000);
       
  1077         EC_WRITE_U16(data + 6, sdo->index); // SDO index
       
  1078         EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
       
  1079         EC_WRITE_U8 (data + 9, 0x00); // value info (no values)
       
  1080 
       
  1081         fsm->retries = EC_FSM_RETRIES;
       
  1082         fsm->state = ec_fsm_coe_dict_entry_request;
       
  1083         return;
  1165         return;
  1084     }
  1166     }
  1085 
  1167 
  1086     // another SDO description to fetch?
  1168     // another SDO description to fetch?
  1087     if (fsm->sdo->list.next != &slave->sdo_dictionary) {
  1169     if (fsm->sdo->list.next != &slave->sdo_dictionary) {
       
  1170 
  1088         fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
  1171         fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
  1089 
  1172         fsm->retries = EC_FSM_RETRIES;
  1090         data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 8);
  1173 
  1091         if (IS_ERR(data)) {
  1174         if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
  1092             fsm->state = ec_fsm_coe_error;
  1175             fsm->state = ec_fsm_coe_error;
  1093             return;
  1176         }
  1094         }
  1177 
  1095 
       
  1096         EC_WRITE_U16(data, 0x8 << 12); // SDO information
       
  1097         EC_WRITE_U8 (data + 2, 0x03); // Get object description request
       
  1098         EC_WRITE_U8 (data + 3, 0x00);
       
  1099         EC_WRITE_U16(data + 4, 0x0000);
       
  1100         EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
       
  1101 
       
  1102         fsm->retries = EC_FSM_RETRIES;
       
  1103         fsm->state = ec_fsm_coe_dict_desc_request;
       
  1104         return;
  1178         return;
  1105     }
  1179     }
  1106 
  1180 
  1107     fsm->state = ec_fsm_coe_end;
  1181     fsm->state = ec_fsm_coe_end;
  1108 }
  1182 }
  1109 
  1183 
  1110 /******************************************************************************
  1184 /******************************************************************************
  1111  *  CoE state machine
  1185  *  CoE state machine
  1112  *****************************************************************************/
  1186  *****************************************************************************/
  1113 
  1187 
       
  1188 /** Prepare a donwnload request.
       
  1189  *
       
  1190  * \return Zero on success, otherwise a negative error code.
       
  1191  */
       
  1192 int ec_fsm_coe_prepare_down_start(
       
  1193         ec_fsm_coe_t *fsm, /**< Finite state machine. */
       
  1194         ec_datagram_t *datagram /**< Datagram to use. */
       
  1195         )
       
  1196 {
       
  1197     u8 *data;
       
  1198     ec_slave_t *slave = fsm->slave;
       
  1199     ec_sdo_request_t *request = fsm->request;
       
  1200     uint8_t data_set_size;
       
  1201 
       
  1202     if (request->data_size <= 4) { // use expedited transfer type
       
  1203         data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
       
  1204                 EC_COE_DOWN_REQ_HEADER_SIZE);
       
  1205         if (IS_ERR(data)) {
       
  1206             request->errno = PTR_ERR(data);
       
  1207             return PTR_ERR(data);
       
  1208         }
       
  1209 
       
  1210         fsm->remaining = 0;
       
  1211 
       
  1212         data_set_size = 4 - request->data_size;
       
  1213 
       
  1214         EC_WRITE_U16(data, 0x2 << 12); // SDO request
       
  1215         EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
       
  1216                     | data_set_size << 2
       
  1217                     | ((request->complete_access ? 1 : 0) << 4)
       
  1218                     | 0x1 << 5)); // Download request
       
  1219         EC_WRITE_U16(data + 3, request->index);
       
  1220         EC_WRITE_U8 (data + 5,
       
  1221                 request->complete_access ? 0x00 : request->subindex);
       
  1222         memcpy(data + 6, request->data, request->data_size);
       
  1223         memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
       
  1224 
       
  1225         if (slave->master->debug_level) {
       
  1226             EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
       
  1227             ec_print_data(data, EC_COE_DOWN_REQ_HEADER_SIZE);
       
  1228         }
       
  1229     }
       
  1230     else { // request->data_size > 4, use normal transfer type
       
  1231         size_t data_size,
       
  1232                max_data_size =
       
  1233                    slave->configured_rx_mailbox_size - EC_MBOX_HEADER_SIZE,
       
  1234                required_data_size =
       
  1235                    EC_COE_DOWN_REQ_HEADER_SIZE + request->data_size;
       
  1236 
       
  1237         if (max_data_size < required_data_size) {
       
  1238             // segmenting needed
       
  1239             data_size = max_data_size;
       
  1240         } else {
       
  1241             data_size = required_data_size;
       
  1242         }
       
  1243 
       
  1244         data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
       
  1245                 data_size);
       
  1246         if (IS_ERR(data)) {
       
  1247             request->errno = PTR_ERR(data);
       
  1248             return PTR_ERR(data);
       
  1249         }
       
  1250 
       
  1251         fsm->offset = 0;
       
  1252         fsm->remaining = request->data_size;
       
  1253 
       
  1254         EC_WRITE_U16(data, 0x2 << 12); // SDO request
       
  1255         EC_WRITE_U8(data + 2,
       
  1256                 0x1 // size indicator, normal
       
  1257                 | ((request->complete_access ? 1 : 0) << 4)
       
  1258                 | 0x1 << 5); // Download request
       
  1259         EC_WRITE_U16(data + 3, request->index);
       
  1260         EC_WRITE_U8 (data + 5,
       
  1261                 request->complete_access ? 0x00 : request->subindex);
       
  1262         EC_WRITE_U32(data + 6, request->data_size);
       
  1263 
       
  1264         if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
       
  1265             size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
       
  1266             memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
       
  1267                     request->data, segment_size);
       
  1268             fsm->offset += segment_size;
       
  1269             fsm->remaining -= segment_size;
       
  1270         }
       
  1271 
       
  1272         if (slave->master->debug_level) {
       
  1273             EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
       
  1274             ec_print_data(data, data_size);
       
  1275         }
       
  1276     }
       
  1277 
       
  1278     fsm->state = ec_fsm_coe_down_request;
       
  1279     return 0;
       
  1280 }
       
  1281 
       
  1282 /****************************************************************************/
       
  1283 
  1114 /** CoE state: DOWN START.
  1284 /** CoE state: DOWN START.
  1115  */
  1285  */
  1116 void ec_fsm_coe_down_start(
  1286 void ec_fsm_coe_down_start(
  1117         ec_fsm_coe_t *fsm /**< finite state machine */
  1287         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1118         )
  1288         ec_datagram_t *datagram /**< Datagram to use. */
  1119 {
  1289         )
  1120     ec_mailbox_t *mbox = fsm->mbox;
  1290 {
  1121     ec_slave_t *slave = fsm->slave;
  1291     ec_slave_t *slave = fsm->slave;
  1122     ec_sdo_request_t *request = fsm->request;
  1292     ec_sdo_request_t *request = fsm->request;
  1123     uint8_t *data;
       
  1124     uint8_t data_set_size;
       
  1125 
  1293 
  1126     if (fsm->slave->master->debug_level) {
  1294     if (fsm->slave->master->debug_level) {
  1127         char subidxstr[10];
  1295         char subidxstr[10];
  1128         if (request->complete_access) {
  1296         if (request->complete_access) {
  1129             subidxstr[0] = 0x00;
  1297             subidxstr[0] = 0x00;
  1140         request->errno = EPROTONOSUPPORT;
  1308         request->errno = EPROTONOSUPPORT;
  1141         fsm->state = ec_fsm_coe_error;
  1309         fsm->state = ec_fsm_coe_error;
  1142         return;
  1310         return;
  1143     }
  1311     }
  1144 
  1312 
  1145     if (slave->configured_rx_mailbox_size < 
  1313     if (slave->configured_rx_mailbox_size <
  1146             EC_MBOX_HEADER_SIZE + EC_COE_DOWN_REQ_HEADER_SIZE) {
  1314             EC_MBOX_HEADER_SIZE + EC_COE_DOWN_REQ_HEADER_SIZE) {
  1147         EC_SLAVE_ERR(slave, "Mailbox too small!\n");
  1315         EC_SLAVE_ERR(slave, "Mailbox too small!\n");
  1148         request->errno = EOVERFLOW;
  1316         request->errno = EOVERFLOW;
  1149         fsm->state = ec_fsm_coe_error;
  1317         fsm->state = ec_fsm_coe_error;
  1150         return;
  1318         return;
  1151     }
  1319     }
  1152 
  1320 
  1153     if (request->data_size <= 4) { // use expedited transfer type
       
  1154         data = ec_slave_mbox_prepare_send(slave, mbox, 0x03,
       
  1155                 EC_COE_DOWN_REQ_HEADER_SIZE);
       
  1156         if (IS_ERR(data)) {
       
  1157             request->errno = PTR_ERR(data);
       
  1158             fsm->state = ec_fsm_coe_error;
       
  1159             return;
       
  1160         }
       
  1161 
       
  1162         fsm->remaining = 0;
       
  1163 
       
  1164         data_set_size = 4 - request->data_size;
       
  1165 
       
  1166         EC_WRITE_U16(data, 0x2 << 12); // SDO request
       
  1167         EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
       
  1168                     | data_set_size << 2
       
  1169                     | ((request->complete_access ? 1 : 0) << 4) 
       
  1170                     | 0x1 << 5)); // Download request
       
  1171         EC_WRITE_U16(data + 3, request->index);
       
  1172         EC_WRITE_U8 (data + 5,
       
  1173                 request->complete_access ? 0x00 : request->subindex);
       
  1174         memcpy(data + 6, request->data, request->data_size);
       
  1175         memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);
       
  1176 
       
  1177         if (slave->master->debug_level) {
       
  1178             EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
       
  1179             ec_print_data(data, EC_COE_DOWN_REQ_HEADER_SIZE);
       
  1180         }
       
  1181     }
       
  1182     else { // request->data_size > 4, use normal transfer type
       
  1183         size_t data_size,
       
  1184                max_data_size =
       
  1185                    slave->configured_rx_mailbox_size - EC_MBOX_HEADER_SIZE,
       
  1186                required_data_size =
       
  1187                    EC_COE_DOWN_REQ_HEADER_SIZE + request->data_size;
       
  1188 
       
  1189         if (max_data_size < required_data_size) {
       
  1190             // segmenting needed
       
  1191             data_size = max_data_size;
       
  1192         } else {
       
  1193             data_size = required_data_size;
       
  1194         }
       
  1195 
       
  1196         data = ec_slave_mbox_prepare_send(slave, mbox, 0x03,
       
  1197                 data_size);
       
  1198         if (IS_ERR(data)) {
       
  1199             request->errno = PTR_ERR(data);
       
  1200             fsm->state = ec_fsm_coe_error;
       
  1201             return;
       
  1202         }
       
  1203 
       
  1204         fsm->offset = 0;
       
  1205         fsm->remaining = request->data_size;
       
  1206 
       
  1207         EC_WRITE_U16(data, 0x2 << 12); // SDO request
       
  1208         EC_WRITE_U8(data + 2,
       
  1209                 0x1 // size indicator, normal
       
  1210                 | ((request->complete_access ? 1 : 0) << 4) 
       
  1211                 | 0x1 << 5); // Download request
       
  1212         EC_WRITE_U16(data + 3, request->index);
       
  1213         EC_WRITE_U8 (data + 5,
       
  1214                 request->complete_access ? 0x00 : request->subindex);
       
  1215         EC_WRITE_U32(data + 6, request->data_size);
       
  1216 
       
  1217         if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
       
  1218             size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
       
  1219             memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
       
  1220                     request->data, segment_size);
       
  1221             fsm->offset += segment_size;
       
  1222             fsm->remaining -= segment_size;
       
  1223         }
       
  1224 
       
  1225         if (slave->master->debug_level) {
       
  1226             EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
       
  1227             ec_print_data(data, data_size);
       
  1228         }
       
  1229     }
       
  1230 
  1321 
  1231     fsm->request->jiffies_sent = jiffies;
  1322     fsm->request->jiffies_sent = jiffies;
  1232     fsm->retries = EC_FSM_RETRIES;
  1323     fsm->retries = EC_FSM_RETRIES;
  1233     fsm->state = ec_fsm_coe_down_request;
  1324 
       
  1325     if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
       
  1326         fsm->state = ec_fsm_coe_error;
       
  1327     }
  1234 }
  1328 }
  1235 
  1329 
  1236 /*****************************************************************************/
  1330 /*****************************************************************************/
  1237 
  1331 
  1238 /**
  1332 /**
  1239    CoE state: DOWN REQUEST.
  1333    CoE state: DOWN REQUEST.
  1240    \todo Timeout behavior
  1334    \todo Timeout behavior
  1241 */
  1335 */
  1242 
  1336 
  1243 void ec_fsm_coe_down_request(ec_fsm_coe_t *fsm /**< finite state machine */)
  1337 void ec_fsm_coe_down_request(
  1244 {
  1338         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1245     ec_mailbox_t *mbox = fsm->mbox;
  1339         ec_datagram_t *datagram /**< Datagram to use. */
  1246     ec_datagram_t *datagram = mbox->datagram;
  1340         )
       
  1341 {
  1247     ec_slave_t *slave = fsm->slave;
  1342     ec_slave_t *slave = fsm->slave;
  1248     unsigned long diff_ms;
  1343     unsigned long diff_ms;
  1249 
  1344 
  1250     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  1345     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  1251             && fsm->retries--) {
  1346         if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
  1252         return; // FIXME: check for response first?
  1347             fsm->state = ec_fsm_coe_error;
  1253     }
  1348         }
  1254 
  1349         return;
  1255     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  1350     }
       
  1351 
       
  1352     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  1256         fsm->request->errno = EIO;
  1353         fsm->request->errno = EIO;
  1257         fsm->state = ec_fsm_coe_error;
  1354         fsm->state = ec_fsm_coe_error;
  1258         EC_SLAVE_ERR(slave, "Failed to receive CoE download"
  1355         EC_SLAVE_ERR(slave, "Failed to receive CoE download"
  1259                 " request datagram: ");
  1356                 " request datagram: ");
  1260         ec_datagram_print_state(datagram);
  1357         ec_datagram_print_state(fsm->datagram);
  1261         return;
  1358         return;
  1262     }
  1359     }
  1263 
  1360 
  1264     diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
  1361     diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
  1265 
  1362 
  1266     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  1363     if (fsm->datagram->working_counter != 1) {
  1267         if (ec_mbox_is_datagram_wc(mbox, 0)) {
  1364         if (!fsm->datagram->working_counter) {
  1268             if (diff_ms < fsm->request->response_timeout) {
  1365             if (diff_ms < fsm->request->response_timeout) {
  1269 #if DEBUG_RETRIES
  1366 #if DEBUG_RETRIES
  1270                 EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
  1367                 EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
  1271                         " download request. Retrying after %lu ms...\n",
  1368                         " download request. Retrying after %lu ms...\n",
  1272                         diff_ms);
  1369                         diff_ms);
  1273 #endif
  1370 #endif
  1274                 // no response; send request datagram again
  1371                 // no response; send request datagram again
       
  1372                 if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
       
  1373                     fsm->state = ec_fsm_coe_error;
       
  1374                 }
  1275                 return;
  1375                 return;
  1276             }
  1376             }
  1277         }
  1377         }
  1278         fsm->request->errno = EIO;
  1378         fsm->request->errno = EIO;
  1279         fsm->state = ec_fsm_coe_error;
  1379         fsm->state = ec_fsm_coe_error;
  1280         EC_SLAVE_ERR(slave, "Reception of CoE download request"
  1380         EC_SLAVE_ERR(slave, "Reception of CoE download request"
  1281                 " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
  1381                 " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
  1282                 fsm->request->index, fsm->request->subindex, diff_ms);
  1382                 fsm->request->index, fsm->request->subindex, diff_ms);
  1283         ec_datagram_print_wc_error(datagram);
  1383         ec_datagram_print_wc_error(fsm->datagram);
  1284         return;
  1384         return;
  1285     }
  1385     }
  1286 
  1386 
  1287 #if DEBUG_LONG
  1387 #if DEBUG_LONG
  1288     if (diff_ms > 200) {
  1388     if (diff_ms > 200) {
  1289         EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
  1389         EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
  1290                 fsm->request->index, fsm->request->subindex, diff_ms);
  1390                 fsm->request->index, fsm->request->subindex, diff_ms);
  1291     }
  1391     }
  1292 #endif
  1392 #endif
  1293 
  1393 
  1294     fsm->jiffies_start = datagram->jiffies_sent;
  1394     fsm->jiffies_start = fsm->datagram->jiffies_sent;
  1295 
  1395 
  1296     ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1396     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1297     fsm->retries = EC_FSM_RETRIES;
  1397     fsm->retries = EC_FSM_RETRIES;
  1298     fsm->state = ec_fsm_coe_down_check;
  1398     fsm->state = ec_fsm_coe_down_check;
  1299 }
  1399 }
  1300 
  1400 
  1301 /*****************************************************************************/
  1401 /*****************************************************************************/
  1302 
  1402 
  1303 /** CoE state: DOWN CHECK.
  1403 /** CoE state: DOWN CHECK.
  1304  */
  1404  */
  1305 void ec_fsm_coe_down_check(ec_fsm_coe_t *fsm /**< finite state machine */)
  1405 void ec_fsm_coe_down_check(
  1306 {
  1406         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1307     ec_mailbox_t *mbox = fsm->mbox;
  1407         ec_datagram_t *datagram /**< Datagram to use. */
  1308     ec_datagram_t *datagram = mbox->datagram;
  1408         )
  1309     ec_slave_t *slave = fsm->slave;
  1409 {
  1310 
  1410     ec_slave_t *slave = fsm->slave;
  1311     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  1411 
  1312             && fsm->retries--) {
  1412     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  1313         return;
  1413         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1314     }
  1414         return;
  1315 
  1415     }
  1316     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  1416 
       
  1417     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  1317         fsm->request->errno = EIO;
  1418         fsm->request->errno = EIO;
  1318         fsm->state = ec_fsm_coe_error;
  1419         fsm->state = ec_fsm_coe_error;
  1319         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
  1420         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
  1320                 " datagram: ");
  1421                 " datagram: ");
  1321         ec_datagram_print_state(datagram);
  1422         ec_datagram_print_state(fsm->datagram);
  1322         return;
  1423         return;
  1323     }
  1424     }
  1324 
  1425 
  1325     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  1426     if (fsm->datagram->working_counter != 1) {
  1326         fsm->request->errno = EIO;
  1427         fsm->request->errno = EIO;
  1327         fsm->state = ec_fsm_coe_error;
  1428         fsm->state = ec_fsm_coe_error;
  1328         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
  1429         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
  1329                 " datagram failed: ");
  1430                 " datagram failed: ");
  1330         ec_datagram_print_wc_error(datagram);
  1431         ec_datagram_print_wc_error(fsm->datagram);
  1331         return;
  1432         return;
  1332     }
  1433     }
  1333 
  1434 
  1334     if (!ec_slave_mbox_check(mbox)) {
  1435     if (!ec_slave_mbox_check(fsm->datagram)) {
  1335         unsigned long diff_ms =
  1436         unsigned long diff_ms =
  1336             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
  1437             (fsm->datagram->jiffies_received - fsm->jiffies_start) *
       
  1438             1000 / HZ;
  1337         if (diff_ms >= fsm->request->response_timeout) {
  1439         if (diff_ms >= fsm->request->response_timeout) {
  1338             fsm->request->errno = EIO;
  1440             fsm->request->errno = EIO;
  1339             fsm->state = ec_fsm_coe_error;
  1441             fsm->state = ec_fsm_coe_error;
  1340             EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
  1442             EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
  1341                     " for SDO 0x%04x:%x download response.\n", diff_ms,
  1443                     " for SDO 0x%04x:%x download response.\n", diff_ms,
  1342                     fsm->request->index, fsm->request->subindex);
  1444                     fsm->request->index, fsm->request->subindex);
  1343             return;
  1445             return;
  1344         }
  1446         }
  1345 
  1447 
  1346         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1448         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1347         fsm->retries = EC_FSM_RETRIES;
  1449         fsm->retries = EC_FSM_RETRIES;
  1348         return;
  1450         return;
  1349     }
  1451     }
  1350 
  1452 
  1351     // Fetch response
  1453     // Fetch response
  1352     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
  1454     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
  1353     fsm->retries = EC_FSM_RETRIES;
  1455     fsm->retries = EC_FSM_RETRIES;
  1354     fsm->state = ec_fsm_coe_down_response;
  1456     fsm->state = ec_fsm_coe_down_response;
  1355 }
  1457 }
  1356 
  1458 
  1357 /*****************************************************************************/
  1459 /*****************************************************************************/
  1358 
  1460 
  1359 /** Prepare a download segment request.
  1461 /** Prepare a download segment request.
  1360  */
  1462  */
  1361 void ec_fsm_coe_down_prepare_segment_request(
  1463 void ec_fsm_coe_down_prepare_segment_request(
  1362         ec_fsm_coe_t *fsm /**< finite state machine */
  1464         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1363         )
  1465         ec_datagram_t *datagram /**< Datagram to use. */
  1364 {
  1466         )
  1365     ec_mailbox_t *mbox = fsm->mbox;
  1467 {
  1366     ec_slave_t *slave = fsm->slave;
  1468     ec_slave_t *slave = fsm->slave;
  1367     ec_sdo_request_t *request = fsm->request;
  1469     ec_sdo_request_t *request = fsm->request;
  1368     size_t max_segment_size =
  1470     size_t max_segment_size =
  1369         slave->configured_rx_mailbox_size
  1471         slave->configured_rx_mailbox_size
  1370         - EC_MBOX_HEADER_SIZE
  1472         - EC_MBOX_HEADER_SIZE
  1371         - EC_COE_DOWN_SEG_REQ_HEADER_SIZE;
  1473         - EC_COE_DOWN_SEG_REQ_HEADER_SIZE;
  1372     size_t segment_size, data_size;
  1474     size_t data_size;
  1373     uint8_t last_segment, seg_data_size, *data;
  1475     uint8_t last_segment, seg_data_size, *data;
  1374 
  1476 
  1375     if (fsm->remaining > max_segment_size) {
  1477     if (fsm->remaining > max_segment_size) {
  1376         segment_size = max_segment_size;
  1478         fsm->segment_size = max_segment_size;
  1377         last_segment = 0;
  1479         last_segment = 0;
  1378     } else {
  1480     } else {
  1379         segment_size = fsm->remaining;
  1481         fsm->segment_size = fsm->remaining;
  1380         last_segment = 1;
  1482         last_segment = 1;
  1381     }
  1483     }
  1382 
  1484 
  1383     if (segment_size > EC_COE_DOWN_SEG_MIN_DATA_SIZE) {
  1485     if (fsm->segment_size > EC_COE_DOWN_SEG_MIN_DATA_SIZE) {
  1384         seg_data_size = 0x00;
  1486         seg_data_size = 0x00;
  1385         data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + segment_size;
  1487         data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
  1386     } else {
  1488     } else {
  1387         seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - segment_size;
  1489         seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
  1388         data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE
  1490         data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE
  1389             + EC_COE_DOWN_SEG_MIN_DATA_SIZE;
  1491             + EC_COE_DOWN_SEG_MIN_DATA_SIZE;
  1390     }
  1492     }
  1391 
  1493 
  1392     data = ec_slave_mbox_prepare_send(slave, mbox, 0x03,
  1494     data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
  1393             data_size);
  1495             data_size);
  1394     if (IS_ERR(data)) {
  1496     if (IS_ERR(data)) {
  1395         request->errno = PTR_ERR(data);
  1497         request->errno = PTR_ERR(data);
  1396         fsm->state = ec_fsm_coe_error;
  1498         fsm->state = ec_fsm_coe_error;
  1397         return;
  1499         return;
  1398     }
  1500     }
  1399 
  1501 
  1400     EC_WRITE_U16(data, 0x2 << 12); // SDO request
  1502     EC_WRITE_U16(data, 0x2 << 12); // SDO request
  1401     EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
  1503     EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
  1402             | (seg_data_size << 1) 
  1504             | (seg_data_size << 1)
  1403             | (fsm->toggle << 4)
  1505             | (fsm->toggle << 4)
  1404             | (0x00 << 5)); // Download segment request
  1506             | (0x00 << 5)); // Download segment request
  1405     memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
  1507     memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
  1406             request->data + fsm->offset, segment_size);
  1508             request->data + fsm->offset, fsm->segment_size);
  1407     if (segment_size < EC_COE_DOWN_SEG_MIN_DATA_SIZE) {
  1509     if (fsm->segment_size < EC_COE_DOWN_SEG_MIN_DATA_SIZE) {
  1408         memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + segment_size, 0x00,
  1510         memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
  1409                 EC_COE_DOWN_SEG_MIN_DATA_SIZE - segment_size);
  1511                 0x00, EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size);
  1410     }
  1512     }
  1411 
       
  1412     fsm->offset += segment_size;
       
  1413     fsm->remaining -= segment_size;
       
  1414 
  1513 
  1415     if (slave->master->debug_level) {
  1514     if (slave->master->debug_level) {
  1416         EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
  1515         EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
  1417         ec_print_data(data, data_size);
  1516         ec_print_data(data, data_size);
  1418     }
  1517     }
  1425 /**
  1524 /**
  1426    CoE state: DOWN RESPONSE.
  1525    CoE state: DOWN RESPONSE.
  1427    \todo Timeout behavior
  1526    \todo Timeout behavior
  1428 */
  1527 */
  1429 
  1528 
  1430 void ec_fsm_coe_down_response(ec_fsm_coe_t *fsm /**< finite state machine */)
  1529 void ec_fsm_coe_down_response(
  1431 {
  1530         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1432     ec_mailbox_t *mbox = fsm->mbox;
  1531         ec_datagram_t *datagram /**< Datagram to use. */
  1433     ec_datagram_t *datagram = fsm->mbox->datagram;
  1532         )
       
  1533 {
  1434     ec_slave_t *slave = fsm->slave;
  1534     ec_slave_t *slave = fsm->slave;
  1435     uint8_t *data, mbox_prot;
  1535     uint8_t *data, mbox_prot;
  1436     size_t rec_size;
  1536     size_t rec_size;
  1437     ec_sdo_request_t *request = fsm->request;
  1537     ec_sdo_request_t *request = fsm->request;
  1438 
  1538 
  1439     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  1539     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  1440             && fsm->retries--) {
  1540         ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
  1441         return; // FIXME: request again?
  1541         return;
  1442     }
  1542     }
  1443 
  1543 
  1444     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  1544     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  1445         request->errno = EIO;
  1545         request->errno = EIO;
  1446         fsm->state = ec_fsm_coe_error;
  1546         fsm->state = ec_fsm_coe_error;
  1447         EC_SLAVE_ERR(slave, "Failed to receive CoE download"
  1547         EC_SLAVE_ERR(slave, "Failed to receive CoE download"
  1448                 " response datagram: ");
  1548                 " response datagram: ");
  1449         ec_datagram_print_state(datagram);
  1549         ec_datagram_print_state(fsm->datagram);
  1450         return;
  1550         return;
  1451     }
  1551     }
  1452 
  1552 
  1453     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  1553     if (fsm->datagram->working_counter != 1) {
  1454         request->errno = EIO;
  1554         request->errno = EIO;
  1455         fsm->state = ec_fsm_coe_error;
  1555         fsm->state = ec_fsm_coe_error;
  1456         EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
  1556         EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
  1457         ec_datagram_print_wc_error(datagram);
  1557         ec_datagram_print_wc_error(fsm->datagram);
  1458         return;
  1558         return;
  1459     }
  1559     }
  1460 
  1560 
  1461     data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
  1561     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
  1462     if (IS_ERR(data)) {
  1562     if (IS_ERR(data)) {
  1463         request->errno = PTR_ERR(data);
  1563         request->errno = PTR_ERR(data);
  1464         fsm->state = ec_fsm_coe_error;
  1564         fsm->state = ec_fsm_coe_error;
  1465         return;
  1565         return;
  1466     }
  1566     }
  1473         return;
  1573         return;
  1474     }
  1574     }
  1475 
  1575 
  1476     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  1576     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  1477         // check for CoE response again
  1577         // check for CoE response again
  1478         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1578         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1479         fsm->retries = EC_FSM_RETRIES;
  1579         fsm->retries = EC_FSM_RETRIES;
  1480         fsm->state = ec_fsm_coe_down_check;
  1580         fsm->state = ec_fsm_coe_down_check;
  1481         return;
  1581         return;
  1482     }
  1582     }
  1483 
  1583 
  1525             EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
  1625             EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
  1526                     " Retrying...\n");
  1626                     " Retrying...\n");
  1527             ec_print_data(data, rec_size);
  1627             ec_print_data(data, rec_size);
  1528         }
  1628         }
  1529         // check for CoE response again
  1629         // check for CoE response again
  1530         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1630         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1531         fsm->retries = EC_FSM_RETRIES;
  1631         fsm->retries = EC_FSM_RETRIES;
  1532         fsm->state = ec_fsm_coe_down_check;
  1632         fsm->state = ec_fsm_coe_down_check;
  1533         return;
  1633         return;
  1534     }
  1634     }
  1535 
  1635 
  1536     if (fsm->remaining) { // more segments to download
  1636     if (fsm->remaining) { // more segments to download
  1537         fsm->toggle = 0;
  1637         fsm->toggle = 0;
  1538         ec_fsm_coe_down_prepare_segment_request(fsm);
  1638         ec_fsm_coe_down_prepare_segment_request(fsm, datagram);
  1539     } else {
  1639     } else {
  1540         fsm->state = ec_fsm_coe_end; // success
  1640         fsm->state = ec_fsm_coe_end; // success
  1541     }
  1641     }
  1542 }
  1642 }
  1543 
  1643 
  1545 
  1645 
  1546 /**
  1646 /**
  1547    CoE state: DOWN SEG CHECK.
  1647    CoE state: DOWN SEG CHECK.
  1548 */
  1648 */
  1549 
  1649 
  1550 void ec_fsm_coe_down_seg_check(ec_fsm_coe_t *fsm /**< finite state machine */)
  1650 void ec_fsm_coe_down_seg_check(
  1551 {
  1651         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1552     ec_mailbox_t *mbox = fsm->mbox;
  1652         ec_datagram_t *datagram /**< Datagram to use. */
  1553     ec_datagram_t *datagram = mbox->datagram;
  1653         )
  1554     ec_slave_t *slave = fsm->slave;
  1654 {
  1555 
  1655     ec_slave_t *slave = fsm->slave;
  1556     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  1656 
  1557             && fsm->retries--) {
  1657     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
  1558         return;
  1658         return;
  1559     }
  1659 
  1560 
  1660     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  1561     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
       
  1562         fsm->request->errno = EIO;
  1661         fsm->request->errno = EIO;
  1563         fsm->state = ec_fsm_coe_error;
  1662         fsm->state = ec_fsm_coe_error;
  1564         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
  1663         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
  1565         ec_datagram_print_state(datagram);
  1664         ec_datagram_print_state(fsm->datagram);
  1566         return;
  1665         return;
  1567     }
  1666     }
  1568 
  1667 
  1569     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  1668     if (fsm->datagram->working_counter != 1) {
  1570         fsm->request->errno = EIO;
  1669         fsm->request->errno = EIO;
  1571         fsm->state = ec_fsm_coe_error;
  1670         fsm->state = ec_fsm_coe_error;
  1572         EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
  1671         EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
  1573                 " datagram failed: ");
  1672                 " datagram failed: ");
  1574         ec_datagram_print_wc_error(datagram);
  1673         ec_datagram_print_wc_error(fsm->datagram);
  1575         return;
  1674         return;
  1576     }
  1675     }
  1577 
  1676 
  1578     if (!ec_slave_mbox_check(mbox)) {
  1677     if (!ec_slave_mbox_check(fsm->datagram)) {
  1579         unsigned long diff_ms =
  1678         unsigned long diff_ms =
  1580             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
  1679             (fsm->datagram->jiffies_received - fsm->jiffies_start) *
       
  1680             1000 / HZ;
  1581         if (diff_ms >= fsm->request->response_timeout) {
  1681         if (diff_ms >= fsm->request->response_timeout) {
  1582             fsm->request->errno = EIO;
  1682             fsm->request->errno = EIO;
  1583             fsm->state = ec_fsm_coe_error;
  1683             fsm->state = ec_fsm_coe_error;
  1584             EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
  1684             EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
  1585                     " segment response.\n");
  1685                     " segment response.\n");
  1586             return;
  1686             return;
  1587         }
  1687         }
  1588 
  1688 
  1589         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1689         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1590         fsm->retries = EC_FSM_RETRIES;
  1690         fsm->retries = EC_FSM_RETRIES;
  1591         return;
  1691         return;
  1592     }
  1692     }
  1593 
  1693 
  1594     // Fetch response
  1694     // Fetch response
  1595     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
  1695     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
  1596     fsm->retries = EC_FSM_RETRIES;
  1696     fsm->retries = EC_FSM_RETRIES;
  1597     fsm->state = ec_fsm_coe_down_seg_response;
  1697     fsm->state = ec_fsm_coe_down_seg_response;
  1598 }
  1698 }
  1599 
  1699 
  1600 /*****************************************************************************/
  1700 /*****************************************************************************/
  1603    CoE state: DOWN SEG RESPONSE.
  1703    CoE state: DOWN SEG RESPONSE.
  1604    \todo Timeout behavior
  1704    \todo Timeout behavior
  1605 */
  1705 */
  1606 
  1706 
  1607 void ec_fsm_coe_down_seg_response(
  1707 void ec_fsm_coe_down_seg_response(
  1608         ec_fsm_coe_t *fsm /**< finite state machine */
  1708         ec_fsm_coe_t *fsm, /**< Finite state machine */
  1609         )
  1709         ec_datagram_t *datagram /**< Datagram to use. */
  1610 {
  1710         )
  1611     ec_mailbox_t *mbox = fsm->mbox;
  1711 {
  1612     ec_datagram_t *datagram = mbox->datagram;
       
  1613     ec_slave_t *slave = fsm->slave;
  1712     ec_slave_t *slave = fsm->slave;
  1614     uint8_t *data, mbox_prot;
  1713     uint8_t *data, mbox_prot;
  1615     size_t rec_size;
  1714     size_t rec_size;
  1616     ec_sdo_request_t *request = fsm->request;
  1715     ec_sdo_request_t *request = fsm->request;
  1617 
  1716 
  1618     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  1717     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  1619             && fsm->retries--) {
  1718         ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
  1620         return; // FIXME: request again?
  1719         return;
  1621     }
  1720     }
  1622 
  1721 
  1623     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  1722     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  1624         request->errno = EIO;
  1723         request->errno = EIO;
  1625         fsm->state = ec_fsm_coe_error;
  1724         fsm->state = ec_fsm_coe_error;
  1626         EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
  1725         EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
  1627                 " datagram: ");
  1726                 " datagram: ");
  1628         ec_datagram_print_state(datagram);
  1727         ec_datagram_print_state(fsm->datagram);
  1629         return;
  1728         return;
  1630     }
  1729     }
  1631 
  1730 
  1632     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  1731     if (fsm->datagram->working_counter != 1) {
  1633         request->errno = EIO;
  1732         request->errno = EIO;
  1634         fsm->state = ec_fsm_coe_error;
  1733         fsm->state = ec_fsm_coe_error;
  1635         EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
  1734         EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
  1636         ec_datagram_print_wc_error(datagram);
  1735         ec_datagram_print_wc_error(fsm->datagram);
  1637         return;
  1736         return;
  1638     }
  1737     }
  1639 
  1738 
  1640     data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
  1739     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
  1641     if (IS_ERR(data)) {
  1740     if (IS_ERR(data)) {
  1642         request->errno = PTR_ERR(data);
  1741         request->errno = PTR_ERR(data);
  1643         fsm->state = ec_fsm_coe_error;
  1742         fsm->state = ec_fsm_coe_error;
  1644         return;
  1743         return;
  1645     }
  1744     }
  1652         return;
  1751         return;
  1653     }
  1752     }
  1654 
  1753 
  1655     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  1754     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  1656         // check for CoE response again
  1755         // check for CoE response again
  1657         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1756         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1658         fsm->retries = EC_FSM_RETRIES;
  1757         fsm->retries = EC_FSM_RETRIES;
  1659         fsm->state = ec_fsm_coe_down_check;
  1758         fsm->state = ec_fsm_coe_down_check;
  1660         return;
  1759         return;
  1661     }
  1760     }
  1662 
  1761 
  1702             EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
  1801             EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
  1703                     " Retrying...\n");
  1802                     " Retrying...\n");
  1704             ec_print_data(data, rec_size);
  1803             ec_print_data(data, rec_size);
  1705         }
  1804         }
  1706         // check for CoE response again
  1805         // check for CoE response again
  1707         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1806         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1708         fsm->retries = EC_FSM_RETRIES;
  1807         fsm->retries = EC_FSM_RETRIES;
  1709         fsm->state = ec_fsm_coe_down_seg_check;
  1808         fsm->state = ec_fsm_coe_down_seg_check;
  1710         return;
  1809         return;
  1711     }
  1810     }
  1712 
  1811 
  1717         request->errno = EIO;
  1816         request->errno = EIO;
  1718         fsm->state = ec_fsm_coe_error;
  1817         fsm->state = ec_fsm_coe_error;
  1719         return;
  1818         return;
  1720     }
  1819     }
  1721 
  1820 
       
  1821     fsm->offset += fsm->segment_size;
       
  1822     fsm->remaining -= fsm->segment_size;
       
  1823 
  1722     if (fsm->remaining) { // more segments to download
  1824     if (fsm->remaining) { // more segments to download
  1723         fsm->toggle = !fsm->toggle;
  1825         fsm->toggle = !fsm->toggle;
  1724         ec_fsm_coe_down_prepare_segment_request(fsm);
  1826         ec_fsm_coe_down_prepare_segment_request(fsm, datagram);
  1725     } else {
  1827     } else {
  1726         fsm->state = ec_fsm_coe_end; // success
  1828         fsm->state = ec_fsm_coe_end; // success
  1727     }
  1829     }
  1728 }
  1830 }
  1729 
  1831 
  1730 /*****************************************************************************/
  1832 /*****************************************************************************/
  1731 
  1833 
  1732 /**
  1834 /** Prepare an upload request.
  1733    CoE state: UP START.
  1835  *
  1734 */
  1836  * \return Zero on success, otherwise a negative error code.
  1735 
  1837  */
  1736 void ec_fsm_coe_up_start(ec_fsm_coe_t *fsm /**< finite state machine */)
  1838 int ec_fsm_coe_prepare_up(
  1737 {
  1839         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1738     ec_mailbox_t *mbox = fsm->mbox;
  1840         ec_datagram_t *datagram /**< Datagram to use. */
  1739     ec_slave_t *slave = fsm->slave;
  1841         )
       
  1842 {
       
  1843     ec_slave_t *slave = fsm->slave;
       
  1844     ec_sdo_request_t *request = fsm->request;
  1740     ec_master_t *master = slave->master;
  1845     ec_master_t *master = slave->master;
  1741     ec_sdo_request_t *request = fsm->request;
  1846 
  1742     uint8_t *data;
  1847     u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
  1743 
       
  1744     EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
       
  1745             request->index, request->subindex);
       
  1746 
       
  1747     if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
       
  1748         EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
       
  1749         request->errno = EPROTONOSUPPORT;
       
  1750         fsm->state = ec_fsm_coe_error;
       
  1751         return;
       
  1752     }
       
  1753 
       
  1754     data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 10);
       
  1755     if (IS_ERR(data)) {
  1848     if (IS_ERR(data)) {
  1756         request->errno = PTR_ERR(data);
  1849         request->errno = PTR_ERR(data);
  1757         fsm->state = ec_fsm_coe_error;
  1850         return PTR_ERR(data);
  1758         return;
       
  1759     }
  1851     }
  1760 
  1852 
  1761     EC_WRITE_U16(data, 0x2 << 12); // SDO request
  1853     EC_WRITE_U16(data, 0x2 << 12); // SDO request
  1762     EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
  1854     EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
  1763     EC_WRITE_U16(data + 3, request->index);
  1855     EC_WRITE_U16(data + 3, request->index);
  1767     if (master->debug_level) {
  1859     if (master->debug_level) {
  1768         EC_SLAVE_DBG(slave, 1, "Upload request:\n");
  1860         EC_SLAVE_DBG(slave, 1, "Upload request:\n");
  1769         ec_print_data(data, 10);
  1861         ec_print_data(data, 10);
  1770     }
  1862     }
  1771 
  1863 
       
  1864     fsm->state = ec_fsm_coe_up_request;
       
  1865     return 0;
       
  1866 }
       
  1867 
       
  1868 /*****************************************************************************/
       
  1869 
       
  1870 /**
       
  1871    CoE state: UP START.
       
  1872 */
       
  1873 
       
  1874 void ec_fsm_coe_up_start(
       
  1875         ec_fsm_coe_t *fsm, /**< Finite state machine. */
       
  1876         ec_datagram_t *datagram /**< Datagram to use. */
       
  1877         )
       
  1878 {
       
  1879     ec_slave_t *slave = fsm->slave;
       
  1880     ec_sdo_request_t *request = fsm->request;
       
  1881 
       
  1882     EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
       
  1883             request->index, request->subindex);
       
  1884 
       
  1885     if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
       
  1886         EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
       
  1887         request->errno = EPROTONOSUPPORT;
       
  1888         fsm->state = ec_fsm_coe_error;
       
  1889         return;
       
  1890     }
       
  1891 
       
  1892     fsm->retries = EC_FSM_RETRIES;
  1772     fsm->request->jiffies_sent = jiffies;
  1893     fsm->request->jiffies_sent = jiffies;
  1773     fsm->retries = EC_FSM_RETRIES;
  1894 
  1774     fsm->state = ec_fsm_coe_up_request;
  1895     if (ec_fsm_coe_prepare_up(fsm, datagram)) {
  1775 }
  1896         fsm->state = ec_fsm_coe_error;
  1776 
  1897     }
  1777 /*****************************************************************************/
  1898 }
  1778 
  1899 
       
  1900 /*****************************************************************************/
  1779 /**
  1901 /**
  1780    CoE state: UP REQUEST.
  1902    CoE state: UP REQUEST.
  1781    \todo Timeout behavior
  1903    \todo Timeout behavior
  1782 */
  1904 */
  1783 
  1905 
  1784 void ec_fsm_coe_up_request(ec_fsm_coe_t *fsm /**< finite state machine */)
  1906 void ec_fsm_coe_up_request(
  1785 {
  1907         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1786     ec_mailbox_t *mbox = fsm->mbox;
  1908         ec_datagram_t *datagram /**< Datagram to use. */
  1787     ec_datagram_t *datagram = mbox->datagram;
  1909         )
       
  1910 {
  1788     ec_slave_t *slave = fsm->slave;
  1911     ec_slave_t *slave = fsm->slave;
  1789     unsigned long diff_ms;
  1912     unsigned long diff_ms;
  1790 
  1913 
  1791     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  1914     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  1792             && fsm->retries--) {
  1915         if (ec_fsm_coe_prepare_up(fsm, datagram)) {
  1793         return; // FIXME: check for response first?
  1916             fsm->state = ec_fsm_coe_error;
  1794     }
  1917         }
  1795 
  1918         return;
  1796     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  1919     }
       
  1920 
       
  1921     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  1797         fsm->request->errno = EIO;
  1922         fsm->request->errno = EIO;
  1798         fsm->state = ec_fsm_coe_error;
  1923         fsm->state = ec_fsm_coe_error;
  1799         EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
  1924         EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
  1800         ec_datagram_print_state(datagram);
  1925         ec_datagram_print_state(fsm->datagram);
  1801         return;
  1926         return;
  1802     }
  1927     }
  1803 
  1928 
  1804     diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
  1929     diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
  1805 
  1930 
  1806     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  1931     if (fsm->datagram->working_counter != 1) {
  1807         if (ec_mbox_is_datagram_wc(mbox, 0)) {
  1932         if (!fsm->datagram->working_counter) {
  1808             if (diff_ms < fsm->request->response_timeout) {
  1933             if (diff_ms < fsm->request->response_timeout) {
  1809 #if DEBUG_RETRIES
  1934 #if DEBUG_RETRIES
  1810                 EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
  1935                 EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
  1811                         " SDO upload request. Retrying after %lu ms...\n",
  1936                         " SDO upload request. Retrying after %lu ms...\n",
  1812                         diff_ms);
  1937                         diff_ms);
  1813 #endif
  1938 #endif
  1814                 // no response; send request datagram again
  1939                 // no response; send request datagram again
       
  1940                 if (ec_fsm_coe_prepare_up(fsm, datagram)) {
       
  1941                     fsm->state = ec_fsm_coe_error;
       
  1942                 }
  1815                 return;
  1943                 return;
  1816             }
  1944             }
  1817         }
  1945         }
  1818         fsm->request->errno = EIO;
  1946         fsm->request->errno = EIO;
  1819         fsm->state = ec_fsm_coe_error;
  1947         fsm->state = ec_fsm_coe_error;
  1820         EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
  1948         EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
  1821                 " SDO 0x%04x:%x failed with timeout after %lu ms: ",
  1949                 " SDO 0x%04x:%x failed with timeout after %lu ms: ",
  1822                 fsm->request->index, fsm->request->subindex, diff_ms);
  1950                 fsm->request->index, fsm->request->subindex, diff_ms);
  1823         ec_datagram_print_wc_error(datagram);
  1951         ec_datagram_print_wc_error(fsm->datagram);
  1824         return;
  1952         return;
  1825     }
  1953     }
  1826 
  1954 
  1827 #if DEBUG_LONG
  1955 #if DEBUG_LONG
  1828     if (diff_ms > 200) {
  1956     if (diff_ms > 200) {
  1829         EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
  1957         EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
  1830                 fsm->request->index, fsm->request->subindex, diff_ms);
  1958                 fsm->request->index, fsm->request->subindex, diff_ms);
  1831     }
  1959     }
  1832 #endif
  1960 #endif
  1833 
  1961 
  1834     fsm->jiffies_start = datagram->jiffies_sent;
  1962     fsm->jiffies_start = fsm->datagram->jiffies_sent;
  1835 
  1963 
  1836     ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  1964     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1837     fsm->retries = EC_FSM_RETRIES;
  1965     fsm->retries = EC_FSM_RETRIES;
  1838     fsm->state = ec_fsm_coe_up_check;
  1966     fsm->state = ec_fsm_coe_up_check;
  1839 }
  1967 }
  1840 
  1968 
  1841 /*****************************************************************************/
  1969 /*****************************************************************************/
  1842 
  1970 
  1843 /**
  1971 /**
  1844    CoE state: UP CHECK.
  1972    CoE state: UP CHECK.
  1845 */
  1973 */
  1846 
  1974 
  1847 void ec_fsm_coe_up_check(ec_fsm_coe_t *fsm /**< finite state machine */)
  1975 void ec_fsm_coe_up_check(
  1848 {
  1976         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1849     ec_mailbox_t *mbox = fsm->mbox;
  1977         ec_datagram_t *datagram /**< Datagram to use. */
  1850     ec_datagram_t *datagram = mbox->datagram;
  1978         )
  1851     ec_slave_t *slave = fsm->slave;
  1979 {
  1852 
  1980     ec_slave_t *slave = fsm->slave;
  1853     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  1981 
  1854             && fsm->retries--) {
  1982     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  1855         return;
  1983         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1856     }
  1984         return;
  1857 
  1985     }
  1858     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  1986 
       
  1987     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  1859         fsm->request->errno = EIO;
  1988         fsm->request->errno = EIO;
  1860         fsm->state = ec_fsm_coe_error;
  1989         fsm->state = ec_fsm_coe_error;
  1861         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
  1990         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
  1862         ec_datagram_print_state(datagram);
  1991         ec_datagram_print_state(fsm->datagram);
  1863         return;
  1992         return;
  1864     }
  1993     }
  1865 
  1994 
  1866     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  1995     if (fsm->datagram->working_counter != 1) {
  1867         fsm->request->errno = EIO;
  1996         fsm->request->errno = EIO;
  1868         fsm->state = ec_fsm_coe_error;
  1997         fsm->state = ec_fsm_coe_error;
  1869         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
  1998         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
  1870                 " datagram failed: ");
  1999                 " datagram failed: ");
  1871         ec_datagram_print_wc_error(datagram);
  2000         ec_datagram_print_wc_error(fsm->datagram);
  1872         return;
  2001         return;
  1873     }
  2002     }
  1874 
  2003 
  1875     if (!ec_slave_mbox_check(mbox)) {
  2004     if (!ec_slave_mbox_check(fsm->datagram)) {
  1876         unsigned long diff_ms =
  2005         unsigned long diff_ms =
  1877             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
  2006             (fsm->datagram->jiffies_received - fsm->jiffies_start) *
       
  2007             1000 / HZ;
  1878         if (diff_ms >= fsm->request->response_timeout) {
  2008         if (diff_ms >= fsm->request->response_timeout) {
  1879             fsm->request->errno = EIO;
  2009             fsm->request->errno = EIO;
  1880             fsm->state = ec_fsm_coe_error;
  2010             fsm->state = ec_fsm_coe_error;
  1881             EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
  2011             EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
  1882                     " SDO 0x%04x:%x upload response.\n", diff_ms,
  2012                     " SDO 0x%04x:%x upload response.\n", diff_ms,
  1883                     fsm->request->index, fsm->request->subindex);
  2013                     fsm->request->index, fsm->request->subindex);
  1884             return;
  2014             return;
  1885         }
  2015         }
  1886 
  2016 
  1887         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  2017         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1888         fsm->retries = EC_FSM_RETRIES;
  2018         fsm->retries = EC_FSM_RETRIES;
  1889         return;
  2019         return;
  1890     }
  2020     }
  1891 
  2021 
  1892     // Fetch response
  2022     // Fetch response
  1893     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
  2023     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
  1894     fsm->retries = EC_FSM_RETRIES;
  2024     fsm->retries = EC_FSM_RETRIES;
  1895     fsm->state = ec_fsm_coe_up_response;
  2025     fsm->state = ec_fsm_coe_up_response;
  1896 }
  2026 }
  1897 
  2027 
  1898 /*****************************************************************************/
  2028 /*****************************************************************************/
  1899 
  2029 
  1900 /** Prepare an SDO upload segment request.
  2030 /** Prepare an SDO upload segment request.
  1901  */
  2031  */
  1902 void ec_fsm_coe_up_prepare_segment_request(
  2032 void ec_fsm_coe_up_prepare_segment_request(
  1903         ec_fsm_coe_t *fsm /**< Finite state machine */
  2033         ec_fsm_coe_t *fsm, /**< Finite state machine */
       
  2034         ec_datagram_t *datagram /**< Datagram to use. */
  1904         )
  2035         )
  1905 {
  2036 {
  1906     uint8_t *data =
  2037     uint8_t *data =
  1907         ec_slave_mbox_prepare_send(fsm->slave, fsm->mbox, 0x03, 10);
  2038         ec_slave_mbox_prepare_send(fsm->slave, datagram, 0x03, 10);
  1908     if (IS_ERR(data)) {
  2039     if (IS_ERR(data)) {
  1909         fsm->request->errno = PTR_ERR(data);
  2040         fsm->request->errno = PTR_ERR(data);
  1910         fsm->state = ec_fsm_coe_error;
  2041         fsm->state = ec_fsm_coe_error;
  1911         return;
  2042         return;
  1912     }
  2043     }
  1927 /**
  2058 /**
  1928    CoE state: UP RESPONSE.
  2059    CoE state: UP RESPONSE.
  1929    \todo Timeout behavior
  2060    \todo Timeout behavior
  1930 */
  2061 */
  1931 
  2062 
  1932 void ec_fsm_coe_up_response(ec_fsm_coe_t *fsm /**< finite state machine */)
  2063 void ec_fsm_coe_up_response(
  1933 {
  2064         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  1934     ec_mailbox_t *mbox = fsm->mbox;
  2065         ec_datagram_t *datagram /**< Datagram to use. */
  1935     ec_datagram_t *datagram = mbox->datagram;
  2066         )
       
  2067 {
  1936     ec_slave_t *slave = fsm->slave;
  2068     ec_slave_t *slave = fsm->slave;
  1937     ec_master_t *master = slave->master;
  2069     ec_master_t *master = slave->master;
  1938     uint16_t rec_index;
  2070     uint16_t rec_index;
  1939     uint8_t *data, mbox_prot, rec_subindex;
  2071     uint8_t *data, mbox_prot, rec_subindex;
  1940     size_t rec_size, data_size;
  2072     size_t rec_size, data_size;
  1941     ec_sdo_request_t *request = fsm->request;
  2073     ec_sdo_request_t *request = fsm->request;
  1942     unsigned int expedited, size_specified;
  2074     unsigned int expedited, size_specified;
  1943     int ret;
  2075     int ret;
  1944 
  2076 
  1945     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  2077     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  1946             && fsm->retries--) {
  2078         ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
  1947         return; // FIXME: request again?
  2079         return;
  1948     }
  2080     }
  1949 
  2081 
  1950     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  2082     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  1951         request->errno = EIO;
  2083         request->errno = EIO;
  1952         fsm->state = ec_fsm_coe_error;
  2084         fsm->state = ec_fsm_coe_error;
  1953         EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
  2085         EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
  1954                 " datagram: ");
  2086                 " datagram: ");
  1955         ec_datagram_print_state(datagram);
  2087         ec_datagram_print_state(fsm->datagram);
  1956         return;
  2088         return;
  1957     }
  2089     }
  1958 
  2090 
  1959     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  2091     if (fsm->datagram->working_counter != 1) {
  1960         request->errno = EIO;
  2092         request->errno = EIO;
  1961         fsm->state = ec_fsm_coe_error;
  2093         fsm->state = ec_fsm_coe_error;
  1962         EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
  2094         EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
  1963         ec_datagram_print_wc_error(datagram);
  2095         ec_datagram_print_wc_error(fsm->datagram);
  1964         return;
  2096         return;
  1965     }
  2097     }
  1966 
  2098 
  1967     data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
  2099     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
  1968     if (IS_ERR(data)) {
  2100     if (IS_ERR(data)) {
  1969         request->errno = PTR_ERR(data);
  2101         request->errno = PTR_ERR(data);
  1970         fsm->state = ec_fsm_coe_error;
  2102         fsm->state = ec_fsm_coe_error;
  1971         return;
  2103         return;
  1972     }
  2104     }
  1984         return;
  2116         return;
  1985     }
  2117     }
  1986 
  2118 
  1987     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  2119     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  1988         // check for CoE response again
  2120         // check for CoE response again
  1989         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  2121         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  1990         fsm->retries = EC_FSM_RETRIES;
  2122         fsm->retries = EC_FSM_RETRIES;
  1991         fsm->state = ec_fsm_coe_up_check;
  2123         fsm->state = ec_fsm_coe_up_check;
  1992         return;
  2124         return;
  1993     }
  2125     }
  1994 
  2126 
  2035                 " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
  2167                 " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
  2036                 rec_index, rec_subindex, request->index, request->subindex);
  2168                 rec_index, rec_subindex, request->index, request->subindex);
  2037         ec_print_data(data, rec_size);
  2169         ec_print_data(data, rec_size);
  2038 
  2170 
  2039         // check for CoE response again
  2171         // check for CoE response again
  2040         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  2172         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  2041         fsm->retries = EC_FSM_RETRIES;
  2173         fsm->retries = EC_FSM_RETRIES;
  2042         fsm->state = ec_fsm_coe_up_check;
  2174         fsm->state = ec_fsm_coe_up_check;
  2043         return;
  2175         return;
  2044     }
  2176     }
  2045 
  2177 
  2107         fsm->toggle = 0;
  2239         fsm->toggle = 0;
  2108 
  2240 
  2109         if (data_size < fsm->complete_size) {
  2241         if (data_size < fsm->complete_size) {
  2110             EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
  2242             EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
  2111                     " Segmenting...\n", data_size, fsm->complete_size);
  2243                     " Segmenting...\n", data_size, fsm->complete_size);
  2112             ec_fsm_coe_up_prepare_segment_request(fsm);
  2244             ec_fsm_coe_up_prepare_segment_request(fsm, datagram);
  2113             fsm->retries = EC_FSM_RETRIES;
  2245             fsm->retries = EC_FSM_RETRIES;
  2114             fsm->state = ec_fsm_coe_up_seg_request;
  2246             fsm->state = ec_fsm_coe_up_seg_request;
  2115             return;
  2247             return;
  2116         }
  2248         }
  2117     }
  2249     }
  2129 /**
  2261 /**
  2130    CoE state: UP REQUEST.
  2262    CoE state: UP REQUEST.
  2131    \todo Timeout behavior
  2263    \todo Timeout behavior
  2132 */
  2264 */
  2133 
  2265 
  2134 void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *fsm /**< finite state machine */)
  2266 void ec_fsm_coe_up_seg_request(
  2135 {
  2267         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  2136     ec_mailbox_t *mbox = fsm->mbox;
  2268         ec_datagram_t *datagram /**< Datagram to use. */
  2137     ec_datagram_t *datagram = mbox->datagram;
  2269         )
  2138     ec_slave_t *slave = fsm->slave;
  2270 {
  2139 
  2271     ec_slave_t *slave = fsm->slave;
  2140     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  2272 
  2141             && fsm->retries--) {
  2273     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  2142         return; // FIXME: check for response first?
  2274         ec_fsm_coe_up_prepare_segment_request(fsm, datagram);
  2143     }
  2275         return;
  2144 
  2276     }
  2145     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  2277 
       
  2278     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  2146         fsm->request->errno = EIO;
  2279         fsm->request->errno = EIO;
  2147         fsm->state = ec_fsm_coe_error;
  2280         fsm->state = ec_fsm_coe_error;
  2148         EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
  2281         EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
  2149                 " request datagram: ");
  2282                 " request datagram: ");
  2150         ec_datagram_print_state(datagram);
  2283         ec_datagram_print_state(fsm->datagram);
  2151         return;
  2284         return;
  2152     }
  2285     }
  2153 
  2286 
  2154     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  2287     if (fsm->datagram->working_counter != 1) {
  2155         fsm->request->errno = EIO;
  2288         fsm->request->errno = EIO;
  2156         fsm->state = ec_fsm_coe_error;
  2289         fsm->state = ec_fsm_coe_error;
  2157         EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
  2290         EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
  2158                 " request failed: ");
  2291                 " request failed: ");
  2159         ec_datagram_print_wc_error(datagram);
  2292         ec_datagram_print_wc_error(fsm->datagram);
  2160         return;
  2293         return;
  2161     }
  2294     }
  2162 
  2295 
  2163     fsm->jiffies_start = datagram->jiffies_sent;
  2296     fsm->jiffies_start = fsm->datagram->jiffies_sent;
  2164 
  2297 
  2165     ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  2298     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  2166     fsm->retries = EC_FSM_RETRIES;
  2299     fsm->retries = EC_FSM_RETRIES;
  2167     fsm->state = ec_fsm_coe_up_seg_check;
  2300     fsm->state = ec_fsm_coe_up_seg_check;
  2168 }
  2301 }
  2169 
  2302 
  2170 /*****************************************************************************/
  2303 /*****************************************************************************/
  2171 
  2304 
  2172 /**
  2305 /**
  2173    CoE state: UP CHECK.
  2306    CoE state: UP CHECK.
  2174 */
  2307 */
  2175 
  2308 
  2176 void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *fsm /**< finite state machine */)
  2309 void ec_fsm_coe_up_seg_check(
  2177 {
  2310         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  2178     ec_mailbox_t *mbox = fsm->mbox;
  2311         ec_datagram_t *datagram /**< Datagram to use. */
  2179     ec_datagram_t *datagram = mbox->datagram;
  2312         )
  2180     ec_slave_t *slave = fsm->slave;
  2313 {
  2181 
  2314     ec_slave_t *slave = fsm->slave;
  2182     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  2315 
  2183             && fsm->retries--) {
  2316     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  2184         return;
  2317         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  2185     }
  2318         return;
  2186 
  2319     }
  2187     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  2320 
       
  2321     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  2188         fsm->request->errno = EIO;
  2322         fsm->request->errno = EIO;
  2189         fsm->state = ec_fsm_coe_error;
  2323         fsm->state = ec_fsm_coe_error;
  2190         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
  2324         EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
  2191                 " datagram: ");
  2325                 " datagram: ");
  2192         ec_datagram_print_state(datagram);
  2326         ec_datagram_print_state(fsm->datagram);
  2193         return;
  2327         return;
  2194     }
  2328     }
  2195 
  2329 
  2196     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  2330     if (fsm->datagram->working_counter != 1) {
  2197         fsm->request->errno = EIO;
  2331         fsm->request->errno = EIO;
  2198         fsm->state = ec_fsm_coe_error;
  2332         fsm->state = ec_fsm_coe_error;
  2199         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
  2333         EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
  2200                 " failed: ");
  2334                 " failed: ");
  2201         ec_datagram_print_wc_error(datagram);
  2335         ec_datagram_print_wc_error(fsm->datagram);
  2202         return;
  2336         return;
  2203     }
  2337     }
  2204 
  2338 
  2205     if (!ec_slave_mbox_check(mbox)) {
  2339     if (!ec_slave_mbox_check(fsm->datagram)) {
  2206         unsigned long diff_ms =
  2340         unsigned long diff_ms =
  2207             (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
  2341             (fsm->datagram->jiffies_received - fsm->jiffies_start) *
       
  2342             1000 / HZ;
  2208         if (diff_ms >= fsm->request->response_timeout) {
  2343         if (diff_ms >= fsm->request->response_timeout) {
  2209             fsm->request->errno = EIO;
  2344             fsm->request->errno = EIO;
  2210             fsm->state = ec_fsm_coe_error;
  2345             fsm->state = ec_fsm_coe_error;
  2211             EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
  2346             EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
  2212                     " segment response.\n");
  2347                     " segment response.\n");
  2213             return;
  2348             return;
  2214         }
  2349         }
  2215 
  2350 
  2216         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  2351         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  2217         fsm->retries = EC_FSM_RETRIES;
  2352         fsm->retries = EC_FSM_RETRIES;
  2218         return;
  2353         return;
  2219     }
  2354     }
  2220 
  2355 
  2221     // Fetch response
  2356     // Fetch response
  2222     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
  2357     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
  2223     fsm->retries = EC_FSM_RETRIES;
  2358     fsm->retries = EC_FSM_RETRIES;
  2224     fsm->state = ec_fsm_coe_up_seg_response;
  2359     fsm->state = ec_fsm_coe_up_seg_response;
  2225 }
  2360 }
  2226 
  2361 
  2227 /*****************************************************************************/
  2362 /*****************************************************************************/
  2229 /**
  2364 /**
  2230    CoE state: UP RESPONSE.
  2365    CoE state: UP RESPONSE.
  2231    \todo Timeout behavior
  2366    \todo Timeout behavior
  2232 */
  2367 */
  2233 
  2368 
  2234 void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *fsm /**< finite state machine */)
  2369 void ec_fsm_coe_up_seg_response(
  2235 {
  2370         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  2236     ec_mailbox_t *mbox = fsm->mbox;
  2371         ec_datagram_t *datagram /**< Datagram to use. */
  2237     ec_datagram_t *datagram = mbox->datagram;
  2372         )
       
  2373 {
  2238     ec_slave_t *slave = fsm->slave;
  2374     ec_slave_t *slave = fsm->slave;
  2239     ec_master_t *master = slave->master;
  2375     ec_master_t *master = slave->master;
  2240     uint8_t *data, mbox_prot;
  2376     uint8_t *data, mbox_prot;
  2241     size_t rec_size, data_size;
  2377     size_t rec_size, data_size;
  2242     ec_sdo_request_t *request = fsm->request;
  2378     ec_sdo_request_t *request = fsm->request;
  2243     unsigned int last_segment;
  2379     unsigned int last_segment;
  2244 
  2380 
  2245     if (ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_TIMED_OUT)
  2381     if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
  2246             && fsm->retries--) {
  2382         ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
  2247         return; // FIXME: request again?
  2383         return;
  2248     }
  2384     }
  2249 
  2385 
  2250     if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
  2386     if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
  2251         request->errno = EIO;
  2387         request->errno = EIO;
  2252         fsm->state = ec_fsm_coe_error;
  2388         fsm->state = ec_fsm_coe_error;
  2253         EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
  2389         EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
  2254                 " response datagram: ");
  2390                 " response datagram: ");
  2255         ec_datagram_print_state(datagram);
  2391         ec_datagram_print_state(fsm->datagram);
  2256         return;
  2392         return;
  2257     }
  2393     }
  2258 
  2394 
  2259     if (!ec_mbox_is_datagram_wc(mbox, 1)) {
  2395     if (fsm->datagram->working_counter != 1) {
  2260         request->errno = EIO;
  2396         request->errno = EIO;
  2261         fsm->state = ec_fsm_coe_error;
  2397         fsm->state = ec_fsm_coe_error;
  2262         EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
  2398         EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
  2263                 " response failed: ");
  2399                 " response failed: ");
  2264         ec_datagram_print_wc_error(datagram);
  2400         ec_datagram_print_wc_error(fsm->datagram);
  2265         return;
  2401         return;
  2266     }
  2402     }
  2267 
  2403 
  2268     data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
  2404     data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
  2269     if (IS_ERR(data)) {
  2405     if (IS_ERR(data)) {
  2270         request->errno = PTR_ERR(data);
  2406         request->errno = PTR_ERR(data);
  2271         fsm->state = ec_fsm_coe_error;
  2407         fsm->state = ec_fsm_coe_error;
  2272         return;
  2408         return;
  2273     }
  2409     }
  2285         return;
  2421         return;
  2286     }
  2422     }
  2287 
  2423 
  2288     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  2424     if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
  2289         // check for CoE response again
  2425         // check for CoE response again
  2290         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  2426         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  2291         fsm->retries = EC_FSM_RETRIES;
  2427         fsm->retries = EC_FSM_RETRIES;
  2292         fsm->state = ec_fsm_coe_up_seg_check;
  2428         fsm->state = ec_fsm_coe_up_seg_check;
  2293         return;
  2429         return;
  2294     }
  2430     }
  2295 
  2431 
  2318         if (fsm->slave->master->debug_level) {
  2454         if (fsm->slave->master->debug_level) {
  2319             EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
  2455             EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
  2320             ec_print_data(data, rec_size);
  2456             ec_print_data(data, rec_size);
  2321         }
  2457         }
  2322         // check for CoE response again
  2458         // check for CoE response again
  2323         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
  2459         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
  2324         fsm->retries = EC_FSM_RETRIES;
  2460         fsm->retries = EC_FSM_RETRIES;
  2325         fsm->state = ec_fsm_coe_up_seg_check;
  2461         fsm->state = ec_fsm_coe_up_seg_check;
  2326         return;
  2462         return;
  2327     }
  2463     }
  2328 
  2464 
  2346     request->data_size += data_size;
  2482     request->data_size += data_size;
  2347 
  2483 
  2348     last_segment = EC_READ_U8(data + 2) & 0x01;
  2484     last_segment = EC_READ_U8(data + 2) & 0x01;
  2349     if (!last_segment) {
  2485     if (!last_segment) {
  2350         fsm->toggle = !fsm->toggle;
  2486         fsm->toggle = !fsm->toggle;
  2351         ec_fsm_coe_up_prepare_segment_request(fsm);
  2487         ec_fsm_coe_up_prepare_segment_request(fsm, datagram);
  2352         fsm->retries = EC_FSM_RETRIES;
  2488         fsm->retries = EC_FSM_RETRIES;
  2353         fsm->state = ec_fsm_coe_up_seg_request;
  2489         fsm->state = ec_fsm_coe_up_seg_request;
  2354         return;
  2490         return;
  2355     }
  2491     }
  2356 
  2492 
  2373 
  2509 
  2374 /**
  2510 /**
  2375    State: ERROR.
  2511    State: ERROR.
  2376 */
  2512 */
  2377 
  2513 
  2378 void ec_fsm_coe_error(ec_fsm_coe_t *fsm /**< finite state machine */)
  2514 void ec_fsm_coe_error(
       
  2515         ec_fsm_coe_t *fsm, /**< Finite state machine. */
       
  2516         ec_datagram_t *datagram /**< Datagram to use. */
       
  2517         )
  2379 {
  2518 {
  2380 }
  2519 }
  2381 
  2520 
  2382 /*****************************************************************************/
  2521 /*****************************************************************************/
  2383 
  2522 
  2384 /**
  2523 /**
  2385    State: END.
  2524    State: END.
  2386 */
  2525 */
  2387 
  2526 
  2388 void ec_fsm_coe_end(ec_fsm_coe_t *fsm /**< finite state machine */)
  2527 void ec_fsm_coe_end(
  2389 {
  2528         ec_fsm_coe_t *fsm, /**< Finite state machine. */
  2390 }
  2529         ec_datagram_t *datagram /**< Datagram to use. */
  2391 
  2530         )
  2392 /*****************************************************************************/
  2531 {
       
  2532 }
       
  2533 
       
  2534 /*****************************************************************************/