From 72b60d1c0798cd206166ae8b74eb7a267039a3dc Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 4 Dec 2012 14:49:23 +0100 Subject: [PATCH] Removed unnecessary ec_master_soe_request_t type. --- master/fsm_master.h | 10 ---- master/fsm_slave.c | 70 ++++++++++++------------ master/master.c | 127 +++++++++++++++++++++++-------------------- master/slave.c | 7 +-- master/soe_request.c | 1 + 5 files changed, 107 insertions(+), 108 deletions(-) diff --git a/master/fsm_master.h b/master/fsm_master.h index 8f836fef..3a0a8839 100644 --- a/master/fsm_master.h +++ b/master/fsm_master.h @@ -61,16 +61,6 @@ typedef struct { /*****************************************************************************/ -/** SoE request. - */ -typedef struct { - struct list_head list; /**< List head. */ - ec_slave_t *slave; /**< EtherCAT slave. */ - ec_soe_request_t req; /**< SoE request. */ -} ec_master_soe_request_t; - -/*****************************************************************************/ - typedef struct ec_fsm_master ec_fsm_master_t; /**< \see ec_fsm_master */ /** Finite state machine of an EtherCAT master. diff --git a/master/fsm_slave.c b/master/fsm_slave.c index 7ef09111..878e44ea 100644 --- a/master/fsm_slave.c +++ b/master/fsm_slave.c @@ -457,43 +457,43 @@ int ec_fsm_slave_action_process_soe( ) { ec_slave_t *slave = fsm->slave; - ec_master_soe_request_t *req, *next; + ec_soe_request_t *req; - // search the first request to be processed - list_for_each_entry_safe(req, next, &slave->soe_requests, list) { - - list_del_init(&req->list); // dequeue - if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { - EC_SLAVE_WARN(slave, "Aborting SoE request," - " slave has error flag set.\n"); - req->req.state = EC_INT_REQUEST_FAILURE; - wake_up(&slave->soe_queue); - fsm->state = ec_fsm_slave_state_idle; - return 0; - } - - if (slave->current_state == EC_SLAVE_STATE_INIT) { - EC_SLAVE_WARN(slave, "Aborting SoE request, slave is in INIT.\n"); - req->req.state = EC_INT_REQUEST_FAILURE; - wake_up(&slave->soe_queue); - fsm->state = ec_fsm_slave_state_idle; - return 0; - } - - req->req.state = EC_INT_REQUEST_BUSY; - - // Found pending request. Execute it! - EC_SLAVE_DBG(slave, 1, "Processing SoE request...\n"); - - // Start SoE transfer - fsm->soe_request = &req->req; - fsm->state = ec_fsm_slave_state_soe_request; - ec_fsm_soe_transfer(&fsm->fsm_soe, slave, &req->req); - ec_fsm_soe_exec(&fsm->fsm_soe); // execute immediately - ec_master_queue_external_datagram(fsm->slave->master, fsm->datagram); - return 1; + if (list_empty(&slave->soe_requests)) { + return 0; } - return 0; + + // take the first request to be processed + req = list_entry(slave->soe_requests.next, ec_soe_request_t, list); + list_del_init(&req->list); // dequeue + + if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { + EC_SLAVE_WARN(slave, "Aborting SoE request," + " slave has error flag set.\n"); + req->state = EC_INT_REQUEST_FAILURE; + wake_up(&slave->soe_queue); + return 0; + } + + if (slave->current_state == EC_SLAVE_STATE_INIT) { + EC_SLAVE_WARN(slave, "Aborting SoE request, slave is in INIT.\n"); + req->state = EC_INT_REQUEST_FAILURE; + wake_up(&slave->soe_queue); + return 0; + } + + req->state = EC_INT_REQUEST_BUSY; + + // Found pending request. Execute it! + EC_SLAVE_DBG(slave, 1, "Processing SoE request...\n"); + + // Start SoE transfer + fsm->soe_request = req; + fsm->state = ec_fsm_slave_state_soe_request; + ec_fsm_soe_transfer(&fsm->fsm_soe, slave, req); + ec_fsm_soe_exec(&fsm->fsm_soe); // execute immediately + ec_master_queue_external_datagram(fsm->slave->master, fsm->datagram); + return 1; } /*****************************************************************************/ diff --git a/master/master.c b/master/master.c index 723cea90..34cd688f 100644 --- a/master/master.c +++ b/master/master.c @@ -2919,73 +2919,76 @@ int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size, uint16_t *error_code) { - ec_master_soe_request_t request; - int retval; + ec_soe_request_t request; + ec_slave_t *slave; + int ret; if (drive_no > 7) { EC_MASTER_ERR(master, "Invalid drive number!\n"); return -EINVAL; } - INIT_LIST_HEAD(&request.list); - ec_soe_request_init(&request.req); - ec_soe_request_set_drive_no(&request.req, drive_no); - ec_soe_request_set_idn(&request.req, idn); + ec_soe_request_init(&request); + ec_soe_request_set_drive_no(&request, drive_no); + ec_soe_request_set_idn(&request, idn); - if (ec_soe_request_alloc(&request.req, data_size)) { - ec_soe_request_clear(&request.req); - return -ENOMEM; + ret = ec_soe_request_alloc(&request, data_size); + if (ret) { + ec_soe_request_clear(&request); + return ret; } - memcpy(request.req.data, data, data_size); - request.req.data_size = data_size; - ec_soe_request_write(&request.req); + memcpy(request.data, data, data_size); + request.data_size = data_size; + ec_soe_request_write(&request); - if (down_interruptible(&master->master_sem)) + if (down_interruptible(&master->master_sem)) { + ec_soe_request_clear(&request); return -EINTR; + } - if (!(request.slave = ec_master_find_slave( - master, 0, slave_position))) { + if (!(slave = ec_master_find_slave(master, 0, slave_position))) { up(&master->master_sem); EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position); - ec_soe_request_clear(&request.req); + ec_soe_request_clear(&request); return -EINVAL; } - EC_SLAVE_DBG(request.slave, 1, "Scheduling SoE write request.\n"); + EC_SLAVE_DBG(slave, 1, "Scheduling SoE write request.\n"); // schedule SoE write request. - list_add_tail(&request.list, &request.slave->soe_requests); + list_add_tail(&request.list, &slave->soe_requests); up(&master->master_sem); // wait for processing through FSM - if (wait_event_interruptible(request.slave->soe_queue, - request.req.state != EC_INT_REQUEST_QUEUED)) { + if (wait_event_interruptible(slave->soe_queue, + request.state != EC_INT_REQUEST_QUEUED)) { // interrupted by signal down(&master->master_sem); - if (request.req.state == EC_INT_REQUEST_QUEUED) { + if (request.state == EC_INT_REQUEST_QUEUED) { // abort request list_del(&request.list); up(&master->master_sem); - ec_soe_request_clear(&request.req); + ec_soe_request_clear(&request); return -EINTR; } up(&master->master_sem); } + // FIXME slave may become invalid + // wait until master FSM has finished processing - wait_event(request.slave->soe_queue, - request.req.state != EC_INT_REQUEST_BUSY); + wait_event(slave->soe_queue, request.state != EC_INT_REQUEST_BUSY); if (error_code) { - *error_code = request.req.error_code; + *error_code = request.error_code; } - retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; - ec_soe_request_clear(&request.req); + ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; + ec_soe_request_clear(&request); - return retval; + return ret; } /*****************************************************************************/ @@ -2994,80 +2997,86 @@ int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size, size_t *result_size, uint16_t *error_code) { - ec_master_soe_request_t request; + ec_soe_request_t request; + ec_slave_t *slave; + int ret; if (drive_no > 7) { EC_MASTER_ERR(master, "Invalid drive number!\n"); return -EINVAL; } - INIT_LIST_HEAD(&request.list); - ec_soe_request_init(&request.req); - ec_soe_request_set_drive_no(&request.req, drive_no); - ec_soe_request_set_idn(&request.req, idn); - ec_soe_request_read(&request.req); + ec_soe_request_init(&request); + ec_soe_request_set_drive_no(&request, drive_no); + ec_soe_request_set_idn(&request, idn); + ec_soe_request_read(&request); - if (down_interruptible(&master->master_sem)) + if (down_interruptible(&master->master_sem)) { + ec_soe_request_clear(&request); return -EINTR; + } - if (!(request.slave = ec_master_find_slave(master, 0, slave_position))) { + if (!(slave = ec_master_find_slave(master, 0, slave_position))) { up(&master->master_sem); - ec_soe_request_clear(&request.req); + ec_soe_request_clear(&request); EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position); return -EINVAL; } // schedule request. - list_add_tail(&request.list, &request.slave->soe_requests); + list_add_tail(&request.list, &slave->soe_requests); up(&master->master_sem); - EC_SLAVE_DBG(request.slave, 1, "Scheduled SoE read request.\n"); + EC_SLAVE_DBG(slave, 1, "Scheduled SoE read request.\n"); // wait for processing through FSM - if (wait_event_interruptible(request.slave->soe_queue, - request.req.state != EC_INT_REQUEST_QUEUED)) { + if (wait_event_interruptible(slave->soe_queue, + request.state != EC_INT_REQUEST_QUEUED)) { // interrupted by signal down(&master->master_sem); - if (request.req.state == EC_INT_REQUEST_QUEUED) { + if (request.state == EC_INT_REQUEST_QUEUED) { list_del(&request.list); up(&master->master_sem); - ec_soe_request_clear(&request.req); + ec_soe_request_clear(&request); return -EINTR; } // request already processing: interrupt not possible. up(&master->master_sem); } + // FIXME slave may become invalid + // wait until master FSM has finished processing - wait_event(request.slave->soe_queue, - request.req.state != EC_INT_REQUEST_BUSY); + wait_event(slave->soe_queue, request.state != EC_INT_REQUEST_BUSY); if (error_code) { - *error_code = request.req.error_code; + *error_code = request.error_code; } - EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via SoE.\n", - request.req.data_size); + EC_SLAVE_DBG(slave, 1, "Read %zd bytes via SoE.\n", request.data_size); - if (request.req.state != EC_INT_REQUEST_SUCCESS) { + if (request.state != EC_INT_REQUEST_SUCCESS) { if (result_size) { *result_size = 0; } - ec_soe_request_clear(&request.req); - return -EIO; - } else { - if (request.req.data_size > target_size) { + ret = -EIO; + } else { // success + if (request.data_size > target_size) { EC_MASTER_ERR(master, "Buffer too small.\n"); - ec_soe_request_clear(&request.req); - return -EOVERFLOW; + ret = -EOVERFLOW; } - if (result_size) { - *result_size = request.req.data_size; + else { // data fits in buffer + if (result_size) { + *result_size = request.data_size; + } + memcpy(target, request.data, request.data_size); + ret = 0; } - memcpy(target, request.req.data, request.req.data_size); - return 0; } + + ec_soe_request_clear(&request); + return ret; } /*****************************************************************************/ diff --git a/master/slave.c b/master/slave.c index 5114ea12..56fc099b 100644 --- a/master/slave.c +++ b/master/slave.c @@ -225,13 +225,12 @@ void ec_slave_clear(ec_slave_t *slave /**< EtherCAT slave */) } while (!list_empty(&slave->soe_requests)) { - ec_master_soe_request_t *request = - list_entry(slave->soe_requests.next, - ec_master_soe_request_t, list); + ec_soe_request_t *request = + list_entry(slave->soe_requests.next, ec_soe_request_t, list); list_del_init(&request->list); // dequeue EC_SLAVE_WARN(slave, "Discarding SoE request," " slave about to be deleted.\n"); - request->req.state = EC_INT_REQUEST_FAILURE; + request->state = EC_INT_REQUEST_FAILURE; wake_up(&slave->soe_queue); } diff --git a/master/soe_request.c b/master/soe_request.c index 3ac67171..4673e646 100644 --- a/master/soe_request.c +++ b/master/soe_request.c @@ -57,6 +57,7 @@ void ec_soe_request_init( ec_soe_request_t *req /**< SoE request. */ ) { + INIT_LIST_HEAD(&req->list); req->drive_no = 0x00; req->idn = 0x0000; req->al_state = EC_AL_STATE_INIT;