master/fsm_master.c
changeset 1388 3c886ec376f5
parent 1386 95ec1e9bcb53
child 1400 3c4923051e43
equal deleted inserted replaced
1387:57020c731092 1388:3c886ec376f5
    54 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *);
    54 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *);
    55 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
    55 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *);
    56 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
    56 void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
    57 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
    57 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
    58 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
    58 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
    59 void ec_fsm_master_state_phy_request(ec_fsm_master_t *);
    59 void ec_fsm_master_state_reg_request(ec_fsm_master_t *);
    60 void ec_fsm_master_state_foe_request(ec_fsm_master_t *);
    60 void ec_fsm_master_state_foe_request(ec_fsm_master_t *);
    61 
    61 
    62 /*****************************************************************************/
    62 /*****************************************************************************/
    63 
    63 
    64 /** Constructor.
    64 /** Constructor.
   325     return 0;
   325     return 0;
   326 }
   326 }
   327 
   327 
   328 /*****************************************************************************/
   328 /*****************************************************************************/
   329 
   329 
   330 /** Check for pending phy requests and process one.
   330 /** Check for pending register requests and process one.
   331  * 
   331  * 
   332  * \return non-zero, if a phy request is processed.
   332  * \return non-zero, if a register request is processed.
   333  */
   333  */
   334 int ec_fsm_master_action_process_phy(
   334 int ec_fsm_master_action_process_register(
   335         ec_fsm_master_t *fsm /**< Master state machine. */
   335         ec_fsm_master_t *fsm /**< Master state machine. */
   336         )
   336         )
   337 {
   337 {
   338     ec_master_t *master = fsm->master;
   338     ec_master_t *master = fsm->master;
   339     ec_phy_request_t *request;
   339     ec_reg_request_t *request;
   340 
   340 
   341     // search the first request to be processed
   341     // search the first request to be processed
   342     while (!list_empty(&master->phy_requests)) {
   342     while (!list_empty(&master->reg_requests)) {
   343 
   343 
   344         // get first request
   344         // get first request
   345         request = list_entry(master->phy_requests.next,
   345         request = list_entry(master->reg_requests.next,
   346                 ec_phy_request_t, list);
   346                 ec_reg_request_t, list);
   347         list_del_init(&request->list); // dequeue
   347         list_del_init(&request->list); // dequeue
   348         request->state = EC_INT_REQUEST_BUSY;
   348         request->state = EC_INT_REQUEST_BUSY;
   349 
   349 
   350         // found pending request; process it!
   350         // found pending request; process it!
   351         if (master->debug_level)
   351         if (master->debug_level)
   352             EC_DBG("Processing phy request for slave %u, "
   352             EC_DBG("Processing register request for slave %u, "
   353                     "offset 0x%04x, length %u...\n",
   353                     "offset 0x%04x, length %u...\n",
   354                     request->slave->ring_position,
   354                     request->slave->ring_position,
   355                     request->offset, request->length);
   355                     request->offset, request->length);
   356 
   356 
   357         if (request->length > fsm->datagram->mem_size) {
   357         if (request->length > fsm->datagram->mem_size) {
   358             EC_ERR("Request length (%u) exceeds maximum "
   358             EC_ERR("Request length (%u) exceeds maximum "
   359                     "datagram size (%u)!\n", request->length,
   359                     "datagram size (%u)!\n", request->length,
   360                     fsm->datagram->mem_size);
   360                     fsm->datagram->mem_size);
   361             request->state = EC_INT_REQUEST_FAILURE;
   361             request->state = EC_INT_REQUEST_FAILURE;
   362             wake_up(&master->phy_queue);
   362             wake_up(&master->reg_queue);
   363             continue;
   363             continue;
   364         }
   364         }
   365 
   365 
   366         fsm->phy_request = request;
   366         fsm->reg_request = request;
   367 
   367 
   368         if (request->dir == EC_DIR_INPUT) {
   368         if (request->dir == EC_DIR_INPUT) {
   369             ec_datagram_fprd(fsm->datagram, request->slave->station_address,
   369             ec_datagram_fprd(fsm->datagram, request->slave->station_address,
   370                     request->offset, request->length);
   370                     request->offset, request->length);
   371             ec_datagram_zero(fsm->datagram);
   371             ec_datagram_zero(fsm->datagram);
   373             ec_datagram_fpwr(fsm->datagram, request->slave->station_address,
   373             ec_datagram_fpwr(fsm->datagram, request->slave->station_address,
   374                     request->offset, request->length);
   374                     request->offset, request->length);
   375             memcpy(fsm->datagram->data, request->data, request->length);
   375             memcpy(fsm->datagram->data, request->data, request->length);
   376         }
   376         }
   377         fsm->retries = EC_FSM_RETRIES;
   377         fsm->retries = EC_FSM_RETRIES;
   378         fsm->state = ec_fsm_master_state_phy_request;
   378         fsm->state = ec_fsm_master_state_reg_request;
   379         return 1;
   379         return 1;
   380     }
   380     }
   381 
   381 
   382     return 0;
   382     return 0;
   383 }
   383 }
   566 
   566 
   567     // check for pending SII write operations.
   567     // check for pending SII write operations.
   568     if (ec_fsm_master_action_process_sii(fsm))
   568     if (ec_fsm_master_action_process_sii(fsm))
   569         return; // SII write request found
   569         return; // SII write request found
   570 
   570 
   571     // check for pending phy requests.
   571     // check for pending register requests.
   572     if (ec_fsm_master_action_process_phy(fsm))
   572     if (ec_fsm_master_action_process_register(fsm))
   573         return; // phy request processing
   573         return; // register request processing
   574 
   574 
   575     ec_fsm_master_restart(fsm);
   575     ec_fsm_master_restart(fsm);
   576 }
   576 }
   577 
   577 
   578 /*****************************************************************************/
   578 /*****************************************************************************/
  1012     ec_fsm_master_restart(fsm);
  1012     ec_fsm_master_restart(fsm);
  1013 }
  1013 }
  1014 
  1014 
  1015 /*****************************************************************************/
  1015 /*****************************************************************************/
  1016 
  1016 
  1017 /** Master state: PHY.
  1017 /** Master state: REG REQUEST.
  1018  */
  1018  */
  1019 void ec_fsm_master_state_phy_request(
  1019 void ec_fsm_master_state_reg_request(
  1020         ec_fsm_master_t *fsm /**< Master state machine. */
  1020         ec_fsm_master_t *fsm /**< Master state machine. */
  1021         )
  1021         )
  1022 {
  1022 {
  1023     ec_master_t *master = fsm->master;
  1023     ec_master_t *master = fsm->master;
  1024     ec_datagram_t *datagram = fsm->datagram;
  1024     ec_datagram_t *datagram = fsm->datagram;
  1025     ec_phy_request_t *request = fsm->phy_request;
  1025     ec_reg_request_t *request = fsm->reg_request;
  1026 
  1026 
  1027     if (datagram->state != EC_DATAGRAM_RECEIVED) {
  1027     if (datagram->state != EC_DATAGRAM_RECEIVED) {
  1028         EC_ERR("Failed to receive phy request datagram (state %u).\n",
  1028         EC_ERR("Failed to receive register request datagram (state %u).\n",
  1029                 datagram->state);
  1029                 datagram->state);
  1030         request->state = EC_INT_REQUEST_FAILURE;
  1030         request->state = EC_INT_REQUEST_FAILURE;
  1031         wake_up(&master->phy_queue);
  1031         wake_up(&master->reg_queue);
  1032         ec_fsm_master_restart(fsm);
  1032         ec_fsm_master_restart(fsm);
  1033         return;
  1033         return;
  1034     }
  1034     }
  1035     
  1035     
  1036     if (datagram->working_counter == 1) {
  1036     if (datagram->working_counter == 1) {
  1037         if (request->dir == EC_DIR_INPUT) { // read request
  1037         if (request->dir == EC_DIR_INPUT) { // read request
  1038             if (request->data)
  1038             if (request->data)
  1039                 kfree(request->data);
  1039                 kfree(request->data);
  1040             request->data = kmalloc(request->length, GFP_KERNEL);
  1040             request->data = kmalloc(request->length, GFP_KERNEL);
  1041             if (!request->data) {
  1041             if (!request->data) {
  1042                 EC_ERR("Failed to allocate %u bytes of memory for phy request.\n",
  1042                 EC_ERR("Failed to allocate %u bytes of memory for"
  1043                         request->length);
  1043                         " register data.\n", request->length);
  1044                 request->state = EC_INT_REQUEST_FAILURE;
  1044                 request->state = EC_INT_REQUEST_FAILURE;
  1045                 wake_up(&master->phy_queue);
  1045                 wake_up(&master->reg_queue);
  1046                 ec_fsm_master_restart(fsm);
  1046                 ec_fsm_master_restart(fsm);
  1047                 return;
  1047                 return;
  1048             }
  1048             }
  1049             memcpy(request->data, datagram->data, request->length);
  1049             memcpy(request->data, datagram->data, request->length);
  1050         }
  1050         }
  1052         request->state = EC_INT_REQUEST_SUCCESS;
  1052         request->state = EC_INT_REQUEST_SUCCESS;
  1053     } else {
  1053     } else {
  1054         request->state = EC_INT_REQUEST_FAILURE;
  1054         request->state = EC_INT_REQUEST_FAILURE;
  1055     }
  1055     }
  1056 
  1056 
  1057     wake_up(&master->phy_queue);
  1057     wake_up(&master->reg_queue);
  1058 
  1058 
  1059     // check for another PHY request
  1059     // check for another register request
  1060     if (ec_fsm_master_action_process_phy(fsm))
  1060     if (ec_fsm_master_action_process_register(fsm))
  1061         return; // processing another request
  1061         return; // processing another request
  1062 
  1062 
  1063     ec_fsm_master_restart(fsm);
  1063     ec_fsm_master_restart(fsm);
  1064 }
  1064 }
  1065 
  1065