--- a/master/fsm_foe.c Thu Sep 06 14:21:02 2012 +0200
+++ b/master/fsm_foe.c Mon Nov 03 15:20:05 2014 +0100
@@ -3,6 +3,7 @@
* $Id$
*
* Copyright (C) 2008 Olav Zarges, imc Messsysteme GmbH
+ * 2013 Florian Pose <fp@igh-essen.com>
*
* This file is part of the IgH EtherCAT Master.
*
@@ -27,10 +28,9 @@
*
*****************************************************************************/
-/**
- \file
- EtherCAT FoE state machines.
-*/
+/** \file
+ * EtherCAT FoE state machines.
+ */
/*****************************************************************************/
@@ -74,44 +74,42 @@
/*****************************************************************************/
-int ec_foe_prepare_data_send(ec_fsm_foe_t *);
-int ec_foe_prepare_wrq_send(ec_fsm_foe_t *);
-int ec_foe_prepare_rrq_send(ec_fsm_foe_t *);
-int ec_foe_prepare_send_ack(ec_fsm_foe_t *);
+int ec_foe_prepare_data_send(ec_fsm_foe_t *, ec_datagram_t *);
+int ec_foe_prepare_wrq_send(ec_fsm_foe_t *, ec_datagram_t *);
+int ec_foe_prepare_rrq_send(ec_fsm_foe_t *, ec_datagram_t *);
+int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *);
void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t);
-void ec_fsm_foe_write(ec_fsm_foe_t *);
-void ec_fsm_foe_read(ec_fsm_foe_t *);
-void ec_fsm_foe_end(ec_fsm_foe_t *);
-void ec_fsm_foe_error(ec_fsm_foe_t *);
-
-void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *);
-void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *);
-
-void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *);
-void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *);
-
-void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *);
-
-void ec_fsm_foe_state_data_check(ec_fsm_foe_t *);
-void ec_fsm_foe_state_data_read(ec_fsm_foe_t *);
-void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *);
-
-void ec_fsm_foe_write_start(ec_fsm_foe_t *);
-void ec_fsm_foe_read_start(ec_fsm_foe_t *);
+void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *);
+void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *);
+
+void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *, ec_datagram_t *);
+void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *);
+
+void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *);
+void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *);
+
+void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *);
+
+void ec_fsm_foe_state_data_check(ec_fsm_foe_t *, ec_datagram_t *);
+void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *);
+void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *);
+
+void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *);
+void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *);
/*****************************************************************************/
/** Constructor.
*/
-void ec_fsm_foe_init(ec_fsm_foe_t *fsm, /**< finite state machine */
- ec_mailbox_t *mbox /**< mailbox */
- )
+void ec_fsm_foe_init(
+ ec_fsm_foe_t *fsm /**< finite state machine */
+ )
{
fsm->state = NULL;
- fsm->mbox = mbox;
+ fsm->datagram = NULL;
}
/*****************************************************************************/
@@ -125,13 +123,36 @@
/*****************************************************************************/
/** Executes the current state of the state machine.
- * \return false, if state machine has terminated
- */
-int ec_fsm_foe_exec(ec_fsm_foe_t *fsm /**< finite state machine */)
-{
- fsm->state(fsm);
-
- return fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error;
+ *
+ * \return 1, if the datagram was used, else 0.
+ */
+int ec_fsm_foe_exec(
+ ec_fsm_foe_t *fsm, /**< finite state machine */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
+ int datagram_used = 0;
+
+ if (fsm->datagram &&
+ (fsm->datagram->state == EC_DATAGRAM_INIT ||
+ fsm->datagram->state == EC_DATAGRAM_QUEUED ||
+ fsm->datagram->state == EC_DATAGRAM_SENT)) {
+ // datagram not received yet
+ return datagram_used;
+ }
+
+ fsm->state(fsm, datagram);
+
+ datagram_used =
+ fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error;
+
+ if (datagram_used) {
+ fsm->datagram = datagram;
+ } else {
+ fsm->datagram = NULL;
+ }
+
+ return datagram_used;
}
/*****************************************************************************/
@@ -139,7 +160,7 @@
/** Returns, if the state machine terminated with success.
* \return non-zero if successful.
*/
-int ec_fsm_foe_success(ec_fsm_foe_t *fsm /**< Finite state machine */)
+int ec_fsm_foe_success(const ec_fsm_foe_t *fsm /**< Finite state machine */)
{
return fsm->state == ec_fsm_foe_end;
}
@@ -156,11 +177,25 @@
{
fsm->slave = slave;
fsm->request = request;
+
if (request->dir == EC_DIR_OUTPUT) {
- fsm->state = ec_fsm_foe_write;
+ fsm->tx_buffer = fsm->request->buffer;
+ fsm->tx_buffer_size = fsm->request->data_size;
+ fsm->tx_buffer_offset = 0;
+
+ fsm->tx_filename = fsm->request->file_name;
+ fsm->tx_filename_len = strlen(fsm->tx_filename);
+
+ fsm->state = ec_fsm_foe_write_start;
}
else {
- fsm->state = ec_fsm_foe_read;
+ fsm->rx_buffer = fsm->request->buffer;
+ fsm->rx_buffer_size = fsm->request->buffer_size;
+
+ fsm->rx_filename = fsm->request->file_name;
+ fsm->rx_filename_len = strlen(fsm->rx_filename);
+
+ fsm->state = ec_fsm_foe_read_start;
}
}
@@ -168,10 +203,13 @@
/** State: ERROR.
*/
-void ec_fsm_foe_error(ec_fsm_foe_t *fsm /**< finite state machine */)
-{
-#ifdef DEBUG_FOE
- printk("ec_fsm_foe_error()\n");
+void ec_fsm_foe_error(
+ ec_fsm_foe_t *fsm, /**< finite state machine */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
+#ifdef DEBUG_FOE
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
#endif
}
@@ -179,18 +217,26 @@
/** State: END.
*/
-void ec_fsm_foe_end(ec_fsm_foe_t *fsm /**< finite state machine */)
-{
-#ifdef DEBUG_FOE
- printk("ec_fsm_foe_end\n");
+void ec_fsm_foe_end(
+ ec_fsm_foe_t *fsm, /**< finite state machine */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
+#ifdef DEBUG_FOE
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
#endif
}
/*****************************************************************************/
/** Sends a file or the next fragment.
- */
-int ec_foe_prepare_data_send(ec_fsm_foe_t *fsm)
+ *
+ * \return Zero on success, otherwise a negative error code.
+ */
+int ec_foe_prepare_data_send(
+ ec_fsm_foe_t *fsm, /**< Finite state machine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
{
size_t remaining_size, current_size;
uint8_t *data;
@@ -207,13 +253,14 @@
}
data = ec_slave_mbox_prepare_send(fsm->slave,
- fsm->mbox, EC_MBOX_TYPE_FILEACCESS,
+ datagram, EC_MBOX_TYPE_FILEACCESS,
current_size + EC_FOE_HEADER_SIZE);
- if (IS_ERR(data))
+ if (IS_ERR(data)) {
return -1;
-
- EC_WRITE_U8 ( data, EC_FOE_OPCODE_DATA ); // OpCode = DataBlock req.
- EC_WRITE_U32( data + 2, fsm->tx_packet_no ); // PacketNo, Password
+ }
+
+ EC_WRITE_U16(data, EC_FOE_OPCODE_DATA); // OpCode = DataBlock req.
+ EC_WRITE_U32(data + 2, fsm->tx_packet_no); // PacketNo, Password
memcpy(data + EC_FOE_HEADER_SIZE,
fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
@@ -225,8 +272,13 @@
/*****************************************************************************/
/** Prepare a write request (WRQ) with filename
- */
-int ec_foe_prepare_wrq_send(ec_fsm_foe_t *fsm)
+ *
+ * \return Zero on success, otherwise a negative error code.
+ */
+int ec_foe_prepare_wrq_send(
+ ec_fsm_foe_t *fsm, /**< Finite state machine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
{
size_t current_size;
uint8_t *data;
@@ -238,10 +290,11 @@
current_size = fsm->tx_filename_len;
- data = ec_slave_mbox_prepare_send(fsm->slave, fsm->mbox,
+ data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
- if (IS_ERR(data))
+ if (IS_ERR(data)) {
return -1;
+ }
EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
EC_WRITE_U32( data + 2, fsm->tx_packet_no );
@@ -253,27 +306,12 @@
/*****************************************************************************/
-/** Start a write operation.
- */
-void ec_fsm_foe_write(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
- )
-{
- fsm->tx_buffer = fsm->request->buffer;
- fsm->tx_buffer_size = fsm->request->data_size;
- fsm->tx_buffer_offset = 0;
-
- fsm->tx_filename = fsm->request->file_name;
- fsm->tx_filename_len = strlen(fsm->tx_filename);
-
- fsm->state = ec_fsm_foe_write_start;
-}
-
-/*****************************************************************************/
-
/** Initializes the FoE write state machine.
*/
-void ec_fsm_foe_write_start(ec_fsm_foe_t *fsm /**< finite state machine */)
+void ec_fsm_foe_write_start(
+ ec_fsm_foe_t *fsm, /**< finite state machine */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
{
ec_slave_t *slave = fsm->slave;
@@ -283,7 +321,7 @@
fsm->tx_last_packet = 0;
#ifdef DEBUG_FOE
- printk("ec_fsm_foe_write_start()\n");
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
#endif
if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
@@ -292,7 +330,7 @@
return;
}
- if (ec_foe_prepare_wrq_send(fsm)) {
+ if (ec_foe_prepare_wrq_send(fsm, datagram)) {
ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
return;
}
@@ -305,49 +343,48 @@
/** Check for acknowledge.
*/
void ec_fsm_foe_state_ack_check(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
- )
-{
- ec_mailbox_t *mbox = fsm->mbox;
- ec_datagram_t *datagram = mbox->datagram;
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
ec_slave_t *slave = fsm->slave;
#ifdef DEBUG_FOE
- printk("ec_fsm_foe_ack_check()\n");
-#endif
-
- if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
+#endif
+
+ if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: ");
- ec_datagram_print_state(datagram);
- return;
- }
-
- if (!ec_mbox_is_datagram_wc(mbox, 1)) {
- // slave did not put anything in the mailbox yet
+ ec_datagram_print_state(fsm->datagram);
+ return;
+ }
+
+ if (fsm->datagram->working_counter != 1) {
ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram"
" failed: ");
- ec_datagram_print_wc_error(datagram);
- return;
- }
-
- if (!ec_slave_mbox_check(mbox)) {
- unsigned long diff_ms =
- (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
+ ec_datagram_print_wc_error(fsm->datagram);
+ return;
+ }
+
+ if (!ec_slave_mbox_check(fsm->datagram)) {
+ // slave did not put anything in the mailbox yet
+ unsigned long diff_ms = (fsm->datagram->jiffies_received -
+ fsm->jiffies_start) * 1000 / HZ;
if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR);
EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
return;
}
- ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
+ ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
return;
}
// Fetch response
- ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
+ ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_foe_state_ack_read;
@@ -358,36 +395,35 @@
/** Acknowledge a read operation.
*/
void ec_fsm_foe_state_ack_read(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
- )
-{
- ec_mailbox_t *mbox = fsm->mbox;
- ec_datagram_t *datagram = mbox->datagram;
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
ec_slave_t *slave = fsm->slave;
uint8_t *data, mbox_prot;
uint8_t opCode;
size_t rec_size;
#ifdef DEBUG_FOE
- printk("ec_fsm_foe_ack_read()\n");
-#endif
-
- if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
+#endif
+
+ if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
- ec_datagram_print_state(datagram);
- return;
- }
-
- if (!ec_mbox_is_datagram_wc(mbox, 1)) {
+ ec_datagram_print_state(fsm->datagram);
+ return;
+ }
+
+ if (fsm->datagram->working_counter != 1) {
ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: ");
- ec_datagram_print_wc_error(datagram);
- return;
- }
-
- if (!(data = ec_slave_mbox_fetch(fsm->slave, fsm->mbox,
- &mbox_prot, &rec_size))) {
+ ec_datagram_print_wc_error(fsm->datagram);
+ return;
+ }
+
+ data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
+ if (IS_ERR(data)) {
ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
return;
}
@@ -403,7 +439,7 @@
if (opCode == EC_FOE_OPCODE_BUSY) {
// slave not ready
- if (ec_foe_prepare_data_send(fsm)) {
+ if (ec_foe_prepare_data_send(fsm, datagram)) {
ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
EC_SLAVE_ERR(slave, "Slave is busy.\n");
return;
@@ -421,7 +457,7 @@
return;
}
- if (ec_foe_prepare_data_send(fsm)) {
+ if (ec_foe_prepare_data_send(fsm, datagram)) {
ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
return;
}
@@ -439,35 +475,34 @@
* fragment, if necessary.
*/
void ec_fsm_foe_state_wrq_sent(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
- )
-{
- ec_mailbox_t *mbox = fsm->mbox;
- ec_datagram_t *datagram = mbox->datagram;
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
ec_slave_t *slave = fsm->slave;
#ifdef DEBUG_FOE
- printk("ec_foe_state_sent_wrq()\n");
-#endif
-
- if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
+#endif
+
+ if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
- ec_datagram_print_state(datagram);
- return;
- }
-
- if (!ec_mbox_is_datagram_wc(mbox, 1)) {
+ ec_datagram_print_state(fsm->datagram);
+ return;
+ }
+
+ if (fsm->datagram->working_counter != 1) {
// slave did not put anything in the mailbox yet
ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
- ec_datagram_print_wc_error(datagram);
- return;
- }
-
- fsm->jiffies_start = datagram->jiffies_sent;
-
- ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
+ ec_datagram_print_wc_error(fsm->datagram);
+ return;
+ }
+
+ fsm->jiffies_start = fsm->datagram->jiffies_sent;
+
+ ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_foe_state_ack_check;
@@ -481,32 +516,31 @@
* fragment, if necessary.
*/
void ec_fsm_foe_state_data_sent(
- ec_fsm_foe_t *fsm /**< Foe statemachine. */
- )
-{
- ec_mailbox_t *mbox = fsm->mbox;
- ec_datagram_t *datagram = mbox->datagram;
+ ec_fsm_foe_t *fsm, /**< Foe statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
ec_slave_t *slave = fsm->slave;
#ifdef DEBUG_FOE
- printk("ec_fsm_foe_state_data_sent()\n");
-#endif
-
- if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
+#endif
+
+ if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR);
EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
- ec_datagram_print_state(datagram);
- return;
- }
-
- if (!ec_mbox_is_datagram_wc(mbox, 1)) {
+ ec_datagram_print_state(fsm->datagram);
+ return;
+ }
+
+ if (fsm->datagram->working_counter != 1) {
ec_foe_set_tx_error(fsm, FOE_WC_ERROR);
EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
- ec_datagram_print_wc_error(datagram);
- return;
- }
-
- ec_slave_mbox_prepare_check(slave, mbox);
+ ec_datagram_print_wc_error(fsm->datagram);
+ return;
+ }
+
+ ec_slave_mbox_prepare_check(slave, datagram);
fsm->jiffies_start = jiffies;
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_foe_state_ack_check;
@@ -515,18 +549,24 @@
/*****************************************************************************/
/** Prepare a read request (RRQ) with filename
- */
-int ec_foe_prepare_rrq_send(ec_fsm_foe_t *fsm)
+ *
+ * \return Zero on success, otherwise a negative error code.
+ */
+int ec_foe_prepare_rrq_send(
+ ec_fsm_foe_t *fsm, /**< Finite state machine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
{
size_t current_size;
uint8_t *data;
current_size = fsm->rx_filename_len;
- data = ec_slave_mbox_prepare_send(fsm->slave, fsm->mbox,
+ data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
- if (IS_ERR(data))
+ if (IS_ERR(data)) {
return -1;
+ }
EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
EC_WRITE_U32(data + 2, 0x00000000); // no passwd
@@ -543,20 +583,24 @@
/*****************************************************************************/
/** Prepare to send an acknowledge.
+ *
+ * \return Zero on success, otherwise a negative error code.
*/
int ec_foe_prepare_send_ack(
- ec_fsm_foe_t *foe /**< FoE statemachine. */
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
)
{
uint8_t *data;
- data = ec_slave_mbox_prepare_send(foe->slave, foe->mbox,
+ data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE);
- if (IS_ERR(data))
+ if (IS_ERR(data)) {
return -1;
+ }
EC_WRITE_U16(data, EC_FOE_OPCODE_ACK);
- EC_WRITE_U32(data + 2, foe->rx_expected_packet_no);
+ EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no);
return 0;
}
@@ -565,39 +609,38 @@
/** State: RRQ SENT.
*
- * Checks is the previous transmit datagram succeded and sends the next
+ * Checks is the previous transmit datagram succeeded and sends the next
* fragment, if necessary.
*/
void ec_fsm_foe_state_rrq_sent(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
- )
-{
- ec_mailbox_t *mbox = fsm->mbox;
- ec_datagram_t *datagram = mbox->datagram;
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
ec_slave_t *slave = fsm->slave;
#ifdef DEBUG_FOE
- printk("ec_foe_state_rrq_sent()\n");
-#endif
-
- if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
+#endif
+
+ if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
- ec_datagram_print_state(datagram);
- return;
- }
-
- if (!ec_mbox_is_datagram_wc(mbox, 1)) {
+ ec_datagram_print_state(fsm->datagram);
+ return;
+ }
+
+ if (fsm->datagram->working_counter != 1) {
// slave did not put anything in the mailbox yet
ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
- ec_datagram_print_wc_error(datagram);
- return;
- }
-
- fsm->jiffies_start = datagram->jiffies_sent;
-
- ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
+ ec_datagram_print_wc_error(fsm->datagram);
+ return;
+ }
+
+ fsm->jiffies_start = fsm->datagram->jiffies_sent;
+
+ ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_foe_state_data_check;
@@ -605,26 +648,11 @@
/*****************************************************************************/
-/** Start a read operation.
- */
-void ec_fsm_foe_read(
- ec_fsm_foe_t *fsm /**< FoE state machine. */
- )
-{
- fsm->state = ec_fsm_foe_read_start;
- fsm->rx_filename = fsm->request->file_name;
- fsm->rx_filename_len = strlen(fsm->rx_filename);
-
- fsm->rx_buffer = fsm->request->buffer;
- fsm->rx_buffer_size = fsm->request->buffer_size;
-}
-
-/*****************************************************************************/
-
/** Starting state for read operations.
*/
void ec_fsm_foe_read_start(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
)
{
ec_slave_t *slave = fsm->slave;
@@ -634,7 +662,7 @@
fsm->rx_last_packet = 0;
#ifdef DEBUG_FOE
- printk("ec_fsm_foe_read_start()\n");
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
#endif
if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
@@ -643,7 +671,7 @@
return;
}
- if (ec_foe_prepare_rrq_send(fsm)) {
+ if (ec_foe_prepare_rrq_send(fsm, datagram)) {
ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
return;
}
@@ -656,51 +684,49 @@
/** Check for data.
*/
void ec_fsm_foe_state_data_check(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
- )
-{
- ec_mailbox_t *mbox = fsm->mbox;
- ec_datagram_t *datagram = mbox->datagram;
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
ec_slave_t *slave = fsm->slave;
#ifdef DEBUG_FOE
- printk("ec_fsm_foe_state_data_check()\n");
-#endif
-
- if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
+#endif
+
+ if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: ");
- ec_datagram_print_state(datagram);
- return;
- }
-
- if (!ec_mbox_is_datagram_wc(mbox, 1)) {
+ ec_datagram_print_state(fsm->datagram);
+ return;
+ }
+
+ if (fsm->datagram->working_counter != 1) {
ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: ");
- ec_datagram_print_wc_error(datagram);
- return;
- }
-
- if (!ec_slave_mbox_check(mbox)) {
- unsigned long diff_ms =
- (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
+ ec_datagram_print_wc_error(fsm->datagram);
+ return;
+ }
+
+ if (!ec_slave_mbox_check(fsm->datagram)) {
+ unsigned long diff_ms = (fsm->datagram->jiffies_received -
+ fsm->jiffies_start) * 1000 / HZ;
if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR);
EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
return;
}
- ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
+ ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
return;
}
// Fetch response
- ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
+ ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_foe_state_data_read;
-
}
/*****************************************************************************/
@@ -708,35 +734,35 @@
/** Start reading data.
*/
void ec_fsm_foe_state_data_read(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
)
{
size_t rec_size;
uint8_t *data, opCode, packet_no, mbox_prot;
- ec_mailbox_t *mbox = fsm->mbox;
- ec_datagram_t *datagram = mbox->datagram;
ec_slave_t *slave = fsm->slave;
#ifdef DEBUG_FOE
- printk("ec_fsm_foe_state_data_read()\n");
-#endif
-
- if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
+#endif
+
+ if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: ");
- ec_datagram_print_state(datagram);
- return;
- }
-
- if (!ec_mbox_is_datagram_wc(mbox, 1)) {
+ ec_datagram_print_state(fsm->datagram);
+ return;
+ }
+
+ if (fsm->datagram->working_counter != 1) {
ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: ");
- ec_datagram_print_wc_error(datagram);
- return;
- }
-
- if (!(data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size))) {
+ ec_datagram_print_wc_error(fsm->datagram);
+ return;
+ }
+
+ data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
+ if (IS_ERR(data)) {
ec_foe_set_rx_error(fsm, FOE_MBOX_FETCH_ERROR);
return;
}
@@ -751,7 +777,7 @@
opCode = EC_READ_U8(data);
if (opCode == EC_FOE_OPCODE_BUSY) {
- if (ec_foe_prepare_send_ack(fsm)) {
+ if (ec_foe_prepare_send_ack(fsm, datagram)) {
ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
}
return;
@@ -795,7 +821,7 @@
fsm->rx_last_packet =
(rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE
- != fsm->slave->configured_rx_mailbox_size);
+ != slave->configured_rx_mailbox_size);
if (fsm->rx_last_packet ||
(slave->configured_rx_mailbox_size - EC_MBOX_HEADER_SIZE
@@ -804,9 +830,9 @@
// either it was the last packet or a new packet will fit into the
// delivered buffer
#ifdef DEBUG_FOE
- printk ("last_packet=true\n");
-#endif
- if (ec_foe_prepare_send_ack(fsm)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "last_packet=true\n");
+#endif
+ if (ec_foe_prepare_send_ack(fsm, datagram)) {
ec_foe_set_rx_error(fsm, FOE_RX_DATA_ACK_ERROR);
return;
}
@@ -816,13 +842,12 @@
else {
// no more data fits into the delivered buffer
// ... wait for new read request
- printk ("ERROR: data doesn't fit in receive buffer\n");
- printk (" rx_buffer_size = %d\n", fsm->rx_buffer_size);
- printk (" rx_buffer_offset= %d\n", fsm->rx_buffer_offset);
- printk (" rec_size = %zd\n", rec_size);
- printk (" rx_mailbox_size = %d\n",
- slave->configured_rx_mailbox_size);
- printk (" rx_last_packet = %d\n", fsm->rx_last_packet);
+ EC_SLAVE_ERR(slave, "Data do not fit in receive buffer!\n");
+ printk(" rx_buffer_size = %d\n", fsm->rx_buffer_size);
+ printk("rx_buffer_offset = %d\n", fsm->rx_buffer_offset);
+ printk(" rec_size = %zd\n", rec_size);
+ printk(" rx_mailbox_size = %d\n", slave->configured_rx_mailbox_size);
+ printk(" rx_last_packet = %d\n", fsm->rx_last_packet);
fsm->request->result = FOE_READY;
}
}
@@ -832,35 +857,34 @@
/** Sent an acknowledge.
*/
void ec_fsm_foe_state_sent_ack(
- ec_fsm_foe_t *fsm /**< FoE statemachine. */
- )
-{
- ec_mailbox_t *mbox = fsm->mbox;
- ec_datagram_t *datagram = mbox->datagram;
+ ec_fsm_foe_t *fsm, /**< FoE statemachine. */
+ ec_datagram_t *datagram /**< Datagram to use. */
+ )
+{
ec_slave_t *slave = fsm->slave;
#ifdef DEBUG_FOE
- printk("ec_foe_state_sent_ack()\n");
-#endif
-
- if (!ec_mbox_is_datagram_state(mbox, EC_DATAGRAM_RECEIVED)) {
+ EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__);
+#endif
+
+ if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
- ec_datagram_print_state(datagram);
- return;
- }
-
- if (!ec_mbox_is_datagram_wc(mbox, 1)) {
+ ec_datagram_print_state(fsm->datagram);
+ return;
+ }
+
+ if (fsm->datagram->working_counter != 1) {
// slave did not put anything into the mailbox yet
ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
- ec_datagram_print_wc_error(datagram);
- return;
- }
-
- fsm->jiffies_start = datagram->jiffies_sent;
-
- ec_slave_mbox_prepare_check(fsm->slave, fsm->mbox); // can not fail.
+ ec_datagram_print_wc_error(fsm->datagram);
+ return;
+ }
+
+ fsm->jiffies_start = fsm->datagram->jiffies_sent;
+
+ ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
if (fsm->rx_last_packet) {
fsm->rx_expected_packet_no = 0;