Bugfix: Crash after failing to fetch SDO dictionary.
authorFlorian Pose <fp@igh-essen.com>
Wed, 05 Apr 2006 09:50:57 +0000
changeset 157 37c6dd0ff0b1
parent 156 43d7d714679f
child 158 363412c9304e
Bugfix: Crash after failing to fetch SDO dictionary.
master/canopen.c
master/slave.c
--- a/master/canopen.c	Wed Apr 05 09:04:29 2006 +0000
+++ b/master/canopen.c	Wed Apr 05 09:50:57 2006 +0000
@@ -64,7 +64,7 @@
 
     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
         EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
-        EC_ERR("SDO upload of 0x%04X:%X aborted on slave %i.\n",
+        EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
                sdo_index, sdo_subindex, slave->ring_position);
         ec_canopen_abort_msg(EC_READ_U32(data + 6));
         return -1;
@@ -74,8 +74,11 @@
         EC_READ_U8 (data + 2) >> 5 != 0x2 || // Upload response
         EC_READ_U16(data + 3) != sdo_index || // Index
         EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex
+        EC_ERR("SDO upload 0x%04X:%X failed:\n",
+               sdo_index, sdo_subindex, slave->ring_position);
         EC_ERR("Invalid SDO upload response at slave %i!\n",
                slave->ring_position);
+        ec_print_data(data, rec_size);
         return -1;
     }
 
@@ -121,9 +124,8 @@
 
     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
         EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
-        EC_ERR("SDO download of 0x%04X:%X (%i bytes) aborted on!"
-               " slave %i.\n", sdo_index, sdo_subindex, size,
-               slave->ring_position);
+        EC_ERR("SDO download 0x%04X:%X (%i bytes) aborted on slave %i.\n",
+               sdo_index, sdo_subindex, size, slave->ring_position);
         ec_canopen_abort_msg(EC_READ_U32(data + 6));
         return -1;
     }
@@ -131,10 +133,12 @@
     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
         EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
         EC_READ_U16(data + 3) != sdo_index || // Index
-        EC_READ_U8 (data + 5) != sdo_subindex) // Subindex
-    {
+        EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex
+        EC_ERR("SDO download 0x%04X:%X (%i bytes) failed:\n",
+               sdo_index, sdo_subindex, size);
         EC_ERR("Invalid SDO download response at slave %i!\n",
                slave->ring_position);
+        ec_print_data(data, rec_size);
         return -1;
     }
 
@@ -170,7 +174,7 @@
 
     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
         EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
-        EC_ERR("SDO upload of 0x%04X:%X aborted on slave %i.\n",
+        EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
                sdo_index, sdo_subindex, slave->ring_position);
         ec_canopen_abort_msg(EC_READ_U32(data + 6));
         return -1;
@@ -180,13 +184,16 @@
         EC_READ_U8 (data + 2) >> 5 != 0x2 || // Initiate upload response
         EC_READ_U16(data + 3) != sdo_index || // Index
         EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex
+        EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
         EC_ERR("Invalid SDO upload response at slave %i!\n",
                slave->ring_position);
+        ec_print_data(data, rec_size);
         return -1;
     }
 
     if (rec_size < 10) {
         EC_ERR("Received currupted SDO upload response!\n");
+        ec_print_data(data, rec_size);
         return -1;
     }
 
@@ -198,14 +205,12 @@
 
     data_size = rec_size - 10;
 
-    if (data_size == complete_size) {
-        memcpy(target, data + 10, data_size);
-    }
-    else {
-        EC_ERR("SDO data incomplete.\n");
-        return -1;
-    }
-
+    if (data_size != complete_size) {
+        EC_ERR("SDO data incomplete - Fragmenting not implemented.\n");
+        return -1;
+    }
+
+    memcpy(target, data + 10, data_size);
     return 0;
 }
 
