Using common waitqueue for requests.

This commit is contained in:
Florian Pose 2012-12-04 16:05:23 +01:00
parent cf614f6e79
commit 5f73e9c046
7 changed files with 135 additions and 162 deletions

View File

@ -1136,7 +1136,7 @@ void ec_fsm_master_state_write_sii(
if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
EC_SLAVE_ERR(slave, "Failed to write SII data.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&master->sii_queue);
wake_up(&master->request_queue);
ec_fsm_master_restart(fsm);
return;
}
@ -1164,7 +1164,7 @@ void ec_fsm_master_state_write_sii(
// TODO: Evaluate other SII contents!
request->state = EC_INT_REQUEST_SUCCESS;
wake_up(&master->sii_queue);
wake_up(&master->request_queue);
// check for another SII write request
if (ec_fsm_master_action_process_sii(fsm))
@ -1232,14 +1232,14 @@ void ec_fsm_master_state_sdo_request(
EC_SLAVE_DBG(fsm->slave, 1,
"Failed to process internal SDO request.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&fsm->slave->sdo_queue);
wake_up(&fsm->master->request_queue);
ec_fsm_master_restart(fsm);
return;
}
// SDO request finished
request->state = EC_INT_REQUEST_SUCCESS;
wake_up(&fsm->slave->sdo_queue);
wake_up(&fsm->master->request_queue);
EC_SLAVE_DBG(fsm->slave, 1, "Finished internal SDO request.\n");

View File

@ -180,45 +180,45 @@ int ec_fsm_slave_action_process_sdo(
)
{
ec_slave_t *slave = fsm->slave;
ec_sdo_request_t *request, *next;
ec_sdo_request_t *request;
// search the first external request to be processed
list_for_each_entry_safe(request, next, &slave->sdo_requests, list) {
if (list_empty(&slave->sdo_requests)) {
return 0;
}
list_del_init(&request->list); // dequeue
if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
EC_SLAVE_WARN(slave, "Aborting SDO request,"
" slave has error flag set.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->sdo_queue);
fsm->sdo_request = NULL;
fsm->state = ec_fsm_slave_state_idle;
return 0;
}
// take the first request to be processed
request = list_entry(slave->sdo_requests.next, ec_sdo_request_t, list);
list_del_init(&request->list); // dequeue
if (slave->current_state == EC_SLAVE_STATE_INIT) {
EC_SLAVE_WARN(slave, "Aborting SDO request, slave is in INIT.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->sdo_queue);
fsm->sdo_request = NULL;
fsm->state = ec_fsm_slave_state_idle;
return 0;
}
request->state = EC_INT_REQUEST_BUSY;
// Found pending SDO request. Execute it!
EC_SLAVE_DBG(slave, 1, "Processing SDO request...\n");
// Start SDO transfer
fsm->sdo_request = request;
fsm->state = ec_fsm_slave_state_sdo_request;
ec_fsm_coe_transfer(&fsm->fsm_coe, slave, request);
ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
ec_master_queue_external_datagram(fsm->slave->master, fsm->datagram);
if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
EC_SLAVE_WARN(slave, "Aborting SDO request,"
" slave has error flag set.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->master->request_queue);
fsm->state = ec_fsm_slave_state_idle;
return 1;
}
return 0;
if (slave->current_state == EC_SLAVE_STATE_INIT) {
EC_SLAVE_WARN(slave, "Aborting SDO request, slave is in INIT.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->master->request_queue);
fsm->state = ec_fsm_slave_state_idle;
return 1;
}
request->state = EC_INT_REQUEST_BUSY;
// Found pending SDO request. Execute it!
EC_SLAVE_DBG(slave, 1, "Processing SDO request...\n");
// Start SDO transfer
fsm->sdo_request = request;
fsm->state = ec_fsm_slave_state_sdo_request;
ec_fsm_coe_transfer(&fsm->fsm_coe, slave, request);
ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
ec_master_queue_external_datagram(fsm->slave->master, fsm->datagram);
return 1;
}
/*****************************************************************************/
@ -240,7 +240,7 @@ void ec_fsm_slave_state_sdo_request(
if (!ec_fsm_coe_success(&fsm->fsm_coe)) {
EC_SLAVE_ERR(slave, "Failed to process SDO request.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->sdo_queue);
wake_up(&slave->master->request_queue);
fsm->sdo_request = NULL;
fsm->state = ec_fsm_slave_state_ready;
return;
@ -250,8 +250,7 @@ void ec_fsm_slave_state_sdo_request(
// SDO request finished
request->state = EC_INT_REQUEST_SUCCESS;
wake_up(&slave->sdo_queue);
wake_up(&slave->master->request_queue);
fsm->sdo_request = NULL;
fsm->state = ec_fsm_slave_state_ready;
}
@ -296,7 +295,8 @@ int ec_fsm_slave_action_process_reg(
EC_SLAVE_WARN(slave, "Aborting register request,"
" slave has error flag set.\n");
fsm->reg_request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->reg_queue);
wake_up(&slave->master->request_queue);
fsm->reg_request = NULL;
fsm->state = ec_fsm_slave_state_idle;
return 1;
}
@ -345,7 +345,8 @@ void ec_fsm_slave_state_reg_request(
" request datagram: ");
ec_datagram_print_state(fsm->datagram);
reg->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->reg_queue);
wake_up(&slave->master->request_queue);
fsm->reg_request = NULL;
fsm->state = ec_fsm_slave_state_ready;
return;
}
@ -365,7 +366,8 @@ void ec_fsm_slave_state_reg_request(
fsm->datagram->working_counter);
}
wake_up(&slave->reg_queue);
wake_up(&slave->master->request_queue);
fsm->reg_request = NULL;
fsm->state = ec_fsm_slave_state_ready;
}
@ -394,8 +396,9 @@ int ec_fsm_slave_action_process_foe(
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;
wake_up(&slave->master->request_queue);
fsm->state = ec_fsm_slave_state_idle;
return 1;
}
request->state = EC_INT_REQUEST_BUSY;
@ -429,7 +432,7 @@ void ec_fsm_slave_state_foe_request(
if (!ec_fsm_foe_success(&fsm->fsm_foe)) {
EC_SLAVE_ERR(slave, "Failed to handle FoE request.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->foe_queue);
wake_up(&slave->master->request_queue);
fsm->foe_request = NULL;
fsm->state = ec_fsm_slave_state_ready;
return;
@ -440,8 +443,7 @@ void ec_fsm_slave_state_foe_request(
" data.\n", request->data_size);
request->state = EC_INT_REQUEST_SUCCESS;
wake_up(&slave->foe_queue);
wake_up(&slave->master->request_queue);
fsm->foe_request = NULL;
fsm->state = ec_fsm_slave_state_ready;
}
@ -471,14 +473,16 @@ int ec_fsm_slave_action_process_soe(
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;
wake_up(&slave->master->request_queue);
fsm->state = ec_fsm_slave_state_idle;
return 1;
}
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);
wake_up(&slave->master->request_queue);
fsm->state = ec_fsm_slave_state_idle;
return 0;
}
@ -515,7 +519,7 @@ void ec_fsm_slave_state_soe_request(
if (!ec_fsm_soe_success(&fsm->fsm_soe)) {
EC_SLAVE_ERR(slave, "Failed to process SoE request.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->soe_queue);
wake_up(&slave->master->request_queue);
fsm->soe_request = NULL;
fsm->state = ec_fsm_slave_state_ready;
return;
@ -525,8 +529,7 @@ void ec_fsm_slave_state_soe_request(
// SoE request finished
request->state = EC_INT_REQUEST_SUCCESS;
wake_up(&slave->soe_queue);
wake_up(&slave->master->request_queue);
fsm->soe_request = NULL;
fsm->state = ec_fsm_slave_state_ready;
}

View File

@ -911,8 +911,9 @@ static int ec_ioctl_slave_sii_write(
return -EFAULT;
}
if (!data.nwords)
if (!data.nwords) {
return 0;
}
byte_size = sizeof(uint16_t) * data.nwords;
if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
@ -927,8 +928,10 @@ static int ec_ioctl_slave_sii_write(
return -EFAULT;
}
if (down_interruptible(&master->master_sem))
if (down_interruptible(&master->master_sem)) {
kfree(words);
return -EINTR;
}
if (!(slave = ec_master_find_slave(
master, 0, data.slave_position))) {
@ -953,7 +956,7 @@ static int ec_ioctl_slave_sii_write(
up(&master->master_sem);
// wait for processing through FSM
if (wait_event_interruptible(master->sii_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -968,7 +971,7 @@ static int ec_ioctl_slave_sii_write(
}
// wait until master FSM has finished processing
wait_event(master->sii_queue, request.state != EC_INT_REQUEST_BUSY);
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
kfree(words);
@ -1025,7 +1028,7 @@ static int ec_ioctl_slave_reg_read(
up(&master->master_sem);
// wait for processing through FSM
if (wait_event_interruptible(slave->reg_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -1040,7 +1043,7 @@ static int ec_ioctl_slave_reg_read(
}
// wait until master FSM has finished processing
wait_event(slave->reg_queue, request.state != EC_INT_REQUEST_BUSY);
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
if (request.state == EC_INT_REQUEST_SUCCESS) {
if (copy_to_user((void __user *) io.data, request.data, io.size)) {
@ -1092,8 +1095,7 @@ static int ec_ioctl_slave_reg_write(
return -EINTR;
}
if (!(slave = ec_master_find_slave(
master, 0, io.slave_position))) {
if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
up(&master->master_sem);
ec_reg_request_clear(&request);
EC_MASTER_ERR(master, "Slave %u does not exist!\n",
@ -1107,7 +1109,7 @@ static int ec_ioctl_slave_reg_write(
up(&master->master_sem);
// wait for processing through FSM
if (wait_event_interruptible(slave->reg_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -1122,7 +1124,7 @@ static int ec_ioctl_slave_reg_write(
}
// wait until master FSM has finished processing
wait_event(slave->reg_queue, request.state != EC_INT_REQUEST_BUSY);
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
ec_reg_request_clear(&request);
@ -3597,15 +3599,15 @@ static int ec_ioctl_slave_foe_read(
return -EINVAL;
}
EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
// schedule request.
list_add_tail(&request.list, &slave->foe_requests);
up(&master->master_sem);
EC_SLAVE_DBG(slave, 1, "Scheduled FoE read request.\n");
// wait for processing through FSM
if (wait_event_interruptible(slave->foe_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -3619,17 +3621,12 @@ static int ec_ioctl_slave_foe_read(
up(&master->master_sem);
}
// FIXME slave may become invalid
// wait until master FSM has finished processing
wait_event(slave->foe_queue, request.state != EC_INT_REQUEST_BUSY);
wait_event(master->request_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;
@ -3652,10 +3649,7 @@ static int ec_ioctl_slave_foe_read(
ret = -EFAULT;
}
EC_SLAVE_DBG(slave, 1, "Finished FoE read request.\n");
ec_foe_request_clear(&request);
return ret;
}
@ -3715,7 +3709,7 @@ static int ec_ioctl_slave_foe_write(
up(&master->master_sem);
// wait for processing through FSM
if (wait_event_interruptible(slave->foe_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -3729,10 +3723,8 @@ static int ec_ioctl_slave_foe_write(
up(&master->master_sem);
}
// FIXME slave may become invalid
// wait until master FSM has finished processing
wait_event(slave->foe_queue, request.state != EC_INT_REQUEST_BUSY);
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
io.result = request.result;
io.error_code = request.error_code;
@ -3744,9 +3736,6 @@ static int ec_ioctl_slave_foe_write(
}
ec_foe_request_clear(&request);
EC_SLAVE_DBG(slave, 1, "Finished FoE write request.\n");
return ret;
}

View File

@ -220,7 +220,8 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
master->app_cb_data = NULL;
INIT_LIST_HEAD(&master->sii_requests);
init_waitqueue_head(&master->sii_queue);
init_waitqueue_head(&master->request_queue);
// init devices
for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
@ -434,8 +435,8 @@ void ec_master_clear_slaves(ec_master_t *master)
master->dc_ref_clock = NULL;
// external requests are obsolete, so we wake pending waiters and remove
// them from the list
// External requests are obsolete, so we wake pending waiters and remove
// them from the list.
while (!list_empty(&master->sii_requests)) {
ec_sii_write_request_t *request =
@ -445,7 +446,7 @@ void ec_master_clear_slaves(ec_master_t *master)
EC_MASTER_WARN(master, "Discarding SII request, slave %u about"
" to be deleted.\n", request->slave->ring_position);
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&master->sii_queue);
wake_up(&master->request_queue);
}
for (slave = master->slaves;
@ -2667,6 +2668,7 @@ int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
{
ec_sdo_request_t request;
ec_slave_t *slave;
int ret;
EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
" slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
@ -2681,9 +2683,10 @@ int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
ec_sdo_request_init(&request);
ecrt_sdo_request_index(&request, index, subindex);
if (ec_sdo_request_alloc(&request, data_size)) {
ret = ec_sdo_request_alloc(&request, data_size);
if (ret) {
ec_sdo_request_clear(&request);
return -ENOMEM;
return ret;
}
memcpy(request.data, data, data_size);
@ -2702,7 +2705,7 @@ int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
return -EINVAL;
}
EC_SLAVE_DBG(slave, 1, "Schedule SDO download request.\n");
EC_SLAVE_DBG(slave, 1, "Scheduling SDO download request.\n");
// schedule request.
list_add_tail(&request.list, &slave->sdo_requests);
@ -2710,7 +2713,7 @@ int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
up(&master->master_sem);
// wait for processing through FSM
if (wait_event_interruptible(slave->sdo_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -2724,22 +2727,21 @@ int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
up(&master->master_sem);
}
// FIXME slave may become invalid!
// wait until master FSM has finished processing
wait_event(slave->sdo_queue, request.state != EC_INT_REQUEST_BUSY);
EC_SLAVE_DBG(slave, 1, "Finished SDO download request.\n");
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
*abort_code = request.abort_code;
if (request.state == EC_INT_REQUEST_SUCCESS) {
return 0;
ret = 0;
} else if (request.errno) {
return -request.errno;
ret = -request.errno;
} else {
return -EIO;
ret = -EIO;
}
ec_sdo_request_clear(&request);
return ret;
}
/*****************************************************************************/
@ -2750,6 +2752,7 @@ int ecrt_master_sdo_download_complete(ec_master_t *master,
{
ec_sdo_request_t request;
ec_slave_t *slave;
int ret;
EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
" slave_position = %u, index = 0x%04X,"
@ -2764,9 +2767,10 @@ int ecrt_master_sdo_download_complete(ec_master_t *master,
ec_sdo_request_init(&request);
ecrt_sdo_request_index(&request, index, 0);
if (ec_sdo_request_alloc(&request, data_size)) {
ret = ec_sdo_request_alloc(&request, data_size);
if (ret) {
ec_sdo_request_clear(&request);
return -ENOMEM;
return ret;
}
request.complete_access = 1;
@ -2786,7 +2790,7 @@ int ecrt_master_sdo_download_complete(ec_master_t *master,
return -EINVAL;
}
EC_SLAVE_DBG(slave, 1, "Schedule SDO download request"
EC_SLAVE_DBG(slave, 1, "Scheduling SDO download request"
" (complete access).\n");
// schedule request.
@ -2795,7 +2799,7 @@ int ecrt_master_sdo_download_complete(ec_master_t *master,
up(&master->master_sem);
// wait for processing through FSM
if (wait_event_interruptible(slave->sdo_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -2809,23 +2813,21 @@ int ecrt_master_sdo_download_complete(ec_master_t *master,
up(&master->master_sem);
}
// FIXME slave may become invalid!
// wait until master FSM has finished processing
wait_event(slave->sdo_queue, request.state != EC_INT_REQUEST_BUSY);
EC_SLAVE_DBG(slave, 1, "Finished SDO download request"
" (complete access).\n");
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
*abort_code = request.abort_code;
if (request.state == EC_INT_REQUEST_SUCCESS) {
return 0;
ret = 0;
} else if (request.errno) {
return -request.errno;
ret = -request.errno;
} else {
return -EIO;
ret = -EIO;
}
ec_sdo_request_clear(&request);
return ret;
}
/*****************************************************************************/
@ -2836,7 +2838,7 @@ int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
{
ec_sdo_request_t request;
ec_slave_t *slave;
int retval = 0;
int ret = 0;
EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
" slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
@ -2861,7 +2863,7 @@ int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
return -EINVAL;
}
EC_SLAVE_DBG(slave, 1, "Schedule SDO upload request.\n");
EC_SLAVE_DBG(slave, 1, "Scheduling SDO upload request.\n");
// schedule request.
list_add_tail(&request.list, &slave->sdo_requests);
@ -2869,7 +2871,7 @@ int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
up(&master->master_sem);
// wait for processing through FSM
if (wait_event_interruptible(slave->sdo_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -2883,34 +2885,32 @@ int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
up(&master->master_sem);
}
// FIXME slave may become invalid!
// wait until master FSM has finished processing
wait_event(slave->sdo_queue, request.state != EC_INT_REQUEST_BUSY);
EC_SLAVE_DBG(slave, 1, "Finished SDO upload request.\n");
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
*abort_code = request.abort_code;
if (request.state != EC_INT_REQUEST_SUCCESS) {
*result_size = 0;
if (request.errno) {
retval = -request.errno;
ret = -request.errno;
} else {
retval = -EIO;
ret = -EIO;
}
} else {
if (request.data_size > target_size) {
EC_MASTER_ERR(master, "Buffer too small.\n");
ec_sdo_request_clear(&request);
return -EOVERFLOW;
ret = -EOVERFLOW;
}
else {
memcpy(target, request.data, request.data_size);
*result_size = request.data_size;
ret = 0;
}
memcpy(target, request.data, request.data_size);
*result_size = request.data_size;
}
ec_sdo_request_clear(&request);
return retval;
return ret;
}
/*****************************************************************************/
@ -2963,7 +2963,7 @@ int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
up(&master->master_sem);
// wait for processing through FSM
if (wait_event_interruptible(slave->soe_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -2977,10 +2977,8 @@ int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
up(&master->master_sem);
}
// FIXME slave may become invalid
// wait until master FSM has finished processing
wait_event(slave->soe_queue, request.state != EC_INT_REQUEST_BUSY);
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
if (error_code) {
*error_code = request.error_code;
@ -3023,15 +3021,15 @@ int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
return -EINVAL;
}
EC_SLAVE_DBG(slave, 1, "Scheduling SoE read request.\n");
// schedule request.
list_add_tail(&request.list, &slave->soe_requests);
up(&master->master_sem);
EC_SLAVE_DBG(slave, 1, "Scheduled SoE read request.\n");
// wait for processing through FSM
if (wait_event_interruptible(slave->soe_queue,
if (wait_event_interruptible(master->request_queue,
request.state != EC_INT_REQUEST_QUEUED)) {
// interrupted by signal
down(&master->master_sem);
@ -3045,17 +3043,13 @@ int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
up(&master->master_sem);
}
// FIXME slave may become invalid
// wait until master FSM has finished processing
wait_event(slave->soe_queue, request.state != EC_INT_REQUEST_BUSY);
wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
if (error_code) {
*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;

View File

@ -287,8 +287,9 @@ struct ec_master {
void *app_cb_data; /**< Application callback data. */
struct list_head sii_requests; /**< SII write requests. */
wait_queue_head_t sii_queue; /**< Wait queue for SII
write requests from user space. */
wait_queue_head_t request_queue; /**< Wait queue for external requests
from user space. */
};
/*****************************************************************************/

View File

@ -153,16 +153,9 @@ void ec_slave_init(
slave->jiffies_preop = 0;
INIT_LIST_HEAD(&slave->sdo_requests);
init_waitqueue_head(&slave->sdo_queue);
INIT_LIST_HEAD(&slave->reg_requests);
init_waitqueue_head(&slave->reg_queue);
INIT_LIST_HEAD(&slave->foe_requests);
init_waitqueue_head(&slave->foe_queue);
INIT_LIST_HEAD(&slave->soe_requests);
init_waitqueue_head(&slave->soe_queue);
// init state machine datagram
ec_datagram_init(&slave->fsm_datagram);
@ -201,7 +194,7 @@ void ec_slave_clear(ec_slave_t *slave /**< EtherCAT slave */)
EC_SLAVE_WARN(slave, "Discarding SDO request,"
" slave about to be deleted.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->sdo_queue);
wake_up(&slave->master->request_queue);
}
while (!list_empty(&slave->reg_requests)) {
@ -211,7 +204,7 @@ void ec_slave_clear(ec_slave_t *slave /**< EtherCAT slave */)
EC_SLAVE_WARN(slave, "Discarding register request,"
" slave about to be deleted.\n");
reg->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->reg_queue);
wake_up(&slave->master->request_queue);
}
while (!list_empty(&slave->foe_requests)) {
@ -221,7 +214,7 @@ void ec_slave_clear(ec_slave_t *slave /**< EtherCAT slave */)
EC_SLAVE_WARN(slave, "Discarding FoE request,"
" slave about to be deleted.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->foe_queue);
wake_up(&slave->master->request_queue);
}
while (!list_empty(&slave->soe_requests)) {
@ -231,7 +224,7 @@ void ec_slave_clear(ec_slave_t *slave /**< EtherCAT slave */)
EC_SLAVE_WARN(slave, "Discarding SoE request,"
" slave about to be deleted.\n");
request->state = EC_INT_REQUEST_FAILURE;
wake_up(&slave->soe_queue);
wake_up(&slave->master->request_queue);
}
if (slave->config) {

View File

@ -225,17 +225,10 @@ struct ec_slave
unsigned long jiffies_preop; /**< Time, the slave went to PREOP. */
struct list_head sdo_requests; /**< SDO access requests. */
wait_queue_head_t sdo_queue; /**< Wait queue for SDO access requests
from user space. */
struct list_head reg_requests; /**< Register access requests. */
wait_queue_head_t reg_queue; /**< Wait queue for register access requests
from user space. */
struct list_head foe_requests; /**< FoE write requests. */
wait_queue_head_t foe_queue; /**< Wait queue for FoE requests from user
space. */
struct list_head soe_requests; /**< FoE write requests. */
wait_queue_head_t soe_queue; /**< Wait queue for SoE requests from user
space. */
struct list_head soe_requests; /**< SoE write requests. */
ec_fsm_slave_t fsm; /**< Slave state machine. */
ec_datagram_t fsm_datagram; /**< Datagram used for state machines. */
};