master/slave.c
changeset 599 a6ce861a167e
parent 597 3a2c2d6ca5e9
child 601 d6d951b766e3
equal deleted inserted replaced
598:b3b1f4ce590c 599:a6ce861a167e
   789     const uint16_t *data_words, *next_header;
   789     const uint16_t *data_words, *next_header;
   790     uint16_t *new_data;
   790     uint16_t *new_data;
   791 
   791 
   792     if (slave->master->mode != EC_MASTER_MODE_IDLE) {
   792     if (slave->master->mode != EC_MASTER_MODE_IDLE) {
   793         EC_ERR("Writing EEPROMs only allowed in idle mode!\n");
   793         EC_ERR("Writing EEPROMs only allowed in idle mode!\n");
   794         return -1;
   794         return -EACCES;
   795     }
   795     }
   796 
   796 
   797     if (slave->new_eeprom_data) {
   797     if (slave->new_eeprom_data) {
   798         EC_ERR("Slave %i already has a pending EEPROM write operation!\n",
   798         EC_ERR("Slave %i already has a pending EEPROM write operation!\n",
   799                slave->ring_position);
   799                slave->ring_position);
   800         return -1;
   800         return -EBUSY;
   801     }
   801     }
   802 
   802 
   803     // coarse check of the data
   803     // coarse check of the data
   804 
   804 
   805     if (size % 2) {
   805     if (size % 2) {
   806         EC_ERR("EEPROM size is odd! Dropping.\n");
   806         EC_ERR("EEPROM size is odd! Dropping.\n");
   807         return -1;
   807         return -EINVAL;
   808     }
   808     }
   809 
   809 
   810     data_words = (const uint16_t *) data;
   810     data_words = (const uint16_t *) data;
   811     word_size = size / 2;
   811     word_size = size / 2;
   812 
   812 
   813     if (word_size < 0x0041) {
   813     if (word_size < 0x0041) {
   814         EC_ERR("EEPROM data too short! Dropping.\n");
   814         EC_ERR("EEPROM data too short! Dropping.\n");
   815         return -1;
   815         return -EINVAL;
   816     }
   816     }
   817 
   817 
   818     next_header = data_words + 0x0040;
   818     next_header = data_words + 0x0040;
   819     cat_type = EC_READ_U16(next_header);
   819     cat_type = EC_READ_U16(next_header);
   820     while (cat_type != 0xFFFF) {
   820     while (cat_type != 0xFFFF) {
   821         cat_type = EC_READ_U16(next_header);
   821         cat_type = EC_READ_U16(next_header);
   822         cat_size = EC_READ_U16(next_header + 1);
   822         cat_size = EC_READ_U16(next_header + 1);
   823         if ((next_header + cat_size + 2) - data_words >= word_size) {
   823         if ((next_header + cat_size + 2) - data_words >= word_size) {
   824             EC_ERR("EEPROM data seems to be corrupted! Dropping.\n");
   824             EC_ERR("EEPROM data seems to be corrupted! Dropping.\n");
   825             return -1;
   825             return -EINVAL;
   826         }
   826         }
   827         next_header += cat_size + 2;
   827         next_header += cat_size + 2;
   828         cat_type = EC_READ_U16(next_header);
   828         cat_type = EC_READ_U16(next_header);
   829     }
   829     }
   830 
   830 
   831     // data ok!
   831     // data ok!
   832 
   832 
   833     if (!(new_data = (uint16_t *) kmalloc(word_size * 2, GFP_KERNEL))) {
   833     if (!(new_data = (uint16_t *) kmalloc(word_size * 2, GFP_KERNEL))) {
   834         EC_ERR("Unable to allocate memory for new EEPROM data!\n");
   834         EC_ERR("Unable to allocate memory for new EEPROM data!\n");
   835         return -1;
   835         return -ENOMEM;
   836     }
   836     }
   837     memcpy(new_data, data, size);
   837     memcpy(new_data, data, size);
   838 
   838 
   839     slave->new_eeprom_size = word_size;
   839     slave->new_eeprom_size = word_size;
   840     slave->new_eeprom_data = new_data;
   840     slave->new_eeprom_data = new_data;
   841 
   841 
   842     EC_INFO("EEPROM writing scheduled for slave %i, %i words.\n",
   842     EC_INFO("EEPROM writing scheduled for slave %i, %i words.\n",
   843             slave->ring_position, word_size);
   843             slave->ring_position, word_size);
   844     return 0;
   844     return size;
   845 }
   845 }
   846 
   846 
   847 /*****************************************************************************/
   847 /*****************************************************************************/
   848 
   848 
   849 /**
   849 /**
   926         EC_INFO("Accepted new state %s for slave %i.\n",
   926         EC_INFO("Accepted new state %s for slave %i.\n",
   927                 state, slave->ring_position);
   927                 state, slave->ring_position);
   928         return size;
   928         return size;
   929     }
   929     }
   930     else if (attr == &attr_eeprom) {
   930     else if (attr == &attr_eeprom) {
   931         if (!ec_slave_write_eeprom(slave, buffer, size))
   931         return ec_slave_write_eeprom(slave, buffer, size);
   932             return size;
       
   933     }
   932     }
   934 
   933 
   935     return -EINVAL;
   934     return -EINVAL;
   936 }
   935 }
   937 
   936