@@ -233,8 +238,7 @@
     EC_WRITE_U16(data + 6, 0x0001); // Deliver all SDOs!
 
     if (unlikely(ec_master_simple_io(slave->master, &slave->mbox_command))) {
-        EC_ERR("Mailbox checking failed on slave %i!\n",
-               slave->ring_position);
+        EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position);
         return -1;
     }
 
@@ -254,11 +258,13 @@
             (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
             EC_ERR("Invalid SDO list response at slave %i!\n",
                    slave->ring_position);
+            ec_print_data(data, rec_size);
             return -1;
         }
 
         if (rec_size < 8) {
             EC_ERR("Invalid data size!\n");
+            ec_print_data(data, rec_size);
             return -1;
         }
 
@@ -271,11 +277,18 @@
                 EC_ERR("Failed to allocate memory for SDO!\n");
                 return -1;
             }
+
+            // Initialize SDO object
             sdo->index = sdo_index;
+            sdo->type = 0x0000;
+            sdo->features = 0x00;
             sdo->name = NULL;
+            INIT_LIST_HEAD(&sdo->entries);
+
             list_add_tail(&sdo->list, &slave->sdo_dictionary);
         }
-    } while (EC_READ_U8(data + 2) & 0x80);
+    }
+    while (EC_READ_U8(data + 2) & 0x80);
 
     // Alle Beschreibungen laden
     if (ec_slave_fetch_sdo_descriptions(slave)) return -1;
@@ -321,17 +334,18 @@
             EC_ERR("Invalid object description response at slave %i while"
                    " fetching SDO 0x%04X!\n", slave->ring_position,
                    sdo->index);
+            ec_print_data(data, rec_size);
             return -1;
         }
 
         if (rec_size < 12) {
             EC_ERR("Invalid data size!\n");
+            ec_print_data(data, rec_size);
             return -1;
         }
 
         sdo->type = EC_READ_U16(data + 8);
         sdo->features = EC_READ_U8(data + 11);
-        INIT_LIST_HEAD(&sdo->entries);
 
         name_size = rec_size - 12;
         if (name_size) {
@@ -404,11 +418,13 @@
             EC_ERR("Invalid entry description response at slave %i while"
                    " fetching SDO 0x%04X:%i!\n", slave->ring_position,
                    sdo->index, i);
+            ec_print_data(data, rec_size);
             return -1;
         }
 
         if (rec_size < 16) {
             EC_ERR("Invalid data size!\n");
+            ec_print_data(data, rec_size);
             return -1;
         }
 
@@ -458,6 +474,7 @@
             return;
         }
     }
+
     EC_ERR("Unknown SDO abort code 0x%08X.\n", abort_code);
 }
 
--- a/master/slave.c	Wed Apr 05 09:04:29 2006 +0000
+++ b/master/slave.c	Wed Apr 05 09:50:57 2006 +0000
@@ -88,8 +88,8 @@
     ec_eeprom_sync_t *sync, *next_sync;
     ec_eeprom_pdo_t *pdo, *next_pdo;
     ec_eeprom_pdo_entry_t *entry, *next_ent;
-    //ec_sdo_t *sdo, *next_sdo;
-    //ec_sdo_entry_t *en, *next_en;
+    ec_sdo_t *sdo, *next_sdo;
+    ec_sdo_entry_t *en, *next_en;
 
     // Alle Strings freigeben
     list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
@@ -122,7 +122,6 @@
     if (slave->eeprom_group) kfree(slave->eeprom_group);
     if (slave->eeprom_desc) kfree(slave->eeprom_desc);
 
-#if 0
     // Alle SDOs freigeben
     list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
         list_del(&sdo->list);
@@ -136,7 +135,6 @@
     }
 
     ec_command_clear(&slave->mbox_command);
-#endif
 }
 
 /*****************************************************************************/
@@ -908,54 +906,41 @@
     ec_sdo_entry_t *sdo_entry;
     int first, i;
 
