master/slave_config.c
changeset 1313 ed15eef57d5c
parent 1312 74853e018898
child 1326 ef907b0b5125
equal deleted inserted replaced
1312:74853e018898 1313:ed15eef57d5c
   133  * manager is covered. Seperate FMMUs are configured for each domain. If the
   133  * manager is covered. Seperate FMMUs are configured for each domain. If the
   134  * FMMU configuration is already prepared, the function does nothing and
   134  * FMMU configuration is already prepared, the function does nothing and
   135  * returns with success.
   135  * returns with success.
   136  *
   136  *
   137  * \retval >=0 Success, logical offset byte address.
   137  * \retval >=0 Success, logical offset byte address.
   138  * \retval -1  Error, FMMU limit reached.
   138  * \retval  <0 Error code.
   139  */
   139  */
   140 int ec_slave_config_prepare_fmmu(
   140 int ec_slave_config_prepare_fmmu(
   141         ec_slave_config_t *sc, /**< Slave configuration. */
   141         ec_slave_config_t *sc, /**< Slave configuration. */
   142         ec_domain_t *domain, /**< Domain. */
   142         ec_domain_t *domain, /**< Domain. */
   143         uint8_t sync_index, /**< Sync manager index. */
   143         uint8_t sync_index, /**< Sync manager index. */
   155     }
   155     }
   156 
   156 
   157     if (sc->used_fmmus == EC_MAX_FMMUS) {
   157     if (sc->used_fmmus == EC_MAX_FMMUS) {
   158         EC_ERR("FMMU limit reached for slave configuration %u:%u!\n",
   158         EC_ERR("FMMU limit reached for slave configuration %u:%u!\n",
   159                 sc->alias, sc->position);
   159                 sc->alias, sc->position);
   160         return -1;
   160         return -EOVERFLOW;
   161     }
   161     }
   162 
   162 
   163     fmmu = &sc->fmmu_configs[sc->used_fmmus++];
   163     fmmu = &sc->fmmu_configs[sc->used_fmmus++];
   164 
   164 
   165     down(&sc->master->master_sem);
   165     down(&sc->master->master_sem);
   171 
   171 
   172 /*****************************************************************************/
   172 /*****************************************************************************/
   173 
   173 
   174 /** Attaches the configuration to the addressed slave object.
   174 /** Attaches the configuration to the addressed slave object.
   175  *
   175  *
   176  * \retval 0 Success.
   176  * \retval  0 Success.
   177  * \retval -1 Slave not found.
   177  * \retval <0 Error code.
   178  * \retval -2 Slave already configured.
       
   179  * \retval -3 Invalid slave type found at the given position.
       
   180  */
   178  */
   181 int ec_slave_config_attach(
   179 int ec_slave_config_attach(
   182         ec_slave_config_t *sc /**< Slave configuration. */
   180         ec_slave_config_t *sc /**< Slave configuration. */
   183         )
   181         )
   184 {
   182 {
   190     if (!(slave = ec_master_find_slave(
   188     if (!(slave = ec_master_find_slave(
   191                     sc->master, sc->alias, sc->position))) {
   189                     sc->master, sc->alias, sc->position))) {
   192         if (sc->master->debug_level)
   190         if (sc->master->debug_level)
   193             EC_DBG("Failed to find slave for configuration %u:%u.\n",
   191             EC_DBG("Failed to find slave for configuration %u:%u.\n",
   194                     sc->alias, sc->position);
   192                     sc->alias, sc->position);
   195         return -1;
   193         return -ENOENT;
   196     }
   194     }
   197 
   195 
   198 	if (slave->config) {
   196 	if (slave->config) {
   199         if (sc->master->debug_level)
   197         if (sc->master->debug_level)
   200             EC_DBG("Failed to attach slave configuration %u:%u. Slave %u"
   198             EC_DBG("Failed to attach slave configuration %u:%u. Slave %u"
   201                     " already has a configuration!\n", sc->alias,
   199                     " already has a configuration!\n", sc->alias,
   202                     sc->position, slave->ring_position);
   200                     sc->position, slave->ring_position);
   203         return -2;
   201         return -EEXIST;
   204     }
   202     }
   205 
   203 
   206     if (slave->sii.vendor_id != sc->vendor_id
   204     if (slave->sii.vendor_id != sc->vendor_id
   207             || slave->sii.product_code != sc->product_code) {
   205             || slave->sii.product_code != sc->product_code) {
   208         if (sc->master->debug_level)
   206         if (sc->master->debug_level)
   209             EC_DBG("Slave %u has an invalid type (0x%08X/0x%08X) for"
   207             EC_DBG("Slave %u has an invalid type (0x%08X/0x%08X) for"
   210                     " configuration %u:%u (0x%08X/0x%08X).\n",
   208                     " configuration %u:%u (0x%08X/0x%08X).\n",
   211                     slave->ring_position, slave->sii.vendor_id,
   209                     slave->ring_position, slave->sii.vendor_id,
   212                     slave->sii.product_code, sc->alias, sc->position,
   210                     slave->sii.product_code, sc->alias, sc->position,
   213                     sc->vendor_id, sc->product_code);
   211                     sc->vendor_id, sc->product_code);
   214         return -3;
   212         return -EINVAL;
   215 	}
   213 	}
   216 
   214 
   217 	// attach slave
   215 	// attach slave
   218 	slave->config = sc;
   216 	slave->config = sc;
   219 	sc->slave = slave;
   217 	sc->slave = slave;
   397         EC_DBG("ecrt_slave_config_sync_manager(sc = 0x%x, sync_index = %u, "
   395         EC_DBG("ecrt_slave_config_sync_manager(sc = 0x%x, sync_index = %u, "
   398                 "dir = %u)\n", (u32) sc, sync_index, dir);
   396                 "dir = %u)\n", (u32) sc, sync_index, dir);
   399 
   397 
   400     if (sync_index >= EC_MAX_SYNC_MANAGERS) {
   398     if (sync_index >= EC_MAX_SYNC_MANAGERS) {
   401         EC_ERR("Invalid sync manager index %u!\n", sync_index);
   399         EC_ERR("Invalid sync manager index %u!\n", sync_index);
   402         return -1;
   400         return -ENOENT;
   403     }
   401     }
   404 
   402 
   405     if (dir != EC_DIR_OUTPUT && dir != EC_DIR_INPUT) {
   403     if (dir != EC_DIR_OUTPUT && dir != EC_DIR_INPUT) {
   406         EC_ERR("Invalid direction %u!\n", (u32) dir);
   404         EC_ERR("Invalid direction %u!\n", (u32) dir);
   407         return -1;
   405         return -EINVAL;
   408     }
   406     }
   409 
   407 
   410     sync_config = &sc->sync_configs[sync_index];
   408     sync_config = &sc->sync_configs[sync_index];
   411     sync_config->dir = dir;
   409     sync_config->dir = dir;
   412     return 0;
   410     return 0;
   423         EC_DBG("ecrt_slave_config_pdo_assign_add(sc = 0x%x, sync_index = %u, "
   421         EC_DBG("ecrt_slave_config_pdo_assign_add(sc = 0x%x, sync_index = %u, "
   424                 "pdo_index = 0x%04X)\n", (u32) sc, sync_index, pdo_index);
   422                 "pdo_index = 0x%04X)\n", (u32) sc, sync_index, pdo_index);
   425 
   423 
   426     if (sync_index >= EC_MAX_SYNC_MANAGERS) {
   424     if (sync_index >= EC_MAX_SYNC_MANAGERS) {
   427         EC_ERR("Invalid sync manager index %u!\n", sync_index);
   425         EC_ERR("Invalid sync manager index %u!\n", sync_index);
   428         return -1;
   426         return -EINVAL;
   429     }
   427     }
   430 
   428 
   431     down(&sc->master->master_sem);
   429     down(&sc->master->master_sem);
   432 
   430 
   433     if (!(pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos,
   431     pdo = ec_pdo_list_add_pdo(&sc->sync_configs[sync_index].pdos, pdo_index);
   434                     pdo_index))) {
   432     if (IS_ERR(pdo)) {
   435         up(&sc->master->master_sem);
   433         up(&sc->master->master_sem);
   436         return -1;
   434         return PTR_ERR(pdo);
   437     }
   435     }
   438     pdo->sync_index = sync_index;
   436     pdo->sync_index = sync_index;
   439 
   437 
   440     ec_slave_config_load_default_mapping(sc, pdo);
   438     ec_slave_config_load_default_mapping(sc, pdo);
   441 
   439 
   468         uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
   466         uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex,
   469         uint8_t entry_bit_length)
   467         uint8_t entry_bit_length)
   470 {
   468 {
   471     uint8_t sync_index;
   469     uint8_t sync_index;
   472     ec_pdo_t *pdo = NULL;
   470     ec_pdo_t *pdo = NULL;
   473     int retval = -1;
   471     ec_pdo_entry_t *entry;
       
   472     int retval = 0;
   474     
   473     
   475     if (sc->master->debug_level)
   474     if (sc->master->debug_level)
   476         EC_DBG("ecrt_slave_config_pdo_mapping_add(sc = 0x%x, "
   475         EC_DBG("ecrt_slave_config_pdo_mapping_add(sc = 0x%x, "
   477                 "pdo_index = 0x%04X, entry_index = 0x%04X, "
   476                 "pdo_index = 0x%04X, entry_index = 0x%04X, "
   478                 "entry_subindex = 0x%02X, entry_bit_length = %u)\n",
   477                 "entry_subindex = 0x%02X, entry_bit_length = %u)\n",
   484                         &sc->sync_configs[sync_index].pdos, pdo_index)))
   483                         &sc->sync_configs[sync_index].pdos, pdo_index)))
   485             break;
   484             break;
   486 
   485 
   487     if (pdo) {
   486     if (pdo) {
   488         down(&sc->master->master_sem);
   487         down(&sc->master->master_sem);
   489         retval = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
   488         entry = ec_pdo_add_entry(pdo, entry_index, entry_subindex,
   490                 entry_bit_length) ? 0 : -1;
   489                 entry_bit_length);
   491         up(&sc->master->master_sem);
   490         up(&sc->master->master_sem);
       
   491         if (IS_ERR(entry))
       
   492             retval = PTR_ERR(entry);
   492     } else {
   493     } else {
   493         EC_ERR("Pdo 0x%04X is not assigned in config %u:%u.\n",
   494         EC_ERR("Pdo 0x%04X is not assigned in config %u:%u.\n",
   494                 pdo_index, sc->alias, sc->position);
   495                 pdo_index, sc->alias, sc->position);
       
   496         retval = -ENOENT; 
   495     }
   497     }
   496 
   498 
   497     return retval;
   499     return retval;
   498 }
   500 }
   499 
   501 
   527 /*****************************************************************************/
   529 /*****************************************************************************/
   528 
   530 
   529 int ecrt_slave_config_pdos(ec_slave_config_t *sc,
   531 int ecrt_slave_config_pdos(ec_slave_config_t *sc,
   530         unsigned int n_syncs, const ec_sync_info_t syncs[])
   532         unsigned int n_syncs, const ec_sync_info_t syncs[])
   531 {
   533 {
       
   534     int ret;
   532     unsigned int i, j, k;
   535     unsigned int i, j, k;
   533     const ec_sync_info_t *sync_info;
   536     const ec_sync_info_t *sync_info;
   534     const ec_pdo_info_t *pdo_info;
   537     const ec_pdo_info_t *pdo_info;
   535     const ec_pdo_entry_info_t *entry_info;
   538     const ec_pdo_entry_info_t *entry_info;
   536 
   539 
   547         if (sync_info->index == (uint8_t) EC_END)
   550         if (sync_info->index == (uint8_t) EC_END)
   548             break;
   551             break;
   549 
   552 
   550         if (sync_info->index >= EC_MAX_SYNC_MANAGERS) {
   553         if (sync_info->index >= EC_MAX_SYNC_MANAGERS) {
   551             EC_ERR("Invalid sync manager index %u!\n", sync_info->index);
   554             EC_ERR("Invalid sync manager index %u!\n", sync_info->index);
   552             return -1;
   555             return -ENOENT;
   553         }
   556         }
   554 
   557 
   555         if (ecrt_slave_config_sync_manager(
   558         ret = ecrt_slave_config_sync_manager(
   556                     sc, sync_info->index, sync_info->dir))
   559                 sc, sync_info->index, sync_info->dir);
   557             return -1;
   560         if (ret)
       
   561             return ret;
   558 
   562 
   559         if (sync_info->n_pdos && sync_info->pdos) {
   563         if (sync_info->n_pdos && sync_info->pdos) {
   560             ecrt_slave_config_pdo_assign_clear(sc, sync_info->index);
   564             ecrt_slave_config_pdo_assign_clear(sc, sync_info->index);
   561 
   565 
   562             for (j = 0; j < sync_info->n_pdos; j++) {
   566             for (j = 0; j < sync_info->n_pdos; j++) {
   563                 pdo_info = &sync_info->pdos[j];
   567                 pdo_info = &sync_info->pdos[j];
   564 
   568 
   565                 if (ecrt_slave_config_pdo_assign_add(
   569                 ret = ecrt_slave_config_pdo_assign_add(
   566                             sc, sync_info->index, pdo_info->index))
   570                         sc, sync_info->index, pdo_info->index);
   567                     return -1;
   571                 if (ret)
       
   572                     return ret;
   568 
   573 
   569                 if (pdo_info->n_entries && pdo_info->entries) {
   574                 if (pdo_info->n_entries && pdo_info->entries) {
   570                     ecrt_slave_config_pdo_mapping_clear(sc, pdo_info->index);
   575                     ecrt_slave_config_pdo_mapping_clear(sc, pdo_info->index);
   571 
   576 
   572                     for (k = 0; k < pdo_info->n_entries; k++) {
   577                     for (k = 0; k < pdo_info->n_entries; k++) {
   573                         entry_info = &pdo_info->entries[k];
   578                         entry_info = &pdo_info->entries[k];
   574 
   579 
   575                         if (ecrt_slave_config_pdo_mapping_add(sc,
   580                         ret = ecrt_slave_config_pdo_mapping_add(sc,
   576                                     pdo_info->index, entry_info->index,
   581                                 pdo_info->index, entry_info->index,
   577                                     entry_info->subindex,
   582                                 entry_info->subindex,
   578                                     entry_info->bit_length))
   583                                 entry_info->bit_length);
   579                             return -1;
   584                         if (ret)
       
   585                             return ret;
   580                     }
   586                     }
   581                 }
   587                 }
   582             }
   588             }
   583         }
   589         }
   584     }
   590     }
   622                         *bit_position = bit_pos;
   628                         *bit_position = bit_pos;
   623                     } else if (bit_pos) {
   629                     } else if (bit_pos) {
   624                         EC_ERR("Pdo entry 0x%04X:%02X does not byte-align "
   630                         EC_ERR("Pdo entry 0x%04X:%02X does not byte-align "
   625                                 "in config %u:%u.\n", index, subindex,
   631                                 "in config %u:%u.\n", index, subindex,
   626                                 sc->alias, sc->position);
   632                                 sc->alias, sc->position);
   627                         return -3;
   633                         return -EFAULT;
   628                     }
   634                     }
   629 
   635 
   630                     sync_offset = ec_slave_config_prepare_fmmu(
   636                     sync_offset = ec_slave_config_prepare_fmmu(
   631                             sc, domain, sync_index, sync_config->dir);
   637                             sc, domain, sync_index, sync_config->dir);
   632                     if (sync_offset < 0)
   638                     if (sync_offset < 0)
   633                         return -2;
   639                         return sync_offset;
   634 
   640 
   635                     return sync_offset + bit_offset / 8;
   641                     return sync_offset + bit_offset / 8;
   636                 }
   642                 }
   637             }
   643             }
   638         }
   644         }
   639     }
   645     }
   640 
   646 
   641     EC_ERR("Pdo entry 0x%04X:%02X is not mapped in slave config %u:%u.\n",
   647     EC_ERR("Pdo entry 0x%04X:%02X is not mapped in slave config %u:%u.\n",
   642            index, subindex, sc->alias, sc->position);
   648            index, subindex, sc->alias, sc->position);
   643     return -1;
   649     return -ENOENT;
   644 }
   650 }
   645 
   651 
   646 
   652 
   647 /*****************************************************************************/
   653 /*****************************************************************************/
   648 
   654 
   649 int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index,
   655 int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index,
   650         uint8_t subindex, const uint8_t *data, size_t size)
   656         uint8_t subindex, const uint8_t *data, size_t size)
   651 {
   657 {
   652     ec_slave_t *slave = sc->slave;
   658     ec_slave_t *slave = sc->slave;
   653     ec_sdo_request_t *req;
   659     ec_sdo_request_t *req;
       
   660     int ret;
   654 
   661 
   655     if (sc->master->debug_level)
   662     if (sc->master->debug_level)
   656         EC_DBG("ecrt_slave_config_sdo(sc = 0x%x, index = 0x%04X, "
   663         EC_DBG("ecrt_slave_config_sdo(sc = 0x%x, index = 0x%04X, "
   657                 "subindex = 0x%02X, data = 0x%x, size = %u)\n", (u32) sc,
   664                 "subindex = 0x%02X, data = 0x%x, size = %u)\n", (u32) sc,
   658                 index, subindex, (u32) data, size);
   665                 index, subindex, (u32) data, size);
   659 
   666 
   660     if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
   667     if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
   661         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
   668         EC_ERR("Slave %u does not support CoE!\n", slave->ring_position);
   662         return -1;
   669         return -EPROTONOSUPPORT; // protocol not supported
   663     }
   670     }
   664 
   671 
   665     if (!(req = (ec_sdo_request_t *)
   672     if (!(req = (ec_sdo_request_t *)
   666           kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
   673           kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) {
   667         EC_ERR("Failed to allocate memory for Sdo configuration!\n");
   674         EC_ERR("Failed to allocate memory for Sdo configuration!\n");
   668         return -1;
   675         return -ENOMEM;
   669     }
   676     }
   670 
   677 
   671     ec_sdo_request_init(req);
   678     ec_sdo_request_init(req);
   672     ec_sdo_request_address(req, index, subindex);
   679     ec_sdo_request_address(req, index, subindex);
   673 
   680 
   674     if (ec_sdo_request_copy_data(req, data, size)) {
   681     ret = ec_sdo_request_copy_data(req, data, size);
       
   682     if (ret < 0) {
   675         ec_sdo_request_clear(req);
   683         ec_sdo_request_clear(req);
   676         kfree(req);
   684         kfree(req);
   677         return -1;
   685         return ret;
   678     }
   686     }
   679         
   687         
   680     down(&sc->master->master_sem);
   688     down(&sc->master->master_sem);
   681     list_add_tail(&req->list, &sc->sdo_configs);
   689     list_add_tail(&req->list, &sc->sdo_configs);
   682     up(&sc->master->master_sem);
   690     up(&sc->master->master_sem);
   683 
       
   684     return 0;
   691     return 0;
   685 }
   692 }
   686 
   693 
   687 /*****************************************************************************/
   694 /*****************************************************************************/
   688 
   695