BufferContents(Type t, int x_size, int y_size, int z_size, int w_size, uint8_t* data, const std::string &n) : type(t), allocation(NULL), name(n.empty() ? unique_name('b') : n) { user_assert(t.lanes() == 1) << "Can't create of a buffer of a vector type"; buf.elem_size = t.bytes(); uint64_t size = 1; if (x_size) { size *= x_size; check_buffer_size(size, name); } if (y_size) { size *= y_size; check_buffer_size(size, name); } if (z_size) { size *= z_size; check_buffer_size(size, name); } if (w_size) { size *= w_size; check_buffer_size(size, name); } size *= buf.elem_size; check_buffer_size(size, name); if (!data) { size = size + 32; check_buffer_size(size, name); allocation = (uint8_t *)calloc(1, (size_t)size); user_assert(allocation) << "Out of memory allocating buffer " << name << " of size " << size << "\n"; buf.host = allocation; while ((size_t)(buf.host) & 0x1f) buf.host++; } else { buf.host = data; } buf.dev = 0; buf.host_dirty = false; buf.dev_dirty = false; buf.extent[0] = x_size; buf.extent[1] = y_size; buf.extent[2] = z_size; buf.extent[3] = w_size; buf.stride[0] = 1; buf.stride[1] = x_size; buf.stride[2] = x_size*y_size; buf.stride[3] = x_size*y_size*z_size; buf.min[0] = 0; buf.min[1] = 0; buf.min[2] = 0; buf.min[3] = 0; }
static int start_read(struct device *dev, const struct adc_sequence *sequence) { const struct adc_stm32_cfg *config = dev->config->config_info; struct adc_stm32_data *data = dev->driver_data; ADC_TypeDef *adc = (ADC_TypeDef *)config->base; u8_t resolution; int err; switch (sequence->resolution) { #if !defined(CONFIG_SOC_SERIES_STM32F1X) case 6: resolution = table_resolution[0]; break; case 8: resolution = table_resolution[1]; break; case 10: resolution = table_resolution[2]; break; #endif case 12: resolution = table_resolution[3]; break; default: LOG_ERR("Invalid resolution"); return -EINVAL; } u32_t channels = sequence->channels; data->buffer = sequence->buffer; u8_t index; index = find_lsb_set(channels) - 1; u32_t channel = __LL_ADC_DECIMAL_NB_TO_CHANNEL(index); #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) LL_ADC_REG_SetSequencerChannels(adc, channel); #else LL_ADC_REG_SetSequencerRanks(adc, table_rank[0], channel); LL_ADC_REG_SetSequencerLength(adc, table_seq_len[0]); #endif data->channel_count = 1; err = check_buffer_size(sequence, data->channel_count); if (err) { return err; } #if !defined(CONFIG_SOC_SERIES_STM32F1X) LL_ADC_SetResolution(adc, resolution); #endif #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32F3X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) LL_ADC_EnableIT_EOC(adc); #elif defined(CONFIG_SOC_SERIES_STM32F1X) LL_ADC_EnableIT_EOS(adc); #else LL_ADC_EnableIT_EOCS(adc); #endif adc_context_start_read(&data->ctx, sequence); return adc_context_wait_for_completion(&data->ctx); }
static int start_read(struct device *dev, const struct adc_sequence *sequence) { int error = 0; u32_t selected_channels = sequence->channels; u8_t active_channels; u8_t channel_id; nrf_adc_config_resolution_t nrf_resolution; /* Signal an error if channel selection is invalid (no channels or * a non-existing one is selected). */ if (!selected_channels || (selected_channels & ~BIT_MASK(CONFIG_ADC_NRFX_ADC_CHANNEL_COUNT))) { LOG_ERR("Invalid selection of channels"); return -EINVAL; } if (sequence->oversampling != 0) { LOG_ERR("Oversampling is not supported"); return -EINVAL; } switch (sequence->resolution) { case 8: nrf_resolution = NRF_ADC_CONFIG_RES_8BIT; break; case 9: nrf_resolution = NRF_ADC_CONFIG_RES_9BIT; break; case 10: nrf_resolution = NRF_ADC_CONFIG_RES_10BIT; break; default: LOG_ERR("ADC resolution value %d is not valid", sequence->resolution); return -EINVAL; } active_channels = 0; nrfx_adc_all_channels_disable(); /* Enable the channels selected for the pointed sequence. */ channel_id = 0; while (selected_channels) { if (selected_channels & BIT(0)) { /* The nrfx driver requires setting the resolution * for each enabled channel individually. */ m_channels[channel_id].config.resolution = nrf_resolution; nrfx_adc_channel_enable(&m_channels[channel_id]); ++active_channels; } selected_channels >>= 1; ++channel_id; } error = check_buffer_size(sequence, active_channels); if (error) { return error; } m_data.buffer = sequence->buffer; m_data.active_channels = active_channels; adc_context_start_read(&m_data.ctx, sequence); if (!error) { error = adc_context_wait_for_completion(&m_data.ctx); adc_context_release(&m_data.ctx, error); } return error; }
/* * Alon: This function should write the buffer given by the user into the file. * The function assumes the given buffer is encrypted, and will therefor * use the iKey to decypher each character before writing it to the file. * The function returns the amount of bytes it managed to write into the * file, and -1 in case of failure. */ ssize_t my_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) { if(check_buffer_size(count) != 0) { return -EINVAL; } int minor = get_minor_from_file(filp); int is_this_process_reader = is_reader(filp); int key = ((device_private_data *)((filp)->private_data))->private_key; down_interruptible(&write_lock[minor]); down_interruptible(&index_lock[minor]); int maxToWrite = get_max_to_write(minor); if (maxToWrite == 0) { int current_num_of_readers = get_current_num_of_readers(minor); if(current_num_of_readers == is_this_process_reader) { up(&index_lock[minor]); up(&write_lock[minor]); return 0; } //Going to sleep until a reader clears some room in the buffer up(&index_lock[minor]); int wake_up_reason = wait_event_interruptible(write_wq[minor], flag_is_full[minor] == 0 || get_current_num_of_readers(minor) == is_this_process_reader); if(wake_up_reason != 0) { up(&write_lock[minor]); return -EINTR; } if (get_current_num_of_readers(minor) == is_this_process_reader) { up(&write_lock[minor]); return 0; } down_interruptible(&index_lock[minor]); maxToWrite = get_max_to_write(minor); } int numToWrite = MIN(maxToWrite,count); int firstPartSize = 0; int retval = 0; char* tmpBuf =(char*)kmalloc(sizeof(char)*numToWrite,GFP_KERNEL); if (!tmpBuf){ up(&index_lock[minor]); up(&write_lock[minor]); return -ENOMEM; } retval = copy_from_user(tmpBuf, buf, numToWrite); //copy the data from user if(retval != 0){ kfree(tmpBuf); up(&index_lock[minor]); up(&write_lock[minor]); return retval; } int numOfParts = ( (writing_position[minor] + numToWrite) > BUF_SIZE) ? TWO : ONE ; if(numOfParts == ONE ) { if (minor == 1) { encryptor(tmpBuf, &buffer[minor][writing_position[minor]], numToWrite, key, minor); } else if(minor == 0){ memcpy(&buffer[minor][ writing_position[minor] ], tmpBuf, numToWrite); } writing_position[minor] = (writing_position[minor] + numToWrite) % BUF_SIZE; } else { firstPartSize = BUF_SIZE - writing_position[minor]; if (minor == 1) { encryptor(tmpBuf, &buffer[minor][writing_position[minor]], firstPartSize, key, minor); encryptor(tmpBuf + firstPartSize, &buffer[minor][0], numToWrite - firstPartSize, key, minor); } else if (minor == 0) { memcpy(&buffer[minor][writing_position[minor]], tmpBuf, firstPartSize); memcpy(&buffer[minor][0], tmpBuf + firstPartSize, numToWrite - firstPartSize); } writing_position[minor] = (numToWrite - firstPartSize); } if(( writing_position[minor] == reading_position[minor]) && numToWrite){ flag_is_full[minor] = 1; } if (numToWrite) { flag_is_empty[minor] = 0; wake_up_interruptible(&read_wq[minor]); } /* * If we wrote something into the buffer, this makes sure to wake up * any writer who may be waiting for input. */ kfree(tmpBuf); up(&index_lock[minor]); up(&write_lock[minor]); if(retval != 0){ return retval; } return numToWrite; }
/* * Alon: this function should simply read the data on the given file, * copy it, and return it to the user as it is (encrypted or not). * The function's return value is the total amount of bytes read from the * file, or -1 if the function failed. */ ssize_t my_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { if (check_buffer_size(count) != 0) { return -EINVAL; } int minor = get_minor_from_file(filp); int is_this_process_writer = is_writer(filp); int key = ((device_private_data *)((filp)->private_data))->private_key; down_interruptible(&read_lock[minor]); down_interruptible(&index_lock[minor]); int maxToRead = get_max_to_read(minor); if (maxToRead == 0) { int current_num_of_writers = get_current_num_of_writers(minor); if(current_num_of_writers == is_this_process_writer) { up(&index_lock[minor]); up(&read_lock[minor]); return 0; } //Going to sleep until something is written into the buffer up(&index_lock[minor]); int wake_up_reason = wait_event_interruptible(read_wq[minor], flag_is_empty[minor] == 0 || get_current_num_of_writers(minor) == is_this_process_writer); if(wake_up_reason != 0) { up(&read_lock[minor]); return -EINTR; } if (get_current_num_of_writers(minor) == is_this_process_writer) { up(&read_lock[minor]); return 0; } down_interruptible(&index_lock[minor]); maxToRead = get_max_to_read(minor); } int numToRead = MIN(maxToRead,count); int firstPartSize = 0; int retval = 0; char* tmpBuf =(char*)kmalloc(sizeof(char)*numToRead,GFP_KERNEL); if (!tmpBuf){ up(&index_lock[minor]); up(&read_lock[minor]); return -ENOMEM; } int numOfParts = ( (reading_position[minor] + numToRead) > BUF_SIZE) ? TWO : ONE ; char* source = tmpBuf; if(numOfParts == ONE ) { if (minor == 0) { encryptor(&buffer[minor][reading_position[minor]], tmpBuf, numToRead, key, minor); } else if(minor == 1){ // encryptor source = &buffer[minor][ reading_position[minor] ]; } retval = copy_to_user(buf, source, numToRead) ? -EFAULT : 0; reading_position[minor] = (reading_position[minor] + numToRead) % BUF_SIZE; } else { firstPartSize = BUF_SIZE - reading_position[minor]; if (minor == 0) { encryptor(&buffer[minor][ reading_position[minor] ], tmpBuf, firstPartSize, key, minor); encryptor(&buffer[minor][0],tmpBuf+firstPartSize , numToRead - firstPartSize, key, minor); } else if (minor == 1) { memcpy(tmpBuf, &buffer[minor][ reading_position[minor] ], firstPartSize); memcpy(tmpBuf+firstPartSize, &buffer[minor][0], numToRead - firstPartSize); } retval = copy_to_user(buf, tmpBuf, numToRead); reading_position[minor] = numToRead - firstPartSize; } kfree(tmpBuf); if(retval != 0){ up(&index_lock[minor]); up(&read_lock[minor]); return retval; } if((writing_position[minor] == reading_position[minor]) && numToRead){ flag_is_empty[minor] = 1; } if(numToRead != 0){ // if we have read SOMETHING, the buffer is not full anymore flag_is_full[minor] = 0; wake_up_interruptible(&write_wq[minor]); //Notifies any waiting writers that there is now room within the buffer } up(&index_lock[minor]); up(&read_lock[minor]); return numToRead; }