Moved sii to words.
This commit is contained in:
parent
f4c830c21d
commit
96b3009e8e
|
|
@ -384,7 +384,7 @@ void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *fsm /**< slave state
|
|||
" %u words (0xffff limiter missing?).\n",
|
||||
slave->ring_position, EC_MAX_SII_SIZE);
|
||||
// cut off category data...
|
||||
slave->sii_size = EC_FIRST_SII_CATEGORY_OFFSET * 2;
|
||||
slave->sii_nwords = EC_FIRST_SII_CATEGORY_OFFSET;
|
||||
goto alloc_sii;
|
||||
}
|
||||
fsm->sii_offset = next_offset;
|
||||
|
|
@ -394,20 +394,20 @@ void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *fsm /**< slave state
|
|||
return;
|
||||
}
|
||||
|
||||
slave->sii_size = (fsm->sii_offset + 1) * 2;
|
||||
slave->sii_nwords = fsm->sii_offset + 1;
|
||||
|
||||
alloc_sii:
|
||||
if (slave->sii_data) {
|
||||
if (slave->sii_words) {
|
||||
EC_WARN("Freeing old SII data on slave %i...\n",
|
||||
slave->ring_position);
|
||||
kfree(slave->sii_data);
|
||||
kfree(slave->sii_words);
|
||||
}
|
||||
|
||||
if (!(slave->sii_data =
|
||||
(uint8_t *) kmalloc(slave->sii_size, GFP_ATOMIC))) {
|
||||
EC_ERR("Failed to allocate %u bytes of SII data for slave %u.\n",
|
||||
slave->sii_size, slave->ring_position);
|
||||
slave->sii_size = 0;
|
||||
if (!(slave->sii_words =
|
||||
(uint16_t *) kmalloc(slave->sii_nwords * 2, GFP_ATOMIC))) {
|
||||
EC_ERR("Failed to allocate %u words of SII data for slave %u.\n",
|
||||
slave->sii_nwords, slave->ring_position);
|
||||
slave->sii_nwords = 0;
|
||||
slave->error_flag = 1;
|
||||
fsm->state = ec_fsm_slave_scan_state_error;
|
||||
return;
|
||||
|
|
@ -431,7 +431,7 @@ alloc_sii:
|
|||
void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state machine */)
|
||||
{
|
||||
ec_slave_t *slave = fsm->slave;
|
||||
uint16_t *cat_word, cat_type, cat_size, sii_word_size = slave->sii_size / 2;
|
||||
uint16_t *cat_word, cat_type, cat_size;
|
||||
|
||||
if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
|
||||
|
||||
|
|
@ -445,16 +445,13 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
|
|||
|
||||
// 2 words fetched
|
||||
|
||||
if (fsm->sii_offset + 2 <= sii_word_size) { // 2 words fit
|
||||
memcpy(slave->sii_data + fsm->sii_offset * 2,
|
||||
fsm->fsm_sii.value, 4);
|
||||
}
|
||||
else { // copy the last word
|
||||
memcpy(slave->sii_data + fsm->sii_offset * 2,
|
||||
fsm->fsm_sii.value, 2);
|
||||
if (fsm->sii_offset + 2 <= slave->sii_nwords) { // 2 words fit
|
||||
memcpy(slave->sii_words + fsm->sii_offset, fsm->fsm_sii.value, 4);
|
||||
} else { // copy the last word
|
||||
memcpy(slave->sii_words + fsm->sii_offset, fsm->fsm_sii.value, 2);
|
||||
}
|
||||
|
||||
if (fsm->sii_offset + 2 < sii_word_size) {
|
||||
if (fsm->sii_offset + 2 < slave->sii_nwords) {
|
||||
// fetch the next 2 words
|
||||
fsm->sii_offset += 2;
|
||||
ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
|
||||
|
|
@ -468,33 +465,33 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
|
|||
ec_slave_clear_sync_managers(slave);
|
||||
|
||||
slave->sii.alias =
|
||||
EC_READ_U16(slave->sii_data + 2 * 0x0004);
|
||||
EC_READ_U16(slave->sii_words + 0x0004);
|
||||
slave->sii.vendor_id =
|
||||
EC_READ_U32(slave->sii_data + 2 * 0x0008);
|
||||
EC_READ_U32(slave->sii_words + 0x0008);
|
||||
slave->sii.product_code =
|
||||
EC_READ_U32(slave->sii_data + 2 * 0x000A);
|
||||
EC_READ_U32(slave->sii_words + 0x000A);
|
||||
slave->sii.revision_number =
|
||||
EC_READ_U32(slave->sii_data + 2 * 0x000C);
|
||||
EC_READ_U32(slave->sii_words + 0x000C);
|
||||
slave->sii.serial_number =
|
||||
EC_READ_U32(slave->sii_data + 2 * 0x000E);
|
||||
EC_READ_U32(slave->sii_words + 0x000E);
|
||||
slave->sii.rx_mailbox_offset =
|
||||
EC_READ_U16(slave->sii_data + 2 * 0x0018);
|
||||
EC_READ_U16(slave->sii_words + 0x0018);
|
||||
slave->sii.rx_mailbox_size =
|
||||
EC_READ_U16(slave->sii_data + 2 * 0x0019);
|
||||
EC_READ_U16(slave->sii_words + 0x0019);
|
||||
slave->sii.tx_mailbox_offset =
|
||||
EC_READ_U16(slave->sii_data + 2 * 0x001A);
|
||||
EC_READ_U16(slave->sii_words + 0x001A);
|
||||
slave->sii.tx_mailbox_size =
|
||||
EC_READ_U16(slave->sii_data + 2 * 0x001B);
|
||||
EC_READ_U16(slave->sii_words + 0x001B);
|
||||
slave->sii.mailbox_protocols =
|
||||
EC_READ_U16(slave->sii_data + 2 * 0x001C);
|
||||
EC_READ_U16(slave->sii_words + 0x001C);
|
||||
|
||||
if (sii_word_size == EC_FIRST_SII_CATEGORY_OFFSET) {
|
||||
if (slave->sii_nwords == EC_FIRST_SII_CATEGORY_OFFSET) {
|
||||
// sii does not contain category data
|
||||
fsm->state = ec_fsm_slave_scan_state_end;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sii_word_size < EC_FIRST_SII_CATEGORY_OFFSET + 1) {
|
||||
if (slave->sii_nwords < EC_FIRST_SII_CATEGORY_OFFSET + 1) {
|
||||
EC_ERR("Unexpected end of SII data in slave %u:"
|
||||
" First category header missing.\n",
|
||||
slave->ring_position);
|
||||
|
|
@ -502,13 +499,11 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
|
|||
}
|
||||
|
||||
// evaluate category data
|
||||
cat_word =
|
||||
(uint16_t *) slave->sii_data + EC_FIRST_SII_CATEGORY_OFFSET;
|
||||
cat_word = slave->sii_words + EC_FIRST_SII_CATEGORY_OFFSET;
|
||||
while (EC_READ_U16(cat_word) != 0xFFFF) {
|
||||
|
||||
// type and size words must fit
|
||||
if (cat_word + 2 - (uint16_t *) slave->sii_data
|
||||
> sii_word_size) {
|
||||
if (cat_word + 2 - slave->sii_words > slave->sii_nwords) {
|
||||
EC_ERR("Unexpected end of SII data in slave %u:"
|
||||
" Category header incomplete.\n",
|
||||
slave->ring_position);
|
||||
|
|
@ -519,8 +514,7 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
|
|||
cat_size = EC_READ_U16(cat_word + 1);
|
||||
cat_word += 2;
|
||||
|
||||
if (cat_word + cat_size - (uint16_t *) slave->sii_data
|
||||
> sii_word_size) {
|
||||
if (cat_word + cat_size - slave->sii_words > slave->sii_nwords) {
|
||||
EC_WARN("Unexpected end of SII data in slave %u:"
|
||||
" Category data incomplete.\n",
|
||||
slave->ring_position);
|
||||
|
|
@ -562,7 +556,7 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
|
|||
}
|
||||
|
||||
cat_word += cat_size;
|
||||
if (cat_word - (uint16_t *) slave->sii_data >= sii_word_size) {
|
||||
if (cat_word - slave->sii_words >= slave->sii_nwords) {
|
||||
EC_WARN("Unexpected end of SII data in slave %u:"
|
||||
" Next category header missing.\n",
|
||||
slave->ring_position);
|
||||
|
|
|
|||
|
|
@ -124,8 +124,8 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
|
|||
slave->base_build = 0;
|
||||
slave->base_fmmu_count = 0;
|
||||
|
||||
slave->sii_data = NULL;
|
||||
slave->sii_size = 0;
|
||||
slave->sii_words = NULL;
|
||||
slave->sii_nwords = 0;
|
||||
|
||||
slave->sii.alias = 0;
|
||||
slave->sii.vendor_id = 0;
|
||||
|
|
@ -267,8 +267,8 @@ void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
|
|||
kfree(pdo);
|
||||
}
|
||||
|
||||
if (slave->sii_data)
|
||||
kfree(slave->sii_data);
|
||||
if (slave->sii_words)
|
||||
kfree(slave->sii_words);
|
||||
|
||||
kfree(slave);
|
||||
}
|
||||
|
|
@ -1033,14 +1033,14 @@ ssize_t ec_slave_write_alias(ec_slave_t *slave, /**< EtherCAT slave */
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!slave->sii_data || slave->sii_size < 16) {
|
||||
if (!slave->sii_words || slave->sii_nwords < 8) {
|
||||
EC_ERR("Failed to read SII contents from slave %u.\n",
|
||||
slave->ring_position);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// copy first 7 words of recent SII contents
|
||||
memcpy(sii_data, slave->sii_data, 14);
|
||||
memcpy(sii_data, (uint8_t *) slave->sii_words, 14);
|
||||
|
||||
// write new alias address in word 4
|
||||
EC_WRITE_U16(sii_data + 8, alias);
|
||||
|
|
@ -1077,19 +1077,21 @@ ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */
|
|||
)
|
||||
{
|
||||
ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
|
||||
unsigned int sii_size;
|
||||
|
||||
if (attr == &attr_info) {
|
||||
return ec_slave_info(slave, buffer);
|
||||
} else if (attr == &attr_sii) {
|
||||
if (slave->sii_data) {
|
||||
if (slave->sii_size > PAGE_SIZE) {
|
||||
if (slave->sii_words) {
|
||||
sii_size = slave->sii_nwords * 2;
|
||||
if (sii_size > PAGE_SIZE) {
|
||||
EC_ERR("SII contents of slave %u exceed 1 page (%u/%u).\n",
|
||||
slave->ring_position, slave->sii_size,
|
||||
slave->ring_position, sii_size,
|
||||
(int) PAGE_SIZE);
|
||||
}
|
||||
else {
|
||||
memcpy(buffer, slave->sii_data, slave->sii_size);
|
||||
return slave->sii_size;
|
||||
memcpy(buffer, (uint8_t *) slave->sii_words, sii_size);
|
||||
return sii_size;
|
||||
}
|
||||
}
|
||||
} else if (attr == &attr_alias) {
|
||||
|
|
|
|||
|
|
@ -188,8 +188,8 @@ struct ec_slave
|
|||
uint8_t dl_signal[4]; /**< detected signal on RX port */
|
||||
|
||||
// SII
|
||||
uint8_t *sii_data; /**< Complete SII image */
|
||||
size_t sii_size; /**< size of the SII contents in bytes */
|
||||
uint16_t *sii_words; /**< Complete SII image. */
|
||||
size_t sii_nwords; /**< Size of the SII contents in words. */
|
||||
|
||||
// slave information interface
|
||||
ec_sii_t sii; /**< SII data. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue