# HG changeset patch # User Florian Pose # Date 1354627590 -3600 # Node ID e6cc33cac6a29fdfe98c993712e8c920c6cc85aa # Parent 71d38ff288b3ccd79840a83c0b7c2e3f53a55417 Removed unnecessary ec_master_foe_request_t; fixed FoE access. diff -r 71d38ff288b3 -r e6cc33cac6a2 master/foe_request.c --- a/master/foe_request.c Tue Dec 04 14:24:01 2012 +0100 +++ b/master/foe_request.c Tue Dec 04 14:26:30 2012 +0100 @@ -58,6 +58,7 @@ ec_foe_request_t *req, /**< FoE request. */ uint8_t* file_name /** filename */) { + INIT_LIST_HEAD(&req->list); req->buffer = NULL; req->file_name = file_name; req->buffer_size = 0; @@ -109,14 +110,15 @@ size_t size /**< Data size to allocate. */ ) { - if (size <= req->buffer_size) + if (size <= req->buffer_size) { return 0; + } ec_foe_request_clear_data(req); if (!(req->buffer = (uint8_t *) kmalloc(size, GFP_KERNEL))) { EC_ERR("Failed to allocate %zu bytes of FoE memory.\n", size); - return -1; + return -ENOMEM; } req->buffer_size = size; @@ -136,8 +138,12 @@ size_t size /**< Number of bytes in \a source. */ ) { - if (ec_foe_request_alloc(req, size)) - return -1; + int ret; + + ret = ec_foe_request_alloc(req, size); + if (ret) { + return ret; + } memcpy(req->buffer, source, size); req->data_size = size; diff -r 71d38ff288b3 -r e6cc33cac6a2 master/foe_request.h --- a/master/foe_request.h Tue Dec 04 14:24:01 2012 +0100 +++ b/master/foe_request.h Tue Dec 04 14:26:30 2012 +0100 @@ -37,6 +37,8 @@ #ifndef __EC_FOE_REQUEST_H__ #define __EC_FOE_REQUEST_H__ +#include + #include "../include/ecrt.h" #include "globals.h" @@ -46,6 +48,7 @@ /** FoE request. */ typedef struct { + struct list_head list; /**< List item. */ uint8_t *buffer; /**< Pointer to FoE data. */ size_t buffer_size; /**< Size of FoE data memory. */ size_t data_size; /**< Size of FoE data. */ @@ -68,7 +71,7 @@ /*****************************************************************************/ -void ec_foe_request_init(ec_foe_request_t *, uint8_t* file_name); +void ec_foe_request_init(ec_foe_request_t *, uint8_t *file_name); void ec_foe_request_clear(ec_foe_request_t *); int ec_foe_request_alloc(ec_foe_request_t *, size_t); diff -r 71d38ff288b3 -r e6cc33cac6a2 master/fsm_master.h --- a/master/fsm_master.h Tue Dec 04 14:24:01 2012 +0100 +++ b/master/fsm_master.h Tue Dec 04 14:26:30 2012 +0100 @@ -61,16 +61,6 @@ /*****************************************************************************/ -/** FoE request. - */ -typedef struct { - struct list_head list; /**< List head. */ - ec_slave_t *slave; /**< EtherCAT slave. */ - ec_foe_request_t req; /**< FoE request. */ -} ec_master_foe_request_t; - -/*****************************************************************************/ - /** SoE request. */ typedef struct { diff -r 71d38ff288b3 -r e6cc33cac6a2 master/fsm_slave.c --- a/master/fsm_slave.c Tue Dec 04 14:24:01 2012 +0100 +++ b/master/fsm_slave.c Tue Dec 04 14:26:30 2012 +0100 @@ -380,32 +380,34 @@ ) { ec_slave_t *slave = fsm->slave; - ec_master_foe_request_t *request, *next; - - // search the first request to be processed - list_for_each_entry_safe(request, next, &slave->foe_requests, list) { - if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { - EC_SLAVE_WARN(slave, "Aborting FoE request," - " slave has error flag set.\n"); - request->req.state = EC_INT_REQUEST_FAILURE; - wake_up(&slave->sdo_queue); - fsm->sdo_request = NULL; - fsm->state = ec_fsm_slave_state_idle; - return 0; - } - list_del_init(&request->list); // dequeue - request->req.state = EC_INT_REQUEST_BUSY; - - EC_SLAVE_DBG(slave, 1, "Processing FoE request.\n"); - - fsm->foe_request = &request->req; - fsm->state = ec_fsm_slave_state_foe_request; - ec_fsm_foe_transfer(&fsm->fsm_foe, slave, &request->req); - ec_fsm_foe_exec(&fsm->fsm_foe); - ec_master_queue_external_datagram(fsm->slave->master, fsm->datagram); - return 1; - } - return 0; + ec_foe_request_t *request; + + if (list_empty(&slave->foe_requests)) { + return 0; + } + + // take the first request to be processed + request = list_entry(slave->foe_requests.next, ec_foe_request_t, list); + list_del_init(&request->list); // dequeue + + if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { + EC_SLAVE_WARN(slave, "Aborting FoE request," + " slave has error flag set.\n"); + request->state = EC_INT_REQUEST_FAILURE; + wake_up(&slave->sdo_queue); + return 0; + } + + request->state = EC_INT_REQUEST_BUSY; + + EC_SLAVE_DBG(slave, 1, "Processing FoE request.\n"); + + fsm->foe_request = request; + fsm->state = ec_fsm_slave_state_foe_request; + ec_fsm_foe_transfer(&fsm->fsm_foe, slave, request); + ec_fsm_foe_exec(&fsm->fsm_foe); + ec_master_queue_external_datagram(fsm->slave->master, fsm->datagram); + return 1; } /*****************************************************************************/ diff -r 71d38ff288b3 -r e6cc33cac6a2 master/ioctl.c --- a/master/ioctl.c Tue Dec 04 14:24:01 2012 +0100 +++ b/master/ioctl.c Tue Dec 04 14:26:30 2012 +0100 @@ -3566,91 +3566,97 @@ void *arg /**< ioctl() argument. */ ) { - ec_ioctl_slave_foe_t data; - ec_master_foe_request_t request; - int retval; - - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { - return -EFAULT; - } - - ec_foe_request_init(&request.req, data.file_name); - ec_foe_request_read(&request.req); - ec_foe_request_alloc(&request.req, 10000); // FIXME + ec_ioctl_slave_foe_t io; + ec_foe_request_t request; + ec_slave_t *slave; + int ret; + + if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + return -EFAULT; + } + + ec_foe_request_init(&request, io.file_name); + ret = ec_foe_request_alloc(&request, 10000); // FIXME + if (ret) { + ec_foe_request_clear(&request); + return ret; + } + + ec_foe_request_read(&request); if (down_interruptible(&master->master_sem)) { - ec_foe_request_clear(&request.req); + ec_foe_request_clear(&request); return -EINTR; } - if (!(request.slave = ec_master_find_slave( - master, 0, data.slave_position))) { - up(&master->master_sem); - ec_foe_request_clear(&request.req); + if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) { + up(&master->master_sem); + ec_foe_request_clear(&request); EC_MASTER_ERR(master, "Slave %u does not exist!\n", - data.slave_position); + io.slave_position); return -EINVAL; } // schedule request. - list_add_tail(&request.list, &request.slave->foe_requests); + list_add_tail(&request.list, &slave->foe_requests); up(&master->master_sem); - EC_SLAVE_DBG(request.slave, 1, "Scheduled FoE read request.\n"); + EC_SLAVE_DBG(slave, 1, "Scheduled FoE read request.\n"); // wait for processing through FSM - if (wait_event_interruptible(request.slave->foe_queue, - request.req.state != EC_INT_REQUEST_QUEUED)) { + if (wait_event_interruptible(slave->foe_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_foe_request_clear(&request.req); + ec_foe_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->foe_queue, - request.req.state != EC_INT_REQUEST_BUSY); - - data.result = request.req.result; - data.error_code = request.req.error_code; - - EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via FoE" - " (result = 0x%x).\n", request.req.data_size, request.req.result); - - if (request.req.state != EC_INT_REQUEST_SUCCESS) { - data.data_size = 0; - retval = -EIO; + wait_event(slave->foe_queue, request.state != EC_INT_REQUEST_BUSY); + + io.result = request.result; + io.error_code = request.error_code; + + EC_SLAVE_DBG(slave, 1, "Read %zd bytes via FoE (result = 0x%x).\n", + request.data_size, request.result); + + if (request.state != EC_INT_REQUEST_SUCCESS) { + io.data_size = 0; + ret = -EIO; } else { - if (request.req.data_size > data.buffer_size) { + if (request.data_size > io.buffer_size) { EC_MASTER_ERR(master, "Buffer too small.\n"); - ec_foe_request_clear(&request.req); + ec_foe_request_clear(&request); return -EOVERFLOW; } - data.data_size = request.req.data_size; - if (copy_to_user((void __user *) data.buffer, - request.req.buffer, data.data_size)) { - ec_foe_request_clear(&request.req); + io.data_size = request.data_size; + if (copy_to_user((void __user *) io.buffer, + request.buffer, io.data_size)) { + ec_foe_request_clear(&request); return -EFAULT; } - retval = 0; - } - - if (__copy_to_user((void __user *) arg, &data, sizeof(data))) { - retval = -EFAULT; - } - - EC_SLAVE_DBG(request.slave, 1, "Finished FoE read request.\n"); - - ec_foe_request_clear(&request.req); - - return retval; + ret = 0; + } + + if (__copy_to_user((void __user *) arg, &io, sizeof(io))) { + ret = -EFAULT; + } + + EC_SLAVE_DBG(slave, 1, "Finished FoE read request.\n"); + + ec_foe_request_clear(&request); + + return ret; } /*****************************************************************************/ @@ -3662,84 +3668,86 @@ void *arg /**< ioctl() argument. */ ) { - ec_ioctl_slave_foe_t data; - ec_master_foe_request_t request; - int retval; - - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { - return -EFAULT; - } - - INIT_LIST_HEAD(&request.list); - - ec_foe_request_init(&request.req, data.file_name); - - if (ec_foe_request_alloc(&request.req, data.buffer_size)) { - ec_foe_request_clear(&request.req); - return -ENOMEM; - } - if (copy_from_user(request.req.buffer, - (void __user *) data.buffer, data.buffer_size)) { - ec_foe_request_clear(&request.req); - return -EFAULT; - } - request.req.data_size = data.buffer_size; - ec_foe_request_write(&request.req); + ec_ioctl_slave_foe_t io; + ec_foe_request_t request; + ec_slave_t *slave; + int ret; + + if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + return -EFAULT; + } + + ec_foe_request_init(&request, io.file_name); + + ret = ec_foe_request_alloc(&request, io.buffer_size); + if (ret) { + ec_foe_request_clear(&request); + return ret; + } + + if (copy_from_user(request.buffer, + (void __user *) io.buffer, io.buffer_size)) { + ec_foe_request_clear(&request); + return -EFAULT; + } + + request.data_size = io.buffer_size; + ec_foe_request_write(&request); if (down_interruptible(&master->master_sem)) { - ec_foe_request_clear(&request.req); + ec_foe_request_clear(&request); return -EINTR; } - if (!(request.slave = ec_master_find_slave( - master, 0, data.slave_position))) { + if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) { up(&master->master_sem); EC_MASTER_ERR(master, "Slave %u does not exist!\n", - data.slave_position); - ec_foe_request_clear(&request.req); + io.slave_position); + ec_foe_request_clear(&request); return -EINVAL; } - EC_SLAVE_DBG(request.slave, 1, "Scheduling FoE write request.\n"); + EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n"); // schedule FoE write request. - list_add_tail(&request.list, &request.slave->foe_requests); + list_add_tail(&request.list, &slave->foe_requests); up(&master->master_sem); // wait for processing through FSM - if (wait_event_interruptible(request.slave->foe_queue, - request.req.state != EC_INT_REQUEST_QUEUED)) { + if (wait_event_interruptible(slave->foe_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_foe_request_clear(&request.req); + ec_foe_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->foe_queue, - request.req.state != EC_INT_REQUEST_BUSY); - - data.result = request.req.result; - data.error_code = request.req.error_code; - - retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; - - if (__copy_to_user((void __user *) arg, &data, sizeof(data))) { - retval = -EFAULT; - } - - ec_foe_request_clear(&request.req); - - EC_SLAVE_DBG(request.slave, 1, "Finished FoE write request.\n"); - - return retval; + wait_event(slave->foe_queue, request.state != EC_INT_REQUEST_BUSY); + + io.result = request.result; + io.error_code = request.error_code; + + ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; + + if (__copy_to_user((void __user *) arg, &io, sizeof(io))) { + ret = -EFAULT; + } + + ec_foe_request_clear(&request); + + EC_SLAVE_DBG(slave, 1, "Finished FoE write request.\n"); + + return ret; } /*****************************************************************************/ diff -r 71d38ff288b3 -r e6cc33cac6a2 master/slave.c --- a/master/slave.c Tue Dec 04 14:24:01 2012 +0100 +++ b/master/slave.c Tue Dec 04 14:26:30 2012 +0100 @@ -215,13 +215,12 @@ } while (!list_empty(&slave->foe_requests)) { - ec_master_foe_request_t *request = - list_entry(slave->foe_requests.next, - ec_master_foe_request_t, list); + ec_foe_request_t *request = + list_entry(slave->foe_requests.next, ec_foe_request_t, list); list_del_init(&request->list); // dequeue EC_SLAVE_WARN(slave, "Discarding FoE request," " slave about to be deleted.\n"); - request->req.state = EC_INT_REQUEST_FAILURE; + request->state = EC_INT_REQUEST_FAILURE; wake_up(&slave->foe_queue); }