master/slave.c
branchstable-1.0
changeset 1621 4bbe090553f7
parent 1619 0d4119024f55
child 1624 9dc190591c0f
equal deleted inserted replaced
1620:9d7453c16ade 1621:4bbe090553f7
    67 EC_SYSFS_READ_ATTR(product_name);
    67 EC_SYSFS_READ_ATTR(product_name);
    68 EC_SYSFS_READ_ATTR(product_desc);
    68 EC_SYSFS_READ_ATTR(product_desc);
    69 EC_SYSFS_READ_ATTR(sii_name);
    69 EC_SYSFS_READ_ATTR(sii_name);
    70 EC_SYSFS_READ_ATTR(type);
    70 EC_SYSFS_READ_ATTR(type);
    71 EC_SYSFS_READ_WRITE_ATTR(state);
    71 EC_SYSFS_READ_WRITE_ATTR(state);
       
    72 EC_SYSFS_READ_WRITE_ATTR(eeprom);
    72 
    73 
    73 static struct attribute *def_attrs[] = {
    74 static struct attribute *def_attrs[] = {
    74     &attr_ring_position,
    75     &attr_ring_position,
    75     &attr_coupler_address,
    76     &attr_coupler_address,
    76     &attr_vendor_name,
    77     &attr_vendor_name,
    77     &attr_product_name,
    78     &attr_product_name,
    78     &attr_product_desc,
    79     &attr_product_desc,
    79     &attr_sii_name,
    80     &attr_sii_name,
    80     &attr_type,
    81     &attr_type,
    81     &attr_state,
    82     &attr_state,
       
    83     &attr_eeprom,
    82     NULL,
    84     NULL,
    83 };
    85 };
    84 
    86 
    85 static struct sysfs_ops sysfs_ops = {
    87 static struct sysfs_ops sysfs_ops = {
    86     .show = ec_show_slave_attribute,
    88     .show = ec_show_slave_attribute,
   143     slave->sii_tx_mailbox_size = 0;
   145     slave->sii_tx_mailbox_size = 0;
   144     slave->sii_mailbox_protocols = 0;
   146     slave->sii_mailbox_protocols = 0;
   145     slave->type = NULL;
   147     slave->type = NULL;
   146     slave->registered = 0;
   148     slave->registered = 0;
   147     slave->fmmu_count = 0;
   149     slave->fmmu_count = 0;
       
   150     slave->eeprom_data = NULL;
       
   151     slave->eeprom_size = 0;
   148     slave->eeprom_group = NULL;
   152     slave->eeprom_group = NULL;
   149     slave->eeprom_image = NULL;
   153     slave->eeprom_image = NULL;
   150     slave->eeprom_order = NULL;
   154     slave->eeprom_order = NULL;
   151     slave->eeprom_name = NULL;
   155     slave->eeprom_name = NULL;
   152     slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
   156     slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
   153     slave->current_state = EC_SLAVE_STATE_UNKNOWN;
   157     slave->current_state = EC_SLAVE_STATE_UNKNOWN;
   154     slave->state_error = 0;
   158     slave->state_error = 0;
   155     slave->online = 1;
   159     slave->online = 1;
   156 
   160     slave->new_eeprom_data = NULL;
   157     ec_command_init(&slave->mbox_command);
   161     slave->new_eeprom_size = 0;
   158 
   162 
   159     INIT_LIST_HEAD(&slave->eeprom_strings);
   163     INIT_LIST_HEAD(&slave->eeprom_strings);
   160     INIT_LIST_HEAD(&slave->eeprom_syncs);
   164     INIT_LIST_HEAD(&slave->eeprom_syncs);
   161     INIT_LIST_HEAD(&slave->eeprom_pdos);
   165     INIT_LIST_HEAD(&slave->eeprom_pdos);
   162     INIT_LIST_HEAD(&slave->sdo_dictionary);
   166     INIT_LIST_HEAD(&slave->sdo_dictionary);
       
   167     INIT_LIST_HEAD(&slave->varsize_fields);
   163 
   168 
   164     for (i = 0; i < 4; i++) {
   169     for (i = 0; i < 4; i++) {
   165         slave->dl_link[i] = 0;
   170         slave->dl_link[i] = 0;
   166         slave->dl_loop[i] = 0;
   171         slave->dl_loop[i] = 0;
   167         slave->dl_signal[i] = 0;
   172         slave->dl_signal[i] = 0;
   184     ec_eeprom_sync_t *sync, *next_sync;
   189     ec_eeprom_sync_t *sync, *next_sync;
   185     ec_eeprom_pdo_t *pdo, *next_pdo;
   190     ec_eeprom_pdo_t *pdo, *next_pdo;
   186     ec_eeprom_pdo_entry_t *entry, *next_ent;
   191     ec_eeprom_pdo_entry_t *entry, *next_ent;
   187     ec_sdo_t *sdo, *next_sdo;
   192     ec_sdo_t *sdo, *next_sdo;
   188     ec_sdo_entry_t *en, *next_en;
   193     ec_sdo_entry_t *en, *next_en;
       
   194     ec_varsize_t *var, *next_var;
   189 
   195 
   190     slave = container_of(kobj, ec_slave_t, kobj);
   196     slave = container_of(kobj, ec_slave_t, kobj);
   191 
   197 
   192     // free all string objects
   198     // free all string objects
   193     list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
   199     list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
   232             kfree(en);
   238             kfree(en);
   233         }
   239         }
   234         kfree(sdo);
   240         kfree(sdo);
   235     }
   241     }
   236 
   242 
   237     ec_command_clear(&slave->mbox_command);
   243     // free information about variable sized data fields
       
   244     list_for_each_entry_safe(var, next_var, &slave->varsize_fields, list) {
       
   245         list_del(&var->list);
       
   246         kfree(var);
       
   247     }
       
   248 
       
   249     if (slave->eeprom_data) kfree(slave->eeprom_data);
       
   250     if (slave->new_eeprom_data) kfree(slave->new_eeprom_data);
   238 }
   251 }
   239 
   252 
   240 /*****************************************************************************/
   253 /*****************************************************************************/
   241 
   254 
   242 /**
   255 /**
  1119         printk("\n");
  1132         printk("\n");
  1120     }
  1133     }
  1121 
  1134 
  1122     EC_INFO("  EEPROM data:\n");
  1135     EC_INFO("  EEPROM data:\n");
  1123 
  1136 
       
  1137     EC_INFO("    EEPROM content size: %i Bytes\n", slave->eeprom_size);
       
  1138 
  1124     if (slave->sii_alias)
  1139     if (slave->sii_alias)
  1125         EC_INFO("    Configured station alias: 0x%04X (%i)\n",
  1140         EC_INFO("    Configured station alias: 0x%04X (%i)\n",
  1126                 slave->sii_alias, slave->sii_alias);
  1141                 slave->sii_alias, slave->sii_alias);
  1127 
  1142 
  1128     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
  1143     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
  1237 }
  1252 }
  1238 
  1253 
  1239 /*****************************************************************************/
  1254 /*****************************************************************************/
  1240 
  1255 
  1241 /**
  1256 /**
       
  1257    Schedules an EEPROM write operation.
       
  1258    \return 0 in case of success, else < 0
       
  1259 */
       
  1260 
       
  1261 ssize_t ec_slave_write_eeprom(ec_slave_t *slave, /**< EtherCAT slave */
       
  1262                               const uint8_t *data, /**< new EEPROM data */
       
  1263                               size_t size /**< size of data in bytes */
       
  1264                               )
       
  1265 {
       
  1266     uint16_t word_size, cat_type, cat_size;
       
  1267     const uint16_t *data_words, *next_header;
       
  1268     uint16_t *new_data;
       
  1269 
       
  1270     if (!slave->master->eeprom_write_enable) {
       
  1271         EC_ERR("Writing EEPROMs not allowed! Enable via"
       
  1272                " eeprom_write_enable SysFS entry.\n");
       
  1273         return -1;
       
  1274     }
       
  1275 
       
  1276     if (slave->master->mode != EC_MASTER_MODE_FREERUN) {
       
  1277         EC_ERR("Writing EEPROMs only allowed in freerun mode!\n");
       
  1278         return -1;
       
  1279     }
       
  1280 
       
  1281     if (slave->new_eeprom_data) {
       
  1282         EC_ERR("Slave %i already has a pending EEPROM write operation!\n",
       
  1283                slave->ring_position);
       
  1284         return -1;
       
  1285     }
       
  1286 
       
  1287     // coarse check of the data
       
  1288 
       
  1289     if (size % 2) {
       
  1290         EC_ERR("EEPROM size is odd! Dropping.\n");
       
  1291         return -1;
       
  1292     }
       
  1293 
       
  1294     data_words = (const uint16_t *) data;
       
  1295     word_size = size / 2;
       
  1296 
       
  1297     if (word_size < 0x0041) {
       
  1298         EC_ERR("EEPROM data too short! Dropping.\n");
       
  1299         return -1;
       
  1300     }
       
  1301 
       
  1302     next_header = data_words + 0x0040;
       
  1303     cat_type = EC_READ_U16(next_header);
       
  1304     while (cat_type != 0xFFFF) {
       
  1305         cat_type = EC_READ_U16(next_header);
       
  1306         cat_size = EC_READ_U16(next_header + 1);
       
  1307         if ((next_header + cat_size + 2) - data_words >= word_size) {
       
  1308             EC_ERR("EEPROM data seems to be corrupted! Dropping.\n");
       
  1309             return -1;
       
  1310         }
       
  1311         next_header += cat_size + 2;
       
  1312         cat_type = EC_READ_U16(next_header);
       
  1313     }
       
  1314 
       
  1315     // data ok!
       
  1316 
       
  1317     if (!(new_data = (uint16_t *) kmalloc(word_size * 2, GFP_KERNEL))) {
       
  1318         EC_ERR("Unable to allocate memory for new EEPROM data!\n");
       
  1319         return -1;
       
  1320     }
       
  1321     memcpy(new_data, data, size);
       
  1322 
       
  1323     slave->new_eeprom_size = word_size;
       
  1324     slave->new_eeprom_data = new_data;
       
  1325 
       
  1326     EC_INFO("EEPROM writing scheduled for slave %i, %i words.\n",
       
  1327             slave->ring_position, word_size);
       
  1328     return 0;
       
  1329 }
       
  1330 
       
  1331 /*****************************************************************************/
       
  1332 
       
  1333 /**
  1242    Formats attribute data for SysFS read access.
  1334    Formats attribute data for SysFS read access.
  1243    \return number of bytes to read
  1335    \return number of bytes to read
  1244 */
  1336 */
  1245 
  1337 
  1246 ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */
  1338 ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */
  1293                 return sprintf(buffer, "OP\n");
  1385                 return sprintf(buffer, "OP\n");
  1294             default:
  1386             default:
  1295                 return sprintf(buffer, "UNKNOWN\n");
  1387                 return sprintf(buffer, "UNKNOWN\n");
  1296         }
  1388         }
  1297     }
  1389     }
       
  1390     else if (attr == &attr_eeprom) {
       
  1391         if (slave->eeprom_data) {
       
  1392             if (slave->eeprom_size > PAGE_SIZE) {
       
  1393                 EC_ERR("EEPROM contents of slave %i exceed 1 page (%i/%i).\n",
       
  1394                        slave->ring_position, slave->eeprom_size,
       
  1395                        (int) PAGE_SIZE);
       
  1396             }
       
  1397             else {
       
  1398                 memcpy(buffer, slave->eeprom_data, slave->eeprom_size);
       
  1399                 return slave->eeprom_size;
       
  1400             }
       
  1401         }
       
  1402     }
  1298 
  1403 
  1299     return 0;
  1404     return 0;
  1300 }
  1405 }
  1301 
  1406 
  1302 /*****************************************************************************/
  1407 /*****************************************************************************/
  1336             return size;
  1441             return size;
  1337         }
  1442         }
  1338 
  1443 
  1339         EC_ERR("Failed to set slave state!\n");
  1444         EC_ERR("Failed to set slave state!\n");
  1340     }
  1445     }
       
  1446     else if (attr == &attr_eeprom) {
       
  1447         if (!ec_slave_write_eeprom(slave, buffer, size))
       
  1448             return size;
       
  1449     }
  1341 
  1450 
  1342     return -EINVAL;
  1451     return -EINVAL;
       
  1452 }
       
  1453 
       
  1454 /*****************************************************************************/
       
  1455 
       
  1456 /**
       
  1457    \return size of sync manager contents
       
  1458 */
       
  1459 
       
  1460 size_t ec_slave_calc_sync_size(const ec_slave_t *slave, /**< EtherCAT slave */
       
  1461                                const ec_sync_t *sync /**< sync manager */
       
  1462                                )
       
  1463 {
       
  1464     unsigned int i, found;
       
  1465     const ec_field_t *field;
       
  1466     const ec_varsize_t *var;
       
  1467     size_t size;
       
  1468 
       
  1469     // if size is specified, return size
       
  1470     if (sync->size) return sync->size;
       
  1471 
       
  1472     // sync manager has variable size (size == 0).
       
  1473 
       
  1474     size = 0;
       
  1475     for (i = 0; (field = sync->fields[i]); i++) {
       
  1476         found = 0;
       
  1477         list_for_each_entry(var, &slave->varsize_fields, list) {
       
  1478             if (var->field != field) continue;
       
  1479             size += var->size;
       
  1480             found = 1;
       
  1481         }
       
  1482 
       
  1483         if (!found) {
       
  1484             EC_WARN("Variable data field \"%s\" of slave %i has no size"
       
  1485                     " information!\n", field->name, slave->ring_position);
       
  1486         }
       
  1487     }
       
  1488     return size;
  1343 }
  1489 }
  1344 
  1490 
  1345 /******************************************************************************
  1491 /******************************************************************************
  1346  *  Realtime interface
  1492  *  Realtime interface
  1347  *****************************************************************************/
  1493  *****************************************************************************/
  1359     return ec_slave_sii_write16(slave, 0x0004, alias);
  1505     return ec_slave_sii_write16(slave, 0x0004, alias);
  1360 }
  1506 }
  1361 
  1507 
  1362 /*****************************************************************************/
  1508 /*****************************************************************************/
  1363 
  1509 
       
  1510 /**
       
  1511    \return 0 in case of success, else < 0
       
  1512    \ingroup RealtimeInterface
       
  1513 */
       
  1514 
       
  1515 int ecrt_slave_field_size(ec_slave_t *slave, /**< EtherCAT slave */
       
  1516                           const char *field_name, /**< data field name */
       
  1517                           unsigned int field_index, /**< data field index */
       
  1518                           size_t size /**< new data field size */
       
  1519                           )
       
  1520 {
       
  1521     unsigned int i, j, field_counter;
       
  1522     const ec_sync_t *sync;
       
  1523     const ec_field_t *field;
       
  1524     ec_varsize_t *var;
       
  1525 
       
  1526     if (!slave->type) {
       
  1527         EC_ERR("Slave %i has no type information!\n", slave->ring_position);
       
  1528         return -1;
       
  1529     }
       
  1530 
       
  1531     field_counter = 0;
       
  1532     for (i = 0; (sync = slave->type->sync_managers[i]); i++) {
       
  1533         for (j = 0; (field = sync->fields[j]); j++) {
       
  1534             if (!strcmp(field->name, field_name)) {
       
  1535                 if (field_counter++ == field_index) {
       
  1536                     // is the size of this field variable?
       
  1537                     if (field->size) {
       
  1538                         EC_ERR("Field \"%s\"[%i] of slave %i has no variable"
       
  1539                                " size!\n", field->name, field_index,
       
  1540                                slave->ring_position);
       
  1541                         return -1;
       
  1542                     }
       
  1543                     // does a size specification already exist?
       
  1544                     list_for_each_entry(var, &slave->varsize_fields, list) {
       
  1545                         if (var->field == field) {
       
  1546                             EC_WARN("Resizing field \"%s\"[%i] of slave %i.\n",
       
  1547                                     field->name, field_index,
       
  1548                                     slave->ring_position);
       
  1549                             var->size = size;
       
  1550                             return 0;
       
  1551                         }
       
  1552                     }
       
  1553                     // create a new size specification...
       
  1554                     if (!(var = kmalloc(sizeof(ec_varsize_t), GFP_KERNEL))) {
       
  1555                         EC_ERR("Failed to allocate memory for varsize_t!\n");
       
  1556                         return -1;
       
  1557                     }
       
  1558                     var->field = field;
       
  1559                     var->size = size;
       
  1560                     list_add_tail(&var->list, &slave->varsize_fields);
       
  1561                     return 0;
       
  1562                 }
       
  1563             }
       
  1564         }
       
  1565     }
       
  1566 
       
  1567     EC_ERR("Slave %i (\"%s %s\") has no field \"%s\"[%i]!\n",
       
  1568            slave->ring_position, slave->type->vendor_name,
       
  1569            slave->type->product_name, field_name, field_index);
       
  1570     return -1;
       
  1571 }
       
  1572 
       
  1573 /*****************************************************************************/
       
  1574 
  1364 /**< \cond */
  1575 /**< \cond */
  1365 
  1576 
  1366 EXPORT_SYMBOL(ecrt_slave_write_alias);
  1577 EXPORT_SYMBOL(ecrt_slave_write_alias);
       
  1578 EXPORT_SYMBOL(ecrt_slave_field_size);
  1367 
  1579 
  1368 /**< \endcond */
  1580 /**< \endcond */
  1369 
  1581 
  1370 /*****************************************************************************/
  1582 /*****************************************************************************/