diff -r 3b81d074735c -r 3778920f61e4 master/pdo.c --- a/master/pdo.c Thu Feb 14 09:18:55 2008 +0000 +++ b/master/pdo.c Tue Feb 19 08:22:20 2008 +0000 @@ -44,66 +44,196 @@ /*****************************************************************************/ -/** - * PDO constructor. - */ - -void ec_pdo_init(ec_pdo_t *pdo /**< EtherCAT PDO */) -{ +void ec_pdo_clear_entries(ec_pdo_t *); + +/*****************************************************************************/ + +/** PDO constructor. + */ +void ec_pdo_init( + ec_pdo_t *pdo /**< EtherCAT PDO */ + ) +{ + pdo->sync_index = -1; // not assigned pdo->name = NULL; INIT_LIST_HEAD(&pdo->entries); } /*****************************************************************************/ -/** - * PDO destructor. - */ - +/** Pdo copy constructor. + */ +int ec_pdo_init_copy(ec_pdo_t *pdo, const ec_pdo_t *other_pdo) +{ + pdo->dir = other_pdo->dir; + pdo->index = other_pdo->index; + pdo->sync_index = other_pdo->sync_index; + pdo->name = NULL; + INIT_LIST_HEAD(&pdo->entries); + + if (ec_pdo_set_name(pdo, other_pdo->name)) + goto out_return; + + if (ec_pdo_copy_entries(pdo, other_pdo)) + goto out_clear; + + return 0; + +out_clear: + ec_pdo_clear(pdo); +out_return: + return -1; +} + +/*****************************************************************************/ + +/** PDO destructor. + */ void ec_pdo_clear(ec_pdo_t *pdo /**< EtherCAT PDO */) { + if (pdo->name) + kfree(pdo->name); + + ec_pdo_clear_entries(pdo); +} + +/*****************************************************************************/ + +/** Clear Pdo entry list. + */ +void ec_pdo_clear_entries(ec_pdo_t *pdo /**< EtherCAT PDO */) +{ ec_pdo_entry_t *entry, *next; // free all PDO entries list_for_each_entry_safe(entry, next, &pdo->entries, list) { list_del(&entry->list); + ec_pdo_entry_clear(entry); kfree(entry); } } /*****************************************************************************/ -/** - * Makes a deep copy of a PDO. - */ - -int ec_pdo_copy(ec_pdo_t *pdo, const ec_pdo_t *other_pdo) -{ - ec_pdo_entry_t *entry, *other_entry, *next; - - // make flat copy - *pdo = *other_pdo; - - INIT_LIST_HEAD(&pdo->entries); - list_for_each_entry(other_entry, &other_pdo->entries, list) { +/** Set Pdo name. + */ +int ec_pdo_set_name( + ec_pdo_t *pdo, /**< Pdo. */ + const char *name /**< New name. */ + ) +{ + unsigned int len; + + if (pdo->name) + kfree(pdo->name); + + if (name && (len = strlen(name))) { + if (!(pdo->name = (char *) kmalloc(len + 1, GFP_KERNEL))) { + EC_ERR("Failed to allocate PDO name.\n"); + return -1; + } + memcpy(pdo->name, name, len + 1); + } else { + pdo->name = NULL; + } + + return 0; +} + +/*****************************************************************************/ + +/** Copy Pdo entries from another Pdo. + */ +int ec_pdo_copy_entries(ec_pdo_t *pdo, const ec_pdo_t *other) +{ + ec_pdo_entry_t *entry, *other_entry; + + ec_pdo_clear_entries(pdo); + + list_for_each_entry(other_entry, &other->entries, list) { if (!(entry = (ec_pdo_entry_t *) kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) { EC_ERR("Failed to allocate memory for PDO entry copy.\n"); - goto out_free; - } - - *entry = *other_entry; // flat copy is sufficient + return -1; + } + + if (ec_pdo_entry_init_copy(entry, other_entry)) { + kfree(entry); + return -1; + } + list_add_tail(&entry->list, &pdo->entries); } return 0; - -out_free: - list_for_each_entry_safe(entry, next, &pdo->entries, list) { - list_del(&entry->list); - kfree(entry); - } - return -1; -} - -/*****************************************************************************/ +} + +/*****************************************************************************/ + +/** Pdo entry constructor. + */ +void ec_pdo_entry_init( + ec_pdo_entry_t *entry /**< Pdo entry. */ + ) +{ + entry->name = NULL; +} + +/*****************************************************************************/ + +/** Pdo entry copy constructor. + */ +int ec_pdo_entry_init_copy( + ec_pdo_entry_t *entry, /**< Pdo entry. */ + const ec_pdo_entry_t *other /**< Pdo entry to copy from. */ + ) +{ + entry->index = other->index; + entry->subindex = other->subindex; + entry->name = NULL; + entry->bit_length = other->bit_length; + + if (ec_pdo_entry_set_name(entry, other->name)) + return -1; + + return 0; +} + +/*****************************************************************************/ + +/** Pdo entry destructor. + */ +void ec_pdo_entry_clear(ec_pdo_entry_t *entry /**< Pdo entry. */) +{ + if (entry->name) + kfree(entry->name); +} + +/*****************************************************************************/ + +/** Set Pdo entry name. + */ +int ec_pdo_entry_set_name( + ec_pdo_entry_t *entry, /**< Pdo entry. */ + const char *name /**< New name. */ + ) +{ + unsigned int len; + + if (entry->name) + kfree(entry->name); + + if (name && (len = strlen(name))) { + if (!(entry->name = (char *) kmalloc(len + 1, GFP_KERNEL))) { + EC_ERR("Failed to allocate PDO entry name.\n"); + return -1; + } + memcpy(entry->name, name, len + 1); + } else { + entry->name = NULL; + } + + return 0; +} + +/*****************************************************************************/