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 /** |