master/voe_handler.c
changeset 2046 4cf0161c445a
parent 2045 ff2a13a4603c
child 2589 2b9c78543663
equal deleted inserted replaced
2042:8b358effa78b 2046:4cf0161c445a
    86     voe->dir = EC_DIR_INVALID;
    86     voe->dir = EC_DIR_INVALID;
    87     voe->state = ec_voe_handler_state_error;
    87     voe->state = ec_voe_handler_state_error;
    88     voe->request_state = EC_INT_REQUEST_INIT;
    88     voe->request_state = EC_INT_REQUEST_INIT;
    89 
    89 
    90     ec_datagram_init(&voe->datagram);
    90     ec_datagram_init(&voe->datagram);
       
    91     ec_mbox_init(&voe->mbox,&voe->datagram);
    91     return ec_datagram_prealloc(&voe->datagram,
    92     return ec_datagram_prealloc(&voe->datagram,
    92             size + EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE);
    93             size + EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE);
    93 }
    94 }
    94 
    95 
    95 /*****************************************************************************/
    96 /*****************************************************************************/
    98  */
    99  */
    99 void ec_voe_handler_clear(
   100 void ec_voe_handler_clear(
   100         ec_voe_handler_t *voe /**< VoE handler. */
   101         ec_voe_handler_t *voe /**< VoE handler. */
   101         )
   102         )
   102 {
   103 {
       
   104     ec_mbox_clear(&voe->mbox);
   103     ec_datagram_clear(&voe->datagram);
   105     ec_datagram_clear(&voe->datagram);
   104 }
   106 }
   105 
   107 
   106 /*****************************************************************************/
   108 /*****************************************************************************/
   107 
   109 
   189 ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
   191 ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
   190 {
   192 {
   191     if (voe->config->slave) { // FIXME locking?
   193     if (voe->config->slave) { // FIXME locking?
   192         voe->state(voe);
   194         voe->state(voe);
   193         if (voe->request_state == EC_INT_REQUEST_BUSY)
   195         if (voe->request_state == EC_INT_REQUEST_BUSY)
   194             ec_master_queue_datagram(voe->config->master, &voe->datagram);
   196             ec_slave_mbox_queue_datagrams(voe->config->slave,&voe->mbox);
   195     } else {
   197     } else {
   196         voe->state = ec_voe_handler_state_error;
   198         voe->state = ec_voe_handler_state_error;
   197         voe->request_state = EC_INT_REQUEST_FAILURE;
   199         voe->request_state = EC_INT_REQUEST_FAILURE;
   198     }
   200     }
   199 
   201 
   222         voe->state = ec_voe_handler_state_error;
   224         voe->state = ec_voe_handler_state_error;
   223         voe->request_state = EC_INT_REQUEST_FAILURE;
   225         voe->request_state = EC_INT_REQUEST_FAILURE;
   224         return;
   226         return;
   225     }
   227     }
   226 
   228 
   227     data = ec_slave_mbox_prepare_send(slave, &voe->datagram,
   229     data = ec_slave_mbox_prepare_send(slave, &voe->mbox,
   228             EC_MBOX_TYPE_VOE, EC_VOE_HEADER_SIZE + voe->data_size);
   230             EC_MBOX_TYPE_VOE, EC_VOE_HEADER_SIZE + voe->data_size);
   229     if (IS_ERR(data)) {
   231     if (IS_ERR(data)) {
   230         voe->state = ec_voe_handler_state_error;
   232         voe->state = ec_voe_handler_state_error;
   231         voe->request_state = EC_INT_REQUEST_FAILURE;
   233         voe->request_state = EC_INT_REQUEST_FAILURE;
   232         return;
   234         return;
   245 
   247 
   246 /** Wait for the mailbox response.
   248 /** Wait for the mailbox response.
   247  */
   249  */
   248 void ec_voe_handler_state_write_response(ec_voe_handler_t *voe)
   250 void ec_voe_handler_state_write_response(ec_voe_handler_t *voe)
   249 {
   251 {
   250     ec_datagram_t *datagram = &voe->datagram;
   252     ec_mailbox_t *mbox = &voe->mbox;
   251     ec_slave_t *slave = voe->config->slave;
   253     ec_slave_t *slave = voe->config->slave;
   252 
   254 
   253     if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
   255     if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && voe->retries--)
   254         return;
   256         return;
   255 
   257 
   256     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   258     if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
   257         voe->state = ec_voe_handler_state_error;
   259         voe->state = ec_voe_handler_state_error;
   258         voe->request_state = EC_INT_REQUEST_FAILURE;
   260         voe->request_state = EC_INT_REQUEST_FAILURE;
   259         EC_SLAVE_ERR(slave, "Failed to receive VoE write request datagram: ");
   261         EC_SLAVE_ERR(slave, "Failed to receive VoE write request datagram: ");
   260         ec_datagram_print_state(datagram);
   262         ec_datagram_print_state(mbox->datagram);
   261         return;
   263         return;
   262     }
   264     }
   263 
   265 
   264     if (datagram->working_counter != 1) {
   266     if (!ec_mbox_is_datagram_wc(mbox,1)) {
   265         if (!datagram->working_counter) {
   267         if (ec_mbox_is_datagram_wc(mbox,0)) {
   266             unsigned long diff_ms =
   268             unsigned long diff_ms =
   267                 (jiffies - voe->jiffies_start) * 1000 / HZ;
   269                 (jiffies - voe->jiffies_start) * 1000 / HZ;
   268             if (diff_ms < EC_VOE_RESPONSE_TIMEOUT) {
   270             if (diff_ms < EC_VOE_RESPONSE_TIMEOUT) {
   269                 EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
   271                 EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
   270                         " VoE write request. Retrying after %lu ms...\n",
   272                         " VoE write request. Retrying after %lu ms...\n",
   274             }
   276             }
   275         }
   277         }
   276         voe->state = ec_voe_handler_state_error;
   278         voe->state = ec_voe_handler_state_error;
   277         voe->request_state = EC_INT_REQUEST_FAILURE;
   279         voe->request_state = EC_INT_REQUEST_FAILURE;
   278         EC_SLAVE_ERR(slave, "Reception of VoE write request failed: ");
   280         EC_SLAVE_ERR(slave, "Reception of VoE write request failed: ");
   279         ec_datagram_print_wc_error(datagram);
   281         ec_datagram_print_wc_error(mbox->datagram);
   280         return;
   282         return;
   281     }
   283     }
   282 
   284 
   283     EC_CONFIG_DBG(voe->config, 1, "VoE write request successful.\n");
   285     EC_CONFIG_DBG(voe->config, 1, "VoE write request successful.\n");
   284 
   286 
   290 
   292 
   291 /** Start reading VoE data.
   293 /** Start reading VoE data.
   292  */
   294  */
   293 void ec_voe_handler_state_read_start(ec_voe_handler_t *voe)
   295 void ec_voe_handler_state_read_start(ec_voe_handler_t *voe)
   294 {
   296 {
   295     ec_datagram_t *datagram = &voe->datagram;
   297     ec_mailbox_t *mbox = &voe->mbox;
   296     ec_slave_t *slave = voe->config->slave;
   298     ec_slave_t *slave = voe->config->slave;
   297 
   299 
   298     EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n");
   300     EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n");
   299 
   301 
   300     if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) {
   302     if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) {
   302         voe->state = ec_voe_handler_state_error;
   304         voe->state = ec_voe_handler_state_error;
   303         voe->request_state = EC_INT_REQUEST_FAILURE;
   305         voe->request_state = EC_INT_REQUEST_FAILURE;
   304         return;
   306         return;
   305     }
   307     }
   306 
   308 
   307     ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   309     ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   308 
   310 
   309     voe->jiffies_start = jiffies;
   311     voe->jiffies_start = jiffies;
   310     voe->retries = EC_FSM_RETRIES;
   312     voe->retries = EC_FSM_RETRIES;
   311     voe->state = ec_voe_handler_state_read_check;
   313     voe->state = ec_voe_handler_state_read_check;
   312 }
   314 }
   315 
   317 
   316 /** Check for new data in the mailbox.
   318 /** Check for new data in the mailbox.
   317  */
   319  */
   318 void ec_voe_handler_state_read_check(ec_voe_handler_t *voe)
   320 void ec_voe_handler_state_read_check(ec_voe_handler_t *voe)
   319 {
   321 {
   320     ec_datagram_t *datagram = &voe->datagram;
   322     ec_mailbox_t *mbox = &voe->mbox;
   321     ec_slave_t *slave = voe->config->slave;
   323     ec_slave_t *slave = voe->config->slave;
   322 
   324 
   323     if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
   325     if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && voe->retries--)
   324         return;
   326         return;
   325 
   327 
   326     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   328     if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
   327         voe->state = ec_voe_handler_state_error;
   329         voe->state = ec_voe_handler_state_error;
   328         voe->request_state = EC_INT_REQUEST_FAILURE;
   330         voe->request_state = EC_INT_REQUEST_FAILURE;
   329         EC_SLAVE_ERR(slave, "Failed to receive VoE mailbox check datagram: ");
   331         EC_SLAVE_ERR(slave, "Failed to receive VoE mailbox check datagram: ");
   330         ec_datagram_print_state(datagram);
   332         ec_datagram_print_state(mbox->datagram);
   331         return;
   333         return;
   332     }
   334     }
   333 
   335 
   334     if (datagram->working_counter != 1) {
   336     if (!ec_mbox_is_datagram_wc(mbox,1)) {
   335         voe->state = ec_voe_handler_state_error;
   337         voe->state = ec_voe_handler_state_error;
   336         voe->request_state = EC_INT_REQUEST_FAILURE;
   338         voe->request_state = EC_INT_REQUEST_FAILURE;
   337         EC_SLAVE_ERR(slave, "Reception of VoE mailbox check"
   339         EC_SLAVE_ERR(slave, "Reception of VoE mailbox check"
   338                 " datagram failed: ");
   340                 " datagram failed: ");
   339         ec_datagram_print_wc_error(datagram);
   341         ec_datagram_print_wc_error(mbox->datagram);
   340         return;
   342         return;
   341     }
   343     }
   342 
   344 
   343     if (!ec_slave_mbox_check(datagram)) {
   345     if (!ec_slave_mbox_check(mbox)) {
   344         unsigned long diff_ms =
   346         unsigned long diff_ms =
   345             (datagram->jiffies_received - voe->jiffies_start) * 1000 / HZ;
   347             (mbox->datagram->jiffies_received - voe->jiffies_start) * 1000 / HZ;
   346         if (diff_ms >= EC_VOE_RESPONSE_TIMEOUT) {
   348         if (diff_ms >= EC_VOE_RESPONSE_TIMEOUT) {
   347             voe->state = ec_voe_handler_state_error;
   349             voe->state = ec_voe_handler_state_error;
   348             voe->request_state = EC_INT_REQUEST_FAILURE;
   350             voe->request_state = EC_INT_REQUEST_FAILURE;
   349             EC_SLAVE_ERR(slave, "Timeout while waiting for VoE data.\n");
   351             EC_SLAVE_ERR(slave, "Timeout while waiting for VoE data.\n");
   350             return;
   352             return;
   351         }
   353         }
   352 
   354 
   353         ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
   355         ec_slave_mbox_prepare_check(slave, mbox); // can not fail.
   354         voe->retries = EC_FSM_RETRIES;
   356         voe->retries = EC_FSM_RETRIES;
   355         return;
   357         return;
   356     }
   358     }
   357 
   359 
   358     // Fetch response
   360     // Fetch response
   359     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   361     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
   360     voe->retries = EC_FSM_RETRIES;
   362     voe->retries = EC_FSM_RETRIES;
   361     voe->state = ec_voe_handler_state_read_response;
   363     voe->state = ec_voe_handler_state_read_response;
   362 }
   364 }
   363 
   365 
   364 /*****************************************************************************/
   366 /*****************************************************************************/
   365 
   367 
   366 /** Read the pending mailbox data.
   368 /** Read the pending mailbox data.
   367  */
   369  */
   368 void ec_voe_handler_state_read_response(ec_voe_handler_t *voe)
   370 void ec_voe_handler_state_read_response(ec_voe_handler_t *voe)
   369 {
   371 {
   370     ec_datagram_t *datagram = &voe->datagram;
   372     ec_mailbox_t *mbox = &voe->mbox;
   371     ec_slave_t *slave = voe->config->slave;
   373     ec_slave_t *slave = voe->config->slave;
   372     ec_master_t *master = voe->config->master;
   374     ec_master_t *master = voe->config->master;
   373     uint8_t *data, mbox_prot;
   375     uint8_t *data, mbox_prot;
   374     size_t rec_size;
   376     size_t rec_size;
   375 
   377 
   376     if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
   378     if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && voe->retries--)
   377         return;
   379         return;
   378 
   380 
   379     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   381     if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
   380         voe->state = ec_voe_handler_state_error;
   382         voe->state = ec_voe_handler_state_error;
   381         voe->request_state = EC_INT_REQUEST_FAILURE;
   383         voe->request_state = EC_INT_REQUEST_FAILURE;
   382         EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: ");
   384         EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: ");
   383         ec_datagram_print_state(datagram);
   385         ec_datagram_print_state(mbox->datagram);
   384         return;
   386         return;
   385     }
   387     }
   386 
   388 
   387     if (datagram->working_counter != 1) {
   389     if (!ec_mbox_is_datagram_wc(mbox,1)) {
   388         voe->state = ec_voe_handler_state_error;
   390         voe->state = ec_voe_handler_state_error;
   389         voe->request_state = EC_INT_REQUEST_FAILURE;
   391         voe->request_state = EC_INT_REQUEST_FAILURE;
   390         EC_SLAVE_ERR(slave, "Reception of VoE read response failed: ");
   392         EC_SLAVE_ERR(slave, "Reception of VoE read response failed: ");
   391         ec_datagram_print_wc_error(datagram);
   393         ec_datagram_print_wc_error(mbox->datagram);
   392         return;
   394         return;
   393     }
   395     }
   394 
   396 
   395     data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
   397     data = ec_slave_mbox_fetch(slave, mbox, &mbox_prot, &rec_size);
   396     if (IS_ERR(data)) {
   398     if (IS_ERR(data)) {
   397         voe->state = ec_voe_handler_state_error;
   399         voe->state = ec_voe_handler_state_error;
   398         voe->request_state = EC_INT_REQUEST_FAILURE;
   400         voe->request_state = EC_INT_REQUEST_FAILURE;
   399         return;
   401         return;
   400     }
   402     }
   430 
   432 
   431 /** Start reading VoE data without sending a sync message before.
   433 /** Start reading VoE data without sending a sync message before.
   432  */
   434  */
   433 void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *voe)
   435 void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *voe)
   434 {
   436 {
   435     ec_datagram_t *datagram = &voe->datagram;
   437     ec_mailbox_t *mbox = &voe->mbox;
   436     ec_slave_t *slave = voe->config->slave;
   438     ec_slave_t *slave = voe->config->slave;
   437 
   439 
   438     EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n");
   440     EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n");
   439 
   441 
   440     if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) {
   442     if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) {
   442         voe->state = ec_voe_handler_state_error;
   444         voe->state = ec_voe_handler_state_error;
   443         voe->request_state = EC_INT_REQUEST_FAILURE;
   445         voe->request_state = EC_INT_REQUEST_FAILURE;
   444         return;
   446         return;
   445     }
   447     }
   446 
   448 
   447     ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
   449     ec_slave_mbox_prepare_fetch(slave, mbox); // can not fail.
   448 
   450 
   449     voe->jiffies_start = jiffies;
   451     voe->jiffies_start = jiffies;
   450     voe->retries = EC_FSM_RETRIES;
   452     voe->retries = EC_FSM_RETRIES;
   451     voe->state = ec_voe_handler_state_read_nosync_response;
   453     voe->state = ec_voe_handler_state_read_nosync_response;
   452 }
   454 }
   456 /** Read the pending mailbox data without sending a sync message before. This
   458 /** Read the pending mailbox data without sending a sync message before. This
   457  *  might lead to an empty reponse from the client.
   459  *  might lead to an empty reponse from the client.
   458  */
   460  */
   459 void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *voe)
   461 void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *voe)
   460 {
   462 {
   461     ec_datagram_t *datagram = &voe->datagram;
   463     ec_mailbox_t *mbox = &voe->mbox;
   462     ec_slave_t *slave = voe->config->slave;
   464     ec_slave_t *slave = voe->config->slave;
   463     ec_master_t *master = voe->config->master;
   465     ec_master_t *master = voe->config->master;
   464     uint8_t *data, mbox_prot;
   466     uint8_t *data, mbox_prot;
   465     size_t rec_size;
   467     size_t rec_size;
   466 
   468 
   467     if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
   469     if (ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_TIMED_OUT) && voe->retries--)
   468         return;
   470         return;
   469 
   471 
   470     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   472     if (!ec_mbox_is_datagram_state(mbox,EC_DATAGRAM_RECEIVED)) {
   471         voe->state = ec_voe_handler_state_error;
   473         voe->state = ec_voe_handler_state_error;
   472         voe->request_state = EC_INT_REQUEST_FAILURE;
   474         voe->request_state = EC_INT_REQUEST_FAILURE;
   473         EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: ");
   475         EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: ");
   474         ec_datagram_print_state(datagram);
   476         ec_datagram_print_state(mbox->datagram);
   475         return;
   477         return;
   476     }
   478     }
   477 
   479 
   478     if (datagram->working_counter == 0) {
   480     if (ec_mbox_is_datagram_wc(mbox,0)) {
   479         voe->state = ec_voe_handler_state_error;
   481         voe->state = ec_voe_handler_state_error;
   480         voe->request_state = EC_INT_REQUEST_FAILURE;
   482         voe->request_state = EC_INT_REQUEST_FAILURE;
   481         EC_SLAVE_DBG(slave, 1, "Slave did not send VoE data.\n");
   483         EC_SLAVE_DBG(slave, 1, "Slave did not send VoE data.\n");
   482         return;
   484         return;
   483     }
   485     }
   484 
   486 
   485     if (datagram->working_counter != 1) {
   487     if (!ec_mbox_is_datagram_wc(mbox,1)) {
   486         voe->state = ec_voe_handler_state_error;
   488         voe->state = ec_voe_handler_state_error;
   487         voe->request_state = EC_INT_REQUEST_FAILURE;
   489         voe->request_state = EC_INT_REQUEST_FAILURE;
   488         EC_SLAVE_WARN(slave, "Reception of VoE read response failed: ");
   490         EC_SLAVE_WARN(slave, "Reception of VoE read response failed: ");
   489         ec_datagram_print_wc_error(datagram);
   491         ec_datagram_print_wc_error(mbox->datagram);
   490         return;
   492         return;
   491     }
   493     }
   492 
   494 
   493     if (!(data = ec_slave_mbox_fetch(slave, datagram,
   495     if (!(data = ec_slave_mbox_fetch(slave, mbox,
   494                     &mbox_prot, &rec_size))) {
   496                     &mbox_prot, &rec_size))) {
   495         voe->state = ec_voe_handler_state_error;
   497         voe->state = ec_voe_handler_state_error;
   496         voe->request_state = EC_INT_REQUEST_FAILURE;
   498         voe->request_state = EC_INT_REQUEST_FAILURE;
   497         return;
   499         return;
   498     }
   500     }