-    if (!verbosity) {
-        if (slave->type) {
-            EC_INFO("%2i) %s %s: %s\n", slave->ring_position,
-                    slave->type->vendor_name, slave->type->product_name,
-                    slave->type->description);
-        }
-        else {
-            EC_INFO("%2i) UNKNOWN SLAVE: 0x%08X 0x%08X\n",
-                    slave->ring_position, slave->sii_vendor_id,
-                    slave->sii_product_code);
-        }
-        return;
-    }
-
-    EC_INFO("x-- EtherCAT slave information ---------------\n");
-
     if (slave->type) {
-        EC_INFO("| Vendor \"%s\", Product \"%s\": %s\n",
+        EC_INFO("%i) %s %s: %s\n", slave->ring_position,
                 slave->type->vendor_name, slave->type->product_name,
                 slave->type->description);
     }
     else {
-        EC_INFO("| *** This slave has no type information! ***\n");
-    }
-
-    EC_INFO("| Ring position: %i, Station address: 0x%04X\n",
-            slave->ring_position, slave->station_address);
-
-    EC_INFO("| Data link status:\n");
+        EC_INFO("%i) UNKNOWN SLAVE: vendor 0x%08X, product 0x%08X\n",
+                slave->ring_position, slave->sii_vendor_id,
+                slave->sii_product_code);
+    }
+
+    if (!verbosity) return;
+
+    EC_INFO("  Station address: 0x%04X\n", slave->station_address);
+
+    EC_INFO("  Data link status:\n");
     for (i = 0; i < 2; i++) {
-        EC_INFO("|   Port %i: link %s, loop %s, %s\n", i,
+        EC_INFO("    Port %i: link %s, loop %s, comm %s\n", i,
                 slave->dl_status_link[i] ? "up" : "down",
                 slave->dl_status_loop[i] ? "closed" : "open",
-                slave->dl_status_comm[i] ? "comm. establ." : "no comm.");
-    }
-
-    EC_INFO("| Base information:\n");
-    EC_INFO("|   Type %u, Revision %i, Build %i\n",
+                slave->dl_status_comm[i] ? "up" : "down");
+    }
+
+    EC_INFO("  Base information:\n");
+    EC_INFO("    Type %u, revision %i, build %i\n",
             slave->base_type, slave->base_revision, slave->base_build);
