master/slave.c
changeset 772 6c29e74d6763
parent 765 5eaf2af36427
child 784 0a0994fdafb8
equal deleted inserted replaced
771:9946a675f86e 772:6c29e74d6763
   686 
   686 
   687 /**
   687 /**
   688    Outputs all information about a certain slave.
   688    Outputs all information about a certain slave.
   689 */
   689 */
   690 
   690 
   691 size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
   691 ssize_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
   692                      char *buffer /**< Output buffer */
   692         char *buffer /**< Output buffer */
   693                      )
   693         )
   694 {
   694 {
   695     off_t off = 0;
       
   696     ec_sync_t *sync;
   695     ec_sync_t *sync;
   697     ec_pdo_t *pdo;
   696     ec_pdo_t *pdo;
   698     ec_pdo_entry_t *pdo_entry;
   697     ec_pdo_entry_t *pdo_entry;
   699     int first, i;
   698     int first, i;
   700     ec_sdo_data_t *sdodata;
   699     ec_sdo_data_t *sdodata;
   701     char str[20];
   700     char str[20];
   702 
   701     char *large_buffer, *buf;
   703     off += sprintf(buffer + off, "Ring position: %i\n",
   702     unsigned int size;
       
   703 
       
   704     if (!(large_buffer = (char *) kmalloc(PAGE_SIZE * 2, GFP_KERNEL))) {
       
   705         return -ENOMEM;
       
   706     }
       
   707 
       
   708     buf = large_buffer;
       
   709 
       
   710     buf += sprintf(buf, "Ring position: %i\n",
   704                    slave->ring_position);
   711                    slave->ring_position);
   705     off += sprintf(buffer + off, "State: ");
   712     buf += sprintf(buf, "State: ");
   706     off += ec_state_string(slave->current_state, buffer + off);
   713     buf += ec_state_string(slave->current_state, buf);
   707     off += sprintf(buffer + off, " (");
   714     buf += sprintf(buf, " (");
   708     off += ec_state_string(slave->requested_state, buffer + off);
   715     buf += ec_state_string(slave->requested_state, buf);
   709     off += sprintf(buffer + off, ")\n");
   716     buf += sprintf(buf, ")\n");
   710     off += sprintf(buffer + off, "Flags: %s, %s\n\n",
   717     buf += sprintf(buf, "Flags: %s, %s\n\n",
   711             slave->online_state == EC_SLAVE_ONLINE ? "online" : "OFFLINE",
   718             slave->online_state == EC_SLAVE_ONLINE ? "online" : "OFFLINE",
   712             slave->error_flag ? "ERROR" : "ok");
   719             slave->error_flag ? "ERROR" : "ok");
   713 
   720 
   714     off += sprintf(buffer + off, "Data link status:\n");
   721     buf += sprintf(buf, "Data link status:\n");
   715     for (i = 0; i < 4; i++) {
   722     for (i = 0; i < 4; i++) {
   716         off += sprintf(buffer + off, "  Port %u: Phy %u (",
   723         buf += sprintf(buf, "  Port %u: Phy %u (",
   717                 i, slave->sii_physical_layer[i]);
   724                 i, slave->sii_physical_layer[i]);
   718         switch (slave->sii_physical_layer[i]) {
   725         switch (slave->sii_physical_layer[i]) {
   719             case 0x00:
   726             case 0x00:
   720                 off += sprintf(buffer + off, "EBUS");
   727                 buf += sprintf(buf, "EBUS");
   721                 break;
   728                 break;
   722             case 0x01:
   729             case 0x01:
   723                 off += sprintf(buffer + off, "100BASE-TX");
   730                 buf += sprintf(buf, "100BASE-TX");
   724                 break;
   731                 break;
   725             case 0x02:
   732             case 0x02:
   726                 off += sprintf(buffer + off, "100BASE-FX");
   733                 buf += sprintf(buf, "100BASE-FX");
   727                 break;
   734                 break;
   728             default:
   735             default:
   729                 off += sprintf(buffer + off, "unknown");
   736                 buf += sprintf(buf, "unknown");
   730         }
   737         }
   731         off += sprintf(buffer + off, "), Link %s, Loop %s, %s\n",
   738         buf += sprintf(buf, "), Link %s, Loop %s, %s\n",
   732                        slave->dl_link[i] ? "up" : "down",
   739                        slave->dl_link[i] ? "up" : "down",
   733                        slave->dl_loop[i] ? "closed" : "open",
   740                        slave->dl_loop[i] ? "closed" : "open",
   734                        slave->dl_signal[i] ? "Signal detected" : "No signal");
   741                        slave->dl_signal[i] ? "Signal detected" : "No signal");
   735     }
   742     }
   736     off += sprintf(buffer + off, "\n");
   743     buf += sprintf(buf, "\n");
   737 
   744 
   738     if (slave->sii_alias)
   745     if (slave->sii_alias)
   739         off += sprintf(buffer + off, "Configured station alias:"
   746         buf += sprintf(buf, "Configured station alias:"
   740                        " 0x%04X (%i)\n\n", slave->sii_alias, slave->sii_alias);
   747                        " 0x%04X (%i)\n\n", slave->sii_alias, slave->sii_alias);
   741 
   748 
   742     off += sprintf(buffer + off, "Identity:\n");
   749     buf += sprintf(buf, "Identity:\n");
   743     off += sprintf(buffer + off, "  Vendor ID: 0x%08X (%u)\n",
   750     buf += sprintf(buf, "  Vendor ID: 0x%08X (%u)\n",
   744                    slave->sii_vendor_id, slave->sii_vendor_id);
   751                    slave->sii_vendor_id, slave->sii_vendor_id);
   745     off += sprintf(buffer + off, "  Product code: 0x%08X (%u)\n",
   752     buf += sprintf(buf, "  Product code: 0x%08X (%u)\n",
   746                    slave->sii_product_code, slave->sii_product_code);
   753                    slave->sii_product_code, slave->sii_product_code);
   747     off += sprintf(buffer + off, "  Revision number: 0x%08X (%u)\n",
   754     buf += sprintf(buf, "  Revision number: 0x%08X (%u)\n",
   748                    slave->sii_revision_number, slave->sii_revision_number);
   755                    slave->sii_revision_number, slave->sii_revision_number);
   749     off += sprintf(buffer + off, "  Serial number: 0x%08X (%u)\n\n",
   756     buf += sprintf(buf, "  Serial number: 0x%08X (%u)\n\n",
   750                    slave->sii_serial_number, slave->sii_serial_number);
   757                    slave->sii_serial_number, slave->sii_serial_number);
   751 
   758 
   752     if (slave->sii_mailbox_protocols) {
   759     if (slave->sii_mailbox_protocols) {
   753         off += sprintf(buffer + off, "Mailboxes:\n");
   760         buf += sprintf(buf, "Mailboxes:\n");
   754         off += sprintf(buffer + off, "  RX: 0x%04X/%u, TX: 0x%04X/%u\n",
   761         buf += sprintf(buf, "  RX: 0x%04X/%u, TX: 0x%04X/%u\n",
   755                 slave->sii_rx_mailbox_offset, slave->sii_rx_mailbox_size,
   762                 slave->sii_rx_mailbox_offset, slave->sii_rx_mailbox_size,
   756                 slave->sii_tx_mailbox_offset, slave->sii_tx_mailbox_size);
   763                 slave->sii_tx_mailbox_offset, slave->sii_tx_mailbox_size);
   757         off += sprintf(buffer + off, "  Supported protocols: ");
   764         buf += sprintf(buf, "  Supported protocols: ");
   758 
   765 
   759         first = 1;
   766         first = 1;
   760         if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
   767         if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
   761             off += sprintf(buffer + off, "AoE");
   768             buf += sprintf(buf, "AoE");
   762             first = 0;
   769             first = 0;
   763         }
   770         }
   764         if (slave->sii_mailbox_protocols & EC_MBOX_EOE) {
   771         if (slave->sii_mailbox_protocols & EC_MBOX_EOE) {
   765             if (!first) off += sprintf(buffer + off, ", ");
   772             if (!first) buf += sprintf(buf, ", ");
   766             off += sprintf(buffer + off, "EoE");
   773             buf += sprintf(buf, "EoE");
   767             first = 0;
   774             first = 0;
   768         }
   775         }
   769         if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
   776         if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
   770             if (!first) off += sprintf(buffer + off, ", ");
   777             if (!first) buf += sprintf(buf, ", ");
   771             off += sprintf(buffer + off, "CoE");
   778             buf += sprintf(buf, "CoE");
   772             first = 0;
   779             first = 0;
   773         }
   780         }
   774         if (slave->sii_mailbox_protocols & EC_MBOX_FOE) {
   781         if (slave->sii_mailbox_protocols & EC_MBOX_FOE) {
   775             if (!first) off += sprintf(buffer + off, ", ");
   782             if (!first) buf += sprintf(buf, ", ");
   776             off += sprintf(buffer + off, "FoE");
   783             buf += sprintf(buf, "FoE");
   777             first = 0;
   784             first = 0;
   778         }
   785         }
   779         if (slave->sii_mailbox_protocols & EC_MBOX_SOE) {
   786         if (slave->sii_mailbox_protocols & EC_MBOX_SOE) {
   780             if (!first) off += sprintf(buffer + off, ", ");
   787             if (!first) buf += sprintf(buf, ", ");
   781             off += sprintf(buffer + off, "SoE");
   788             buf += sprintf(buf, "SoE");
   782             first = 0;
   789             first = 0;
   783         }
   790         }
   784         if (slave->sii_mailbox_protocols & EC_MBOX_VOE) {
   791         if (slave->sii_mailbox_protocols & EC_MBOX_VOE) {
   785             if (!first) off += sprintf(buffer + off, ", ");
   792             if (!first) buf += sprintf(buf, ", ");
   786             off += sprintf(buffer + off, "VoE");
   793             buf += sprintf(buf, "VoE");
   787         }
   794         }
   788         off += sprintf(buffer + off, "\n\n");
   795         buf += sprintf(buf, "\n\n");
   789     }
   796     }
   790 
   797 
   791     off += sprintf(buffer + off, "Current consumption: %i mA\n\n",
   798     buf += sprintf(buf, "Current consumption: %i mA\n\n",
   792             slave->sii_current_on_ebus);
   799             slave->sii_current_on_ebus);
   793 
   800 
   794     if (slave->sii_group || slave->sii_image || slave->sii_order
   801     if (slave->sii_group || slave->sii_image || slave->sii_order
   795             || slave->sii_name) {
   802             || slave->sii_name) {
   796         off += sprintf(buffer + off, "General:\n");
   803         buf += sprintf(buf, "General:\n");
   797 
   804 
   798         if (slave->sii_group)
   805         if (slave->sii_group)
   799             off += sprintf(buffer + off, "  Group: %s\n", slave->sii_group);
   806             buf += sprintf(buf, "  Group: %s\n", slave->sii_group);
   800         if (slave->sii_image)
   807         if (slave->sii_image)
   801             off += sprintf(buffer + off, "  Image: %s\n", slave->sii_image);
   808             buf += sprintf(buf, "  Image: %s\n", slave->sii_image);
   802         if (slave->sii_order)
   809         if (slave->sii_order)
   803             off += sprintf(buffer + off, "  Order number: %s\n",
   810             buf += sprintf(buf, "  Order number: %s\n",
   804                     slave->sii_order);
   811                     slave->sii_order);
   805         if (slave->sii_name)
   812         if (slave->sii_name)
   806             off += sprintf(buffer + off, "  Name: %s\n", slave->sii_name);
   813             buf += sprintf(buf, "  Name: %s\n", slave->sii_name);
   807         off += sprintf(buffer + off, "\n");
   814         buf += sprintf(buf, "\n");
   808     }
   815     }
   809 
   816 
   810     if (slave->sii_sync_count) {
   817     if (slave->sii_sync_count) {
   811         off += sprintf(buffer + off, "Sync managers / PDO mapping:\n");
   818         buf += sprintf(buf, "Sync managers / PDO mapping:\n");
   812 
   819 
   813         for (i = 0; i < slave->sii_sync_count; i++) {
   820         for (i = 0; i < slave->sii_sync_count; i++) {
   814             sync = &slave->sii_syncs[i];
   821             sync = &slave->sii_syncs[i];
   815             off += sprintf(buffer + off,
   822             buf += sprintf(buf,
   816                     "  SM%u: addr 0x%04X, size %i, control 0x%02X, %s\n",
   823                     "  SM%u: addr 0x%04X, size %i, control 0x%02X, %s\n",
   817                     sync->index, sync->physical_start_address,
   824                     sync->index, sync->physical_start_address,
   818                     ec_sync_size(sync), sync->control_register,
   825                     ec_sync_size(sync), sync->control_register,
   819                     sync->enable ? "enable" : "disable");
   826                     sync->enable ? "enable" : "disable");
   820 
   827 
   821             if (list_empty(&sync->pdos)) {
   828             if (list_empty(&sync->pdos)) {
   822                 off += sprintf(buffer + off, "    No PDOs mapped.\n");
   829                 buf += sprintf(buf, "    No PDOs mapped.\n");
   823             } else if (sync->mapping_source != EC_SYNC_MAPPING_NONE) {
   830             } else if (sync->mapping_source != EC_SYNC_MAPPING_NONE) {
   824                 off += sprintf(buffer + off,
   831                 buf += sprintf(buf,
   825                         "    PDO mapping information from %s.\n",
   832                         "    PDO mapping information from %s.\n",
   826                         sync->mapping_source == EC_SYNC_MAPPING_SII
   833                         sync->mapping_source == EC_SYNC_MAPPING_SII
   827                         ? "SII" : "CoE");
   834                         ? "SII" : "CoE");
   828             }
   835             }
   829 
   836 
   830             list_for_each_entry(pdo, &sync->pdos, list) {
   837             list_for_each_entry(pdo, &sync->pdos, list) {
   831                 off += sprintf(buffer + off, "    %s 0x%04X \"%s\"\n",
   838                 buf += sprintf(buf, "    %s 0x%04X \"%s\"\n",
   832                         pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   839                         pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   833                         pdo->index, pdo->name ? pdo->name : "???");
   840                         pdo->index, pdo->name ? pdo->name : "???");
   834 
   841 
   835                 list_for_each_entry(pdo_entry, &pdo->entries, list) {
   842                 list_for_each_entry(pdo_entry, &pdo->entries, list) {
   836                     off += sprintf(buffer + off,
   843                     buf += sprintf(buf,
   837                             "      0x%04X:%X \"%s\", %i bit\n",
   844                             "      0x%04X:%X \"%s\", %i bit\n",
   838                             pdo_entry->index, pdo_entry->subindex,
   845                             pdo_entry->index, pdo_entry->subindex,
   839                             pdo_entry->name ? pdo_entry->name : "???",
   846                             pdo_entry->name ? pdo_entry->name : "???",
   840                             pdo_entry->bit_length);
   847                             pdo_entry->bit_length);
   841                 }
   848                 }
   842             }
   849             }
   843         }
   850         }
   844         off += sprintf(buffer + off, "\n");
   851         buf += sprintf(buf, "\n");
   845     }
   852     }
   846 
   853 
   847     // type-cast to avoid warnings on some compilers
   854     // type-cast to avoid warnings on some compilers
   848     if (!list_empty((struct list_head *) &slave->sii_pdos)) {
   855     if (!list_empty((struct list_head *) &slave->sii_pdos)) {
   849         off += sprintf(buffer + off, "Available PDOs from SII:\n");
   856         buf += sprintf(buf, "Available PDOs from SII:\n");
   850 
   857 
   851         list_for_each_entry(pdo, &slave->sii_pdos, list) {
   858         list_for_each_entry(pdo, &slave->sii_pdos, list) {
   852             off += sprintf(buffer + off, "  %s 0x%04X \"%s\"",
   859             buf += sprintf(buf, "  %s 0x%04X \"%s\"",
   853                     pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   860                     pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
   854                     pdo->index, pdo->name ? pdo->name : "???");
   861                     pdo->index, pdo->name ? pdo->name : "???");
   855             if (pdo->sync_index >= 0)
   862             if (pdo->sync_index >= 0)
   856                 off += sprintf(buffer + off, ", default mapping: SM%u.\n",
   863                 buf += sprintf(buf, ", default mapping: SM%u.\n",
   857                         pdo->sync_index);
   864                         pdo->sync_index);
   858             else
   865             else
   859                 off += sprintf(buffer + off, ", no default mapping.\n");
   866                 buf += sprintf(buf, ", no default mapping.\n");
   860 
   867 
   861             list_for_each_entry(pdo_entry, &pdo->entries, list) {
   868             list_for_each_entry(pdo_entry, &pdo->entries, list) {
   862                 off += sprintf(buffer + off, "    0x%04X:%X \"%s\", %i bit\n",
   869                 buf += sprintf(buf, "    0x%04X:%X \"%s\", %i bit\n",
   863                         pdo_entry->index, pdo_entry->subindex,
   870                         pdo_entry->index, pdo_entry->subindex,
   864                         pdo_entry->name ? pdo_entry->name : "???",
   871                         pdo_entry->name ? pdo_entry->name : "???",
   865                         pdo_entry->bit_length);
   872                         pdo_entry->bit_length);
   866             }
   873             }
   867         }
   874         }
   868         off += sprintf(buffer + off, "\n");
   875         buf += sprintf(buf, "\n");
   869     }
   876     }
   870 
   877 
   871     // type-cast to avoid warnings on some compilers
   878     // type-cast to avoid warnings on some compilers
   872     if (!list_empty((struct list_head *) &slave->sdo_confs)) {
   879     if (!list_empty((struct list_head *) &slave->sdo_confs)) {
   873         off += sprintf(buffer + off, "SDO configurations:\n");
   880         buf += sprintf(buf, "SDO configurations:\n");
   874 
   881 
   875         list_for_each_entry(sdodata, &slave->sdo_confs, list) {
   882         list_for_each_entry(sdodata, &slave->sdo_confs, list) {
   876             switch (sdodata->size) {
   883             switch (sdodata->size) {
   877                 case 1: sprintf(str, "%i", EC_READ_U8(sdodata->data)); break;
   884                 case 1: sprintf(str, "%i", EC_READ_U8(sdodata->data)); break;
   878                 case 2: sprintf(str, "%i", EC_READ_U16(sdodata->data)); break;
   885                 case 2: sprintf(str, "%i", EC_READ_U16(sdodata->data)); break;
   879                 case 4: sprintf(str, "%i", EC_READ_U32(sdodata->data)); break;
   886                 case 4: sprintf(str, "%i", EC_READ_U32(sdodata->data)); break;
   880                 default: sprintf(str, "(invalid size)"); break;
   887                 default: sprintf(str, "(invalid size)"); break;
   881             }
   888             }
   882             off += sprintf(buffer + off, "  0x%04X:%-3i -> %s\n",
   889             buf += sprintf(buf, "  0x%04X:%-3i -> %s\n",
   883                     sdodata->index, sdodata->subindex, str);
   890                     sdodata->index, sdodata->subindex, str);
   884         }
   891         }
   885         off += sprintf(buffer + off, "\n");
   892         buf += sprintf(buf, "\n");
   886     }
   893     }
   887 
   894 
   888     return off;
   895     size = buf - large_buffer;
       
   896     if (size >= PAGE_SIZE) {
       
   897         const char trunc[] = "\n---TRUNCATED---\n";
       
   898         unsigned int len = strlen(trunc);
       
   899         memcpy(large_buffer + PAGE_SIZE - len, trunc, len);
       
   900     }
       
   901 
       
   902     size = min(size, (unsigned int) PAGE_SIZE);
       
   903     memcpy(buffer, large_buffer, size);
       
   904     kfree(large_buffer);
       
   905     return size;
   889 }
   906 }
   890 
   907 
   891 /*****************************************************************************/
   908 /*****************************************************************************/
   892 
   909 
   893 /**
   910 /**