master/fsm.c
changeset 266 0234b0c26c52
parent 262 636d43737371
child 269 a03be9a6fed6
equal deleted inserted replaced
265:fb965f033bb3 266:0234b0c26c52
    42 #include "fsm.h"
    42 #include "fsm.h"
    43 #include "master.h"
    43 #include "master.h"
    44 
    44 
    45 /*****************************************************************************/
    45 /*****************************************************************************/
    46 
    46 
    47 /**
       
    48    Size of memory to allocate while reading categories.
       
    49 */
       
    50 
       
    51 #define EC_CAT_MEM 0x100
       
    52 
       
    53 /*****************************************************************************/
       
    54 
       
    55 const ec_code_msg_t al_status_messages[];
    47 const ec_code_msg_t al_status_messages[];
    56 
    48 
    57 /*****************************************************************************/
    49 /*****************************************************************************/
    58 
    50 
    59 void ec_fsm_master_start(ec_fsm_t *);
    51 void ec_fsm_master_start(ec_fsm_t *);
    69 
    61 
    70 void ec_fsm_slave_start_reading(ec_fsm_t *);
    62 void ec_fsm_slave_start_reading(ec_fsm_t *);
    71 void ec_fsm_slave_read_status(ec_fsm_t *);
    63 void ec_fsm_slave_read_status(ec_fsm_t *);
    72 void ec_fsm_slave_read_base(ec_fsm_t *);
    64 void ec_fsm_slave_read_base(ec_fsm_t *);
    73 void ec_fsm_slave_read_dl(ec_fsm_t *);
    65 void ec_fsm_slave_read_dl(ec_fsm_t *);
    74 void ec_fsm_slave_prepare_sii(ec_fsm_t *);
    66 void ec_fsm_slave_eeprom_size(ec_fsm_t *);
    75 void ec_fsm_slave_read_sii(ec_fsm_t *);
    67 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *);
    76 void ec_fsm_slave_category_header(ec_fsm_t *);
    68 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *);
    77 void ec_fsm_slave_category_data(ec_fsm_t *);
       
    78 void ec_fsm_slave_end(ec_fsm_t *);
    69 void ec_fsm_slave_end(ec_fsm_t *);
    79 
    70 
    80 void ec_fsm_slave_conf(ec_fsm_t *);
    71 void ec_fsm_slave_conf(ec_fsm_t *);
    81 void ec_fsm_slave_sync(ec_fsm_t *);
    72 void ec_fsm_slave_sync(ec_fsm_t *);
    82 void ec_fsm_slave_preop(ec_fsm_t *);
    73 void ec_fsm_slave_preop(ec_fsm_t *);
   113     fsm->master = master;
   104     fsm->master = master;
   114     fsm->master_state = ec_fsm_master_start;
   105     fsm->master_state = ec_fsm_master_start;
   115     fsm->master_slaves_responding = 0;
   106     fsm->master_slaves_responding = 0;
   116     fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
   107     fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
   117     fsm->master_validation = 0;
   108     fsm->master_validation = 0;
   118     fsm->slave_cat_data = NULL;
       
   119 
   109 
   120     ec_command_init(&fsm->command);
   110     ec_command_init(&fsm->command);
   121     if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) {
   111     if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) {
   122         EC_ERR("FSM failed to allocate FSM command.\n");
   112         EC_ERR("FSM failed to allocate FSM command.\n");
   123         return -1;
   113         return -1;
   132    Destructor.
   122    Destructor.
   133 */
   123 */
   134 
   124 
   135 void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */)
   125 void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */)
   136 {
   126 {
   137     if (fsm->slave_cat_data) kfree(fsm->slave_cat_data);
       
   138     ec_command_clear(&fsm->command);
   127     ec_command_clear(&fsm->command);
   139 }
   128 }
   140 
   129 
   141 /*****************************************************************************/
   130 /*****************************************************************************/
   142 
   131 
   147 void ec_fsm_reset(ec_fsm_t *fsm /**< finite state machine */)
   136 void ec_fsm_reset(ec_fsm_t *fsm /**< finite state machine */)
   148 {
   137 {
   149     fsm->master_state = ec_fsm_master_start;
   138     fsm->master_state = ec_fsm_master_start;
   150     fsm->master_slaves_responding = 0;
   139     fsm->master_slaves_responding = 0;
   151     fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
   140     fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN;
   152 
       
   153     if (fsm->slave_cat_data) {
       
   154         kfree(fsm->slave_cat_data);
       
   155         fsm->slave_cat_data = NULL;
       
   156     }
       
   157 }
   141 }
   158 
   142 
   159 /*****************************************************************************/
   143 /*****************************************************************************/
   160 
   144 
   161 /**
   145 /**
   448         return;
   432         return;
   449     }
   433     }
   450 
   434 
   451     if (fsm->sii_state != ec_fsm_sii_end) return;
   435     if (fsm->sii_state != ec_fsm_sii_end) return;
   452 
   436 
   453     if (fsm->sii_result != slave->sii_vendor_id) {
   437     if (EC_READ_U32(fsm->sii_result) != slave->sii_vendor_id) {
   454         EC_ERR("Slave %i: invalid vendor ID!\n", slave->ring_position);
   438         EC_ERR("Slave %i: invalid vendor ID!\n", slave->ring_position);
   455         fsm->master_state = ec_fsm_master_start;
   439         fsm->master_state = ec_fsm_master_start;
   456         fsm->master_state(fsm); // execute immediately
   440         fsm->master_state(fsm); // execute immediately
   457         return;
   441         return;
   458     }
   442     }
   486         return;
   470         return;
   487     }
   471     }
   488 
   472 
   489     if (fsm->sii_state != ec_fsm_sii_end) return;
   473     if (fsm->sii_state != ec_fsm_sii_end) return;
   490 
   474 
   491     if (fsm->sii_result != slave->sii_product_code) {
   475     if (EC_READ_U32(fsm->sii_result) != slave->sii_product_code) {
   492         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
   476         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
   493         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
   477         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
   494                fsm->sii_result);
   478                EC_READ_U32(fsm->sii_result));
   495         fsm->master_state = ec_fsm_master_start;
   479         fsm->master_state = ec_fsm_master_start;
   496         fsm->master_state(fsm); // execute immediately
   480         fsm->master_state(fsm); // execute immediately
   497         return;
   481         return;
   498     }
   482     }
   499 
   483 
   785         slave->base_fmmu_count = EC_MAX_FMMUS;
   769         slave->base_fmmu_count = EC_MAX_FMMUS;
   786 
   770 
   787     // read data link status
   771     // read data link status
   788     ec_command_nprd(command, slave->station_address, 0x0110, 2);
   772     ec_command_nprd(command, slave->station_address, 0x0110, 2);
   789     ec_master_queue_command(slave->master, command);
   773     ec_master_queue_command(slave->master, command);
   790     fsm->slave_state = ec_fsm_slave_prepare_sii;
   774     fsm->slave_state = ec_fsm_slave_eeprom_size;
   791 }
   775 }
   792 
   776 
   793 /*****************************************************************************/
   777 /*****************************************************************************/
   794 
   778 
   795 /**
   779 /**
   796    Slave state: PREPARE_SII.
   780    Slave state: EEPROM_SIZE.
   797 */
   781    Read the actual size of the EEPROM to allocate the EEPROM image.
   798 
   782 */
   799 void ec_fsm_slave_prepare_sii(ec_fsm_t *fsm /**< finite state machine */)
   783 
       
   784 void ec_fsm_slave_eeprom_size(ec_fsm_t *fsm /**< finite state machine */)
   800 {
   785 {
   801     ec_command_t *command = &fsm->command;
   786     ec_command_t *command = &fsm->command;
   802     ec_slave_t *slave = fsm->slave;
   787     ec_slave_t *slave = fsm->slave;
   803     uint16_t dl_status;
   788     uint16_t dl_status;
   804     unsigned int i;
   789     unsigned int i;
   809         fsm->slave_state = ec_fsm_slave_end;
   794         fsm->slave_state = ec_fsm_slave_end;
   810         return;
   795         return;
   811     }
   796     }
   812 
   797 
   813     dl_status = EC_READ_U16(command->data);
   798     dl_status = EC_READ_U16(command->data);
   814 
       
   815     for (i = 0; i < 4; i++) {
   799     for (i = 0; i < 4; i++) {
   816         slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
   800         slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
   817         slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
   801         slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
   818         slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
   802         slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
   819     }
   803     }
   820 
   804 
   821     fsm->sii_offset = 0x0004;
   805     // Start fetching EEPROM size
       
   806 
       
   807     fsm->sii_offset = 0x0040; // first category header
   822     fsm->sii_mode = 1;
   808     fsm->sii_mode = 1;
   823     fsm->sii_state = ec_fsm_sii_start_reading;
   809     fsm->sii_state = ec_fsm_sii_start_reading;
   824     fsm->slave_sii_num = 0;
   810     fsm->slave_state = ec_fsm_slave_fetch_eeprom;
   825     fsm->slave_state = ec_fsm_slave_read_sii;
       
   826     fsm->slave_state(fsm); // execute state immediately
   811     fsm->slave_state(fsm); // execute state immediately
   827 }
   812 }
   828 
   813 
   829 /*****************************************************************************/
   814 /*****************************************************************************/
   830 
   815 
   831 /**
   816 /**
   832    Slave state: READ_SII.
   817    Slave state: FETCH_EEPROM.
   833 */
   818 */
   834 
   819 
   835 void ec_fsm_slave_read_sii(ec_fsm_t *fsm /**< finite state machine */)
   820 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *fsm /**< finite state machine */)
   836 {
   821 {
   837     ec_slave_t *slave = fsm->slave;
   822     ec_slave_t *slave = fsm->slave;
       
   823     uint16_t cat_type, cat_size;
   838 
   824 
   839     // execute SII state machine
   825     // execute SII state machine
   840     fsm->sii_state(fsm);
   826     fsm->sii_state(fsm);
   841 
   827 
   842     if (fsm->sii_state == ec_fsm_sii_error) {
   828     if (fsm->sii_state == ec_fsm_sii_error) {
   843         fsm->slave_state = ec_fsm_slave_end;
   829         fsm->slave_state = ec_fsm_slave_end;
   844         EC_ERR("FSM failed to read SII data at 0x%04X on slave %i.\n",
   830         EC_ERR("Failed to read EEPROM size of slave %i.\n",
   845                fsm->sii_offset, slave->ring_position);
   831                slave->ring_position);
   846         return;
   832         return;
   847     }
   833     }
   848 
   834 
   849     if (fsm->sii_state != ec_fsm_sii_end) return;
   835     if (fsm->sii_state != ec_fsm_sii_end) return;
   850 
   836 
   851     switch (fsm->slave_sii_num) {
   837     cat_type = EC_READ_U16(fsm->sii_result);
   852         case 0:
   838     cat_size = EC_READ_U16(fsm->sii_result + 2);
   853             slave->sii_alias = fsm->sii_result & 0xFFFF;
   839 
   854             fsm->sii_offset = 0x0008;
   840     if (cat_type != 0xFFFF) { // not the last category
   855             break;
   841         fsm->sii_offset += cat_size + 2;
   856         case 1:
   842         fsm->sii_state = ec_fsm_sii_start_reading;
   857             slave->sii_vendor_id = fsm->sii_result;
   843         fsm->sii_state(fsm); // execute state immediately
   858             fsm->sii_offset = 0x000A;
   844         return;
   859             break;
   845     }
   860         case 2:
   846 
   861             slave->sii_product_code = fsm->sii_result;
   847     slave->eeprom_size = (fsm->sii_offset + 1) * 2;
   862             fsm->sii_offset = 0x000C;
   848 
   863             break;
   849     if (slave->eeprom_data) {
   864         case 3:
   850         EC_INFO("Freeing old EEPROM data on slave %i...\n",
   865             slave->sii_revision_number = fsm->sii_result;
   851                 slave->ring_position);
   866             fsm->sii_offset = 0x000E;
   852         kfree(slave->eeprom_data);
   867             break;
   853     }
   868         case 4:
   854 
   869             slave->sii_serial_number = fsm->sii_result;
   855     if (!(slave->eeprom_data =
   870             fsm->sii_offset = 0x0018;
   856           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
   871             break;
   857         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
   872         case 5:
   858                slave->ring_position);
   873             slave->sii_rx_mailbox_offset = fsm->sii_result & 0xFFFF;
   859         fsm->slave_state = ec_fsm_slave_end;
   874             slave->sii_rx_mailbox_size = fsm->sii_result >> 16;
   860         return;
   875             fsm->sii_offset = 0x001A;
   861     }
   876             break;
   862 
   877         case 6:
   863     // Start fetching EEPROM contents
   878             slave->sii_tx_mailbox_offset = fsm->sii_result & 0xFFFF;
   864 
   879             slave->sii_tx_mailbox_size = fsm->sii_result >> 16;
   865     fsm->sii_offset = 0x0000;
   880             fsm->sii_offset = 0x001C;
   866     fsm->sii_mode = 1;
   881             break;
       
   882         case 7:
       
   883             slave->sii_mailbox_protocols = fsm->sii_result & 0xFFFF;
       
   884 
       
   885             fsm->slave_cat_offset = 0x0040;
       
   886 
       
   887             if (fsm->slave_cat_data) {
       
   888                 EC_INFO("FSM freeing old category data on slave %i...\n",
       
   889                         fsm->slave->ring_position);
       
   890                 kfree(fsm->slave_cat_data);
       
   891             }
       
   892 
       
   893             if (!(fsm->slave_cat_data =
       
   894                   (uint8_t *) kmalloc(EC_CAT_MEM, GFP_ATOMIC))) {
       
   895                 EC_ERR("FSM Failed to allocate category data.\n");
       
   896                 fsm->slave_state = ec_fsm_slave_end;
       
   897                 return;
       
   898             }
       
   899 
       
   900             // start reading first category header
       
   901             fsm->sii_offset = fsm->slave_cat_offset;
       
   902             fsm->sii_state = ec_fsm_sii_start_reading;
       
   903 
       
   904             fsm->slave_state = ec_fsm_slave_category_header;
       
   905             fsm->slave_state(fsm); // execute state immediately
       
   906             return;
       
   907     }
       
   908 
       
   909     fsm->slave_sii_num++;
       
   910     fsm->sii_state = ec_fsm_sii_start_reading;
   867     fsm->sii_state = ec_fsm_sii_start_reading;
       
   868     fsm->slave_state = ec_fsm_slave_fetch_eeprom2;
   911     fsm->slave_state(fsm); // execute state immediately
   869     fsm->slave_state(fsm); // execute state immediately
   912 }
   870 }
   913 
   871 
   914 /*****************************************************************************/
   872 /*****************************************************************************/
   915 
   873 
   916 /**
   874 /**
   917    Slave state: CATEGORY_HEADER.
   875    Slave state: FETCH_EEPROM2.
   918    Start reading categories.
   876 */
   919 */
   877 
   920 
   878 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *fsm /**< finite state machine */)
   921 void ec_fsm_slave_category_header(ec_fsm_t *fsm /**< finite state machine */)
   879 {
   922 {
   880     ec_slave_t *slave = fsm->slave;
       
   881     uint16_t *cat_word, cat_type, cat_size;
       
   882 
   923     // execute SII state machine
   883     // execute SII state machine
   924     fsm->sii_state(fsm);
   884     fsm->sii_state(fsm);
   925 
   885 
   926     if (fsm->sii_state == ec_fsm_sii_error) {
   886     if (fsm->sii_state == ec_fsm_sii_error) {
   927         kfree(fsm->slave_cat_data);
   887         fsm->slave_state = ec_fsm_slave_end;
   928         fsm->slave_cat_data = NULL;
   888         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
   929         fsm->slave_state = ec_fsm_slave_end;
   889                slave->ring_position);
   930         EC_ERR("FSM failed to read category header at 0x%04X on slave %i.\n",
       
   931                fsm->slave_cat_offset, fsm->slave->ring_position);
       
   932         return;
   890         return;
   933     }
   891     }
   934 
   892 
   935     if (fsm->sii_state != ec_fsm_sii_end) return;
   893     if (fsm->sii_state != ec_fsm_sii_end) return;
   936 
   894 
   937     // last category?
   895     // 2 words fetched
   938     if ((fsm->sii_result & 0xFFFF) == 0xFFFF) {
   896 
   939         kfree(fsm->slave_cat_data);
   897     if (fsm->sii_offset + 2 <= slave->eeprom_size / 2) { // 2 words fit
   940         fsm->slave_cat_data = NULL;
   898         memcpy(slave->eeprom_data + fsm->sii_offset * 2, fsm->sii_result, 4);
   941         fsm->slave_state = ec_fsm_slave_end;
   899     }
   942         return;
   900     else { // copy the last word
   943     }
   901         memcpy(slave->eeprom_data + fsm->sii_offset * 2, fsm->sii_result, 2);
   944 
   902     }
   945     fsm->slave_cat_type = fsm->sii_result & 0x7FFF;
   903 
   946     fsm->slave_cat_words = (fsm->sii_result >> 16) & 0xFFFF;
   904     if (fsm->sii_offset + 2 < slave->eeprom_size / 2) {
   947 
   905         // fetch the next 2 words
   948     if (fsm->slave_cat_words > EC_CAT_MEM * 2) {
   906         fsm->sii_offset += 2;
   949         EC_ERR("FSM category memory too small! %i words needed.\n",
       
   950                fsm->slave_cat_words);
       
   951         fsm->slave_state = ec_fsm_slave_end;
       
   952         return;
       
   953     }
       
   954 
       
   955     // start reading category data
       
   956     fsm->slave_cat_data_offset = 0;
       
   957     fsm->sii_offset = (fsm->slave_cat_offset + 2 +
       
   958                        fsm->slave_cat_data_offset);
       
   959     fsm->sii_mode = 1;
       
   960     fsm->sii_state = ec_fsm_sii_start_reading;
       
   961     fsm->slave_state = ec_fsm_slave_category_data;
       
   962     fsm->slave_state(fsm); // execute state immediately
       
   963 }
       
   964 
       
   965 /*****************************************************************************/
       
   966 
       
   967 /**
       
   968    Slave state: CATEGORY_DATA.
       
   969    Reads category data.
       
   970 */
       
   971 
       
   972 void ec_fsm_slave_category_data(ec_fsm_t *fsm /**< finite state machine */)
       
   973 {
       
   974     // execute SII state machine
       
   975     fsm->sii_state(fsm);
       
   976 
       
   977     if (fsm->sii_state == ec_fsm_sii_error) {
       
   978         kfree(fsm->slave_cat_data);
       
   979         fsm->slave_cat_data = NULL;
       
   980         fsm->slave_state = ec_fsm_slave_end;
       
   981         EC_ERR("FSM failed to read category 0x%02X data at 0x%04X"
       
   982                " on slave %i.\n", fsm->slave_cat_type, fsm->sii_offset,
       
   983                fsm->slave->ring_position);
       
   984         return;
       
   985     }
       
   986 
       
   987     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   988 
       
   989     fsm->slave_cat_data[fsm->slave_cat_data_offset * 2] =
       
   990         fsm->sii_result & 0xFF;
       
   991     fsm->slave_cat_data[fsm->slave_cat_data_offset * 2 + 1] =
       
   992         (fsm->sii_result >> 8) & 0xFF;
       
   993 
       
   994     // read second word "on the fly"
       
   995     if (fsm->slave_cat_data_offset + 1 < fsm->slave_cat_words) {
       
   996         fsm->slave_cat_data_offset++;
       
   997         fsm->slave_cat_data[fsm->slave_cat_data_offset * 2] =
       
   998             (fsm->sii_result >> 16) & 0xFF;
       
   999         fsm->slave_cat_data[fsm->slave_cat_data_offset * 2 + 1] =
       
  1000             (fsm->sii_result >> 24) & 0xFF;
       
  1001     }
       
  1002 
       
  1003     fsm->slave_cat_data_offset++;
       
  1004 
       
  1005     if (fsm->slave_cat_data_offset < fsm->slave_cat_words) {
       
  1006         fsm->sii_offset = (fsm->slave_cat_offset + 2 +
       
  1007                            fsm->slave_cat_data_offset);
       
  1008         fsm->sii_mode = 1;
       
  1009         fsm->sii_state = ec_fsm_sii_start_reading;
   907         fsm->sii_state = ec_fsm_sii_start_reading;
  1010         fsm->slave_state = ec_fsm_slave_category_data;
   908         fsm->sii_state(fsm); // execute state immediately
  1011         fsm->slave_state(fsm); // execute state immediately
   909         return;
  1012         return;
   910     }
  1013     }
   911 
  1014 
   912     // Evaluate EEPROM contents
  1015     // category data complete
   913 
  1016     switch (fsm->slave_cat_type)
   914     slave->sii_alias =
  1017     {
   915         EC_READ_U16(slave->eeprom_data + 2 * 0x0004);
  1018         case 0x000A:
   916     slave->sii_vendor_id =
  1019             if (ec_slave_fetch_strings(fsm->slave, fsm->slave_cat_data))
   917         EC_READ_U32(slave->eeprom_data + 2 * 0x0008);
  1020                 goto out_free;
   918     slave->sii_product_code =
  1021             break;
   919         EC_READ_U32(slave->eeprom_data + 2 * 0x000A);
  1022         case 0x001E:
   920     slave->sii_revision_number =
  1023             if (ec_slave_fetch_general(fsm->slave, fsm->slave_cat_data))
   921         EC_READ_U32(slave->eeprom_data + 2 * 0x000C);
  1024                 goto out_free;
   922     slave->sii_serial_number =
  1025             break;
   923         EC_READ_U32(slave->eeprom_data + 2 * 0x000E);
  1026         case 0x0028:
   924     slave->sii_rx_mailbox_offset =
  1027             break;
   925         EC_READ_U16(slave->eeprom_data + 2 * 0x0018);
  1028         case 0x0029:
   926     slave->sii_rx_mailbox_size =
  1029             if (ec_slave_fetch_sync(fsm->slave, fsm->slave_cat_data,
   927         EC_READ_U16(slave->eeprom_data + 2 * 0x0019);
  1030                                     fsm->slave_cat_words))
   928     slave->sii_tx_mailbox_offset =
  1031                 goto out_free;
   929         EC_READ_U16(slave->eeprom_data + 2 * 0x001A);
  1032             break;
   930     slave->sii_tx_mailbox_size =
  1033         case 0x0032:
   931         EC_READ_U16(slave->eeprom_data + 2 * 0x001B);
  1034             if (ec_slave_fetch_pdo(fsm->slave, fsm->slave_cat_data,
   932     slave->sii_mailbox_protocols =
  1035                                    fsm->slave_cat_words,
   933         EC_READ_U16(slave->eeprom_data + 2 * 0x001C);
  1036                                    EC_TX_PDO))
   934 
  1037                 goto out_free;
   935     // evaluate category data
  1038             break;
   936     cat_word = (uint16_t *) slave->eeprom_data + 0x0040;
  1039         case 0x0033:
   937     while (EC_READ_U16(cat_word) != 0xFFFF) {
  1040             if (ec_slave_fetch_pdo(fsm->slave, fsm->slave_cat_data,
   938         cat_type = EC_READ_U16(cat_word) & 0x7FFF;
  1041                                    fsm->slave_cat_words,
   939         cat_size = EC_READ_U16(cat_word + 1);
  1042                                    EC_RX_PDO))
   940 
  1043                 goto out_free;
   941         switch (cat_type) {
  1044             break;
   942             case 0x000A:
  1045         default:
   943                 if (ec_slave_fetch_strings(slave, (uint8_t *) (cat_word + 2)))
  1046             EC_WARN("FSM: Unknown category type 0x%04X in slave %i.\n",
   944                     goto end;
  1047                     fsm->slave_cat_type, fsm->slave->ring_position);
   945                 break;
  1048     }
   946             case 0x001E:
  1049 
   947                 if (ec_slave_fetch_general(slave, (uint8_t *) (cat_word + 2)))
  1050     // start reading next category header
   948                     goto end;
  1051     fsm->slave_cat_offset += 2 + fsm->slave_cat_words;
   949                 break;
  1052     fsm->sii_offset = fsm->slave_cat_offset;
   950             case 0x0028:
  1053     fsm->sii_mode = 1;
   951                 break;
  1054     fsm->sii_state = ec_fsm_sii_start_reading;
   952             case 0x0029:
  1055     fsm->slave_state = ec_fsm_slave_category_header;
   953                 if (ec_slave_fetch_sync(slave, (uint8_t *) (cat_word + 2),
  1056     fsm->slave_state(fsm); // execute state immediately
   954                                         cat_size))
  1057     return;
   955                     goto end;
  1058 
   956                 break;
  1059  out_free:
   957             case 0x0032:
  1060     kfree(fsm->slave_cat_data);
   958                 if (ec_slave_fetch_pdo(slave, (uint8_t *) (cat_word + 2),
  1061     fsm->slave_cat_data = NULL;
   959                                        cat_size, EC_TX_PDO))
       
   960                     goto end;
       
   961                 break;
       
   962             case 0x0033:
       
   963                 if (ec_slave_fetch_pdo(slave, (uint8_t *) (cat_word + 2),
       
   964                                        cat_size, EC_RX_PDO))
       
   965                     goto end;
       
   966                 break;
       
   967             default:
       
   968                 EC_WARN("Unknown category type 0x%04X in slave %i.\n",
       
   969                         cat_type, slave->ring_position);
       
   970         }
       
   971 
       
   972         cat_word += cat_size + 2;
       
   973     }
       
   974 
       
   975  end:
  1062     fsm->slave_state = ec_fsm_slave_end;
   976     fsm->slave_state = ec_fsm_slave_end;
  1063 }
   977 }
  1064 
   978 
  1065 /*****************************************************************************/
   979 /*****************************************************************************/
  1066 
   980 
  1475            EC_READ_U8(command->data + 6), EC_READ_U8(command->data + 7),
  1389            EC_READ_U8(command->data + 6), EC_READ_U8(command->data + 7),
  1476            EC_READ_U8(command->data + 8), EC_READ_U8(command->data + 9));
  1390            EC_READ_U8(command->data + 8), EC_READ_U8(command->data + 9));
  1477 #endif
  1391 #endif
  1478 
  1392 
  1479     // SII value received.
  1393     // SII value received.
  1480     fsm->sii_result = EC_READ_U32(command->data + 6);
  1394     memcpy(fsm->sii_result, command->data + 6, 4);
  1481     fsm->sii_state = ec_fsm_sii_end;
  1395     fsm->sii_state = ec_fsm_sii_end;
  1482 }
  1396 }
  1483 
  1397 
  1484 /*****************************************************************************/
  1398 /*****************************************************************************/
  1485 
  1399