-    EC_INFO("|   Supported FMMUs: %i, Sync managers: %i\n",
+    EC_INFO("    Supported FMMUs: %i, sync managers: %i\n",
             slave->base_fmmu_count, slave->base_sync_count);
 
     if (slave->sii_mailbox_protocols) {
-        EC_INFO("| Mailbox communication:\n");
-        EC_INFO("|   RX mailbox: 0x%04X/%i, TX mailbox: 0x%04X/%i\n",
+        EC_INFO("  Mailbox communication:\n");
+        EC_INFO("    RX mailbox: 0x%04X/%i, TX mailbox: 0x%04X/%i\n",
                 slave->sii_rx_mailbox_offset, slave->sii_rx_mailbox_size,
                 slave->sii_tx_mailbox_offset, slave->sii_tx_mailbox_size);
-        EC_INFO("|   Supported protocols: ");
+        EC_INFO("    Supported protocols: ");
 
         first = 1;
         if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
@@ -989,28 +974,28 @@
         printk("\n");
     }
 
-    EC_INFO("| EEPROM data:\n");
+    EC_INFO("  EEPROM data:\n");
 
     if (slave->sii_alias)
-        EC_INFO("|   Configured station alias: 0x%04X (%i)\n",
+        EC_INFO("    Configured station alias: 0x%04X (%i)\n",
                 slave->sii_alias, slave->sii_alias);
 
-    EC_INFO("|   Vendor-ID: 0x%08X, Product code: 0x%08X\n",
+    EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
             slave->sii_vendor_id, slave->sii_product_code);
-    EC_INFO("|   Revision number: 0x%08X, Serial number: 0x%08X\n",
+    EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
             slave->sii_revision_number, slave->sii_serial_number);
 
     if (slave->eeprom_name)
-        EC_INFO("|   Name: %s\n", slave->eeprom_name);
+        EC_INFO("    Name: %s\n", slave->eeprom_name);
     if (slave->eeprom_group)
-        EC_INFO("|   Group: %s\n", slave->eeprom_group);
+        EC_INFO("    Group: %s\n", slave->eeprom_group);
     if (slave->eeprom_desc)
-        EC_INFO("|   Description: %s\n", slave->eeprom_desc);
+        EC_INFO("    Description: %s\n", slave->eeprom_desc);
 
     if (!list_empty(&slave->eeprom_syncs)) {
-        EC_INFO("|   Sync-Managers:\n");
+        EC_INFO("    Sync-Managers:\n");
         list_for_each_entry(sync, &slave->eeprom_syncs, list) {
-            EC_INFO("|     %i: 0x%04X, length %i, control 0x%02X, %s\n",
+            EC_INFO("      %i: 0x%04X, length %i, control 0x%02X, %s\n",
                     sync->index, sync->physical_start_address,
                     sync->length, sync->control_register,
                     sync->enable ? "enable" : "disable");
@@ -1018,39 +1003,36 @@
     }
 
     list_for_each_entry(pdo, &slave->eeprom_pdos, list) {
-        EC_INFO("|   %s \"%s\" (0x%04X), -> Sync-Manager %i\n",
+        EC_INFO("    %s \"%s\" (0x%04X), -> Sync-Manager %i\n",
                 pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
                 pdo->name ? pdo->name : "???",
                 pdo->index, pdo->sync_manager);
 
         list_for_each_entry(pdo_entry, &pdo->entries, list) {
-            EC_INFO("|     \"%s\" 0x%04X:%X, %i Bit\n",
+            EC_INFO("      \"%s\" 0x%04X:%X, %i Bit\n",
                     pdo_entry->name ? pdo_entry->name : "???",
                     pdo_entry->index, pdo_entry->subindex,
                     pdo_entry->bit_length);
         }
     }
 
-    if (verbosity > 1) // sehr geschwätzig
-    {
-        if (!list_empty(&slave->sdo_dictionary)) {
-            EC_INFO("|   SDO-Dictionary:\n");
-            list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
-                EC_INFO("|     0x%04X \"%s\"\n", sdo->index,
-                        sdo->name ? sdo->name : "");
-                EC_INFO("|       Type 0x%04X, features: 0x%02X\n",
-                        sdo->type, sdo->features);
-                list_for_each_entry(sdo_entry, &sdo->entries, list) {
-                    EC_INFO("|       0x%04X:%i \"%s\", type 0x%04X, %i bits\n",
-                            sdo->index, sdo_entry->subindex,
-                            sdo_entry->name ? sdo_entry->name : "",
-                            sdo_entry->data_type, sdo_entry->bit_length);
-                }
+    if (verbosity < 2) return;
+
+    if (!list_empty(&slave->sdo_dictionary)) {
+        EC_INFO("    SDO-Dictionary:\n");
+        list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
+            EC_INFO("      0x%04X \"%s\"\n", sdo->index,
+                    sdo->name ? sdo->name : "");
+            EC_INFO("        Type 0x%04X, features: 0x%02X\n",
+                    sdo->type, sdo->features);
+            list_for_each_entry(sdo_entry, &sdo->entries, list) {
+                EC_INFO("        0x%04X:%i \"%s\", type 0x%04X, %i bits\n",
+                        sdo->index, sdo_entry->subindex,
+                        sdo_entry->name ? sdo_entry->name : "",
+                        sdo_entry->data_type, sdo_entry->bit_length);
             }
         }
     }
-
-    EC_INFO("x---------------------------------------------\n");
 }
 
 /*****************************************************************************/