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