339 int ec_fsm_slave_action_process_soe( |
339 int ec_fsm_slave_action_process_soe( |
340 ec_fsm_slave_t *fsm /**< Slave state machine. */ |
340 ec_fsm_slave_t *fsm /**< Slave state machine. */ |
341 ) |
341 ) |
342 { |
342 { |
343 ec_slave_t *slave = fsm->slave; |
343 ec_slave_t *slave = fsm->slave; |
344 ec_master_soe_request_t *req, *next; |
344 ec_master_soe_request_t *request, *next; |
345 |
345 |
346 // search the first request to be processed |
346 // search the first request to be processed |
347 list_for_each_entry_safe(req, next, &slave->soe_requests, list) { |
347 list_for_each_entry_safe(request, next, &slave->soe_requests, list) { |
348 |
348 |
349 list_del_init(&req->list); // dequeue |
349 list_del_init(&request->list); // dequeue |
350 if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { |
350 if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) { |
351 EC_SLAVE_WARN(slave, "Aborting SoE request," |
351 EC_SLAVE_WARN(slave, "Aborting SoE request," |
352 " slave has error flag set.\n"); |
352 " slave has error flag set.\n"); |
353 req->req.state = EC_INT_REQUEST_FAILURE; |
353 request->req.state = EC_INT_REQUEST_FAILURE; |
|
354 kref_put(&request->refcount,ec_master_soe_request_release); |
354 wake_up(&slave->soe_queue); |
355 wake_up(&slave->soe_queue); |
355 fsm->state = ec_fsm_slave_state_idle; |
356 fsm->state = ec_fsm_slave_state_idle; |
356 return 0; |
357 return 0; |
357 } |
358 } |
358 |
359 |
359 if (slave->current_state == EC_SLAVE_STATE_INIT) { |
360 if (slave->current_state == EC_SLAVE_STATE_INIT) { |
360 EC_SLAVE_WARN(slave, "Aborting SoE request, slave is in INIT.\n"); |
361 EC_SLAVE_WARN(slave, "Aborting SoE request, slave is in INIT.\n"); |
361 req->req.state = EC_INT_REQUEST_FAILURE; |
362 request->req.state = EC_INT_REQUEST_FAILURE; |
|
363 kref_put(&request->refcount,ec_master_soe_request_release); |
362 wake_up(&slave->soe_queue); |
364 wake_up(&slave->soe_queue); |
363 fsm->state = ec_fsm_slave_state_idle; |
365 fsm->state = ec_fsm_slave_state_idle; |
364 return 0; |
366 return 0; |
365 } |
367 } |
366 |
368 |
367 req->req.state = EC_INT_REQUEST_BUSY; |
369 request->req.state = EC_INT_REQUEST_BUSY; |
368 |
370 |
369 // Found pending request. Execute it! |
371 // Found pending request. Execute it! |
370 EC_SLAVE_DBG(slave, 1, "Processing SoE request...\n"); |
372 EC_SLAVE_DBG(slave, 1, "Processing SoE request...\n"); |
371 |
373 |
372 // Start SoE transfer |
374 // Start SoE transfer |
373 fsm->soe_request = &req->req; |
375 fsm->soe_request = request; |
374 fsm->state = ec_fsm_slave_state_soe_request; |
376 fsm->state = ec_fsm_slave_state_soe_request; |
375 ec_fsm_soe_transfer(&fsm->fsm_soe, slave, &req->req); |
377 ec_fsm_soe_transfer(&fsm->fsm_soe, slave, &request->req); |
376 ec_fsm_soe_exec(&fsm->fsm_soe); // execute immediately |
378 ec_fsm_soe_exec(&fsm->fsm_soe); // execute immediately |
377 ec_master_queue_request_fsm_datagram(fsm->slave->master, fsm->datagram); |
379 ec_master_queue_request_fsm_datagram(fsm->slave->master, fsm->datagram); |
378 return 1; |
380 return 1; |
379 } |
381 } |
380 return 0; |
382 return 0; |
387 void ec_fsm_slave_state_soe_request( |
389 void ec_fsm_slave_state_soe_request( |
388 ec_fsm_slave_t *fsm /**< Slave state machine. */ |
390 ec_fsm_slave_t *fsm /**< Slave state machine. */ |
389 ) |
391 ) |
390 { |
392 { |
391 ec_slave_t *slave = fsm->slave; |
393 ec_slave_t *slave = fsm->slave; |
392 ec_soe_request_t *request = fsm->soe_request; |
394 ec_master_soe_request_t *request = fsm->soe_request; |
393 |
395 |
394 if (ec_fsm_soe_exec(&fsm->fsm_soe)) { |
396 if (ec_fsm_soe_exec(&fsm->fsm_soe)) { |
395 ec_master_queue_request_fsm_datagram(fsm->slave->master, fsm->datagram); |
397 ec_master_queue_request_fsm_datagram(fsm->slave->master, fsm->datagram); |
396 return; |
398 return; |
397 } |
399 } |
398 |
400 |
399 if (!ec_fsm_soe_success(&fsm->fsm_soe)) { |
401 if (!ec_fsm_soe_success(&fsm->fsm_soe)) { |
400 EC_SLAVE_ERR(slave, "Failed to process SoE request.\n"); |
402 EC_SLAVE_ERR(slave, "Failed to process SoE request.\n"); |
401 request->state = EC_INT_REQUEST_FAILURE; |
403 request->req.state = EC_INT_REQUEST_FAILURE; |
|
404 kref_put(&request->refcount,ec_master_soe_request_release); |
402 wake_up(&slave->soe_queue); |
405 wake_up(&slave->soe_queue); |
403 fsm->soe_request = NULL; |
406 fsm->soe_request = NULL; |
404 fsm->state = ec_fsm_slave_state_idle; |
407 fsm->state = ec_fsm_slave_state_idle; |
405 return; |
408 return; |
406 } |
409 } |
407 |
410 |
408 EC_SLAVE_DBG(slave, 1, "Finished SoE request.\n"); |
411 EC_SLAVE_DBG(slave, 1, "Finished SoE request.\n"); |
409 |
412 |
410 // SoE request finished |
413 // SoE request finished |
411 request->state = EC_INT_REQUEST_SUCCESS; |
414 request->req.state = EC_INT_REQUEST_SUCCESS; |
|
415 kref_put(&request->refcount,ec_master_soe_request_release); |
412 wake_up(&slave->soe_queue); |
416 wake_up(&slave->soe_queue); |
413 |
417 |
414 fsm->soe_request = NULL; |
418 fsm->soe_request = NULL; |
415 fsm->state = ec_fsm_slave_state_ready; |
419 fsm->state = ec_fsm_slave_state_ready; |
416 } |
420 } |