| /* |
| * Copyright (c) 2017 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <adc.h> |
| #include <syscall_handler.h> |
| #include <string.h> |
| |
| Z_SYSCALL_HANDLER(adc_enable, dev) |
| { |
| Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, enable)); |
| _impl_adc_enable((struct device *)dev); |
| return 0; |
| } |
| |
| Z_SYSCALL_HANDLER(adc_disable, dev) |
| { |
| Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, disable)); |
| _impl_adc_disable((struct device *)dev); |
| return 0; |
| } |
| |
| Z_SYSCALL_HANDLER(adc_read, dev, seq_table_p) |
| { |
| struct adc_seq_entry *entry, *entries_copy; |
| struct adc_seq_table *seq_table = (struct adc_seq_table *)seq_table_p; |
| struct adc_seq_table seq_table_copy; |
| unsigned int entries_bounds; |
| int i = 0, ret; |
| |
| Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, read)); |
| Z_OOPS(Z_SYSCALL_MEMORY_READ(seq_table, sizeof(struct adc_seq_table))); |
| |
| seq_table_copy = *seq_table; |
| if (Z_SYSCALL_VERIFY_MSG( |
| !__builtin_umul_overflow(seq_table_copy.num_entries, |
| sizeof(struct adc_seq_entry), |
| &entries_bounds), |
| "num_entries too large")) { |
| ret = -EINVAL; |
| goto out; |
| } |
| |
| Z_OOPS(Z_SYSCALL_MEMORY_READ(seq_table_copy.entries, entries_bounds)); |
| entries_copy = z_thread_malloc(entries_bounds); |
| if (!entries_copy) { |
| ret = -ENOMEM; |
| goto out; |
| } |
| |
| memcpy(entries_copy, seq_table_copy.entries, entries_bounds); |
| seq_table_copy.entries = entries_copy; |
| |
| for (entry = seq_table_copy.entries; i < seq_table_copy.num_entries; |
| i++, entry++) { |
| if (Z_SYSCALL_MEMORY_WRITE(entry->buffer, |
| entry->buffer_length)) { |
| k_free(entries_copy); |
| Z_OOPS(1); |
| } |
| } |
| |
| ret = _impl_adc_read((struct device *)dev, &seq_table_copy); |
| k_free(entries_copy); |
| out: |
| return ret; |
| } |