# HG changeset patch # User Florian Pose # Date 1354628963 -3600 # Node ID 35611452b785566856e5315046c0d1dd0bf507e4 # Parent e6cc33cac6a29fdfe98c993712e8c920c6cc85aa Removed unnecessary ec_master_soe_request_t type. diff -r e6cc33cac6a2 -r 35611452b785 master/fsm_master.h --- a/master/fsm_master.h Tue Dec 04 14:26:30 2012 +0100 +++ b/master/fsm_master.h Tue Dec 04 14:49:23 2012 +0100 @@ -61,16 +61,6 @@ /*****************************************************************************/ -/** 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 -r e6cc33cac6a2 -r 35611452b785 master/fsm_slave.c --- a/master/fsm_slave.c Tue Dec 04 14:26:30 2012 +0100 +++ b/master/fsm_slave.c Tue Dec 04 14:49:23 2012 +0100 @@ -457,43 +457,43 @@ ) { ec_slave_t *slave = fsm->slave; - ec_master_soe_request_t *req, *next; - - // 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; - } - return 0; + ec_soe_request_t *req; + + if (list_empty(&slave->soe_requests)) { + 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 -r e6cc33cac6a2 -r 35611452b785 master/master.c --- a/master/master.c Tue Dec 04 14:26:30 2012 +0100 +++ b/master/master.c Tue Dec 04 14:49:23 2012 +0100 @@ -2919,73 +2919,76 @@ 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); - - if (ec_soe_request_alloc(&request.req, data_size)) { - ec_soe_request_clear(&request.req); - return -ENOMEM; - } - - memcpy(request.req.data, data, data_size); - request.req.data_size = data_size; - ec_soe_request_write(&request.req); - - if (down_interruptible(&master->master_sem)) + ec_soe_request_init(&request); + ec_soe_request_set_drive_no(&request, drive_no); + ec_soe_request_set_idn(&request, idn); + + ret = ec_soe_request_alloc(&request, data_size); + if (ret) { + ec_soe_request_clear(&request); + return ret; + } + + memcpy(request.data, data, data_size); + request.data_size = data_size; + ec_soe_request_write(&request); + + 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; - } - retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; - ec_soe_request_clear(&request.req); - - return retval; + *error_code = request.error_code; + } + ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; + ec_soe_request_clear(&request); + + return ret; } /*****************************************************************************/ @@ -2994,80 +2997,86 @@ 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); - - if (down_interruptible(&master->master_sem)) + 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)) { + 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; - } - - EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via SoE.\n", - request.req.data_size); - - if (request.req.state != EC_INT_REQUEST_SUCCESS) { + *error_code = request.error_code; + } + + EC_SLAVE_DBG(slave, 1, "Read %zd bytes via SoE.\n", request.data_size); + + 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; - } - if (result_size) { - *result_size = request.req.data_size; - } - memcpy(target, request.req.data, request.req.data_size); - return 0; - } + ret = -EOVERFLOW; + } + else { // data fits in buffer + if (result_size) { + *result_size = request.data_size; + } + memcpy(target, request.data, request.data_size); + ret = 0; + } + } + + ec_soe_request_clear(&request); + return ret; } /*****************************************************************************/ diff -r e6cc33cac6a2 -r 35611452b785 master/slave.c --- a/master/slave.c Tue Dec 04 14:26:30 2012 +0100 +++ b/master/slave.c Tue Dec 04 14:49:23 2012 +0100 @@ -225,13 +225,12 @@ } 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 -r e6cc33cac6a2 -r 35611452b785 master/soe_request.c --- a/master/soe_request.c Tue Dec 04 14:26:30 2012 +0100 +++ b/master/soe_request.c Tue Dec 04 14:49:23 2012 +0100 @@ -57,6 +57,7 @@ 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;