Merge changes Ie9dd5d5d,Ifc6038c1
am: 0cde0eae09
Change-Id: Ie402e720388b35daed0f704992686f4b84bc5736
This commit is contained in:
commit
5fb6ef6b7a
|
@ -14,7 +14,7 @@
|
|||
|
||||
cc_library_static {
|
||||
name: "libadf",
|
||||
srcs: ["adf.c"],
|
||||
srcs: ["adf.cpp"],
|
||||
cflags: ["-Werror"],
|
||||
local_include_dirs: ["include"],
|
||||
export_include_dirs: ["include"],
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <linux/limits.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -31,52 +35,44 @@
|
|||
|
||||
#define ADF_BASE_PATH "/dev/"
|
||||
|
||||
static ssize_t adf_find_nodes(const char *pattern, adf_id_t **ids)
|
||||
static ssize_t adf_id_vector_to_array(const std::vector<adf_id_t> &in,
|
||||
adf_id_t **out)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *dirent;
|
||||
size_t n = 0;
|
||||
ssize_t ret;
|
||||
adf_id_t *ids_ret = NULL;
|
||||
auto size = sizeof(in[0]) * in.size();
|
||||
// We can't use new[] since the existing API says the caller should free()
|
||||
// the returned array
|
||||
auto ret = static_cast<adf_id_t *>(malloc(size));
|
||||
if (!ret)
|
||||
return -ENOMEM;
|
||||
|
||||
dir = opendir(ADF_BASE_PATH);
|
||||
std::copy(in.begin(), in.end(), ret);
|
||||
*out = ret;
|
||||
return in.size();
|
||||
}
|
||||
|
||||
static ssize_t adf_find_nodes(const char *pattern, adf_id_t **ids_out)
|
||||
{
|
||||
struct dirent *dirent;
|
||||
std::unique_ptr<DIR, decltype(&closedir)>
|
||||
dir{opendir(ADF_BASE_PATH), closedir};
|
||||
if (!dir)
|
||||
return -errno;
|
||||
|
||||
std::vector<adf_id_t> ids;
|
||||
errno = 0;
|
||||
while ((dirent = readdir(dir))) {
|
||||
while ((dirent = readdir(dir.get()))) {
|
||||
adf_id_t id;
|
||||
int matched = sscanf(dirent->d_name, pattern, &id);
|
||||
|
||||
if (matched < 0) {
|
||||
ret = -errno;
|
||||
goto done;
|
||||
} else if (matched != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
|
||||
if (!new_ids) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ids_ret = new_ids;
|
||||
ids_ret[n] = id;
|
||||
n++;
|
||||
if (matched < 0)
|
||||
return -errno;
|
||||
else if (matched == 1)
|
||||
ids.push_back(id);
|
||||
}
|
||||
if (errno)
|
||||
ret = -errno;
|
||||
else
|
||||
ret = n;
|
||||
return -errno;
|
||||
|
||||
done:
|
||||
closedir(dir);
|
||||
if (ret < 0)
|
||||
free(ids_ret);
|
||||
else
|
||||
*ids = ids_ret;
|
||||
return ret;
|
||||
return adf_id_vector_to_array(ids, ids_out);
|
||||
}
|
||||
|
||||
ssize_t adf_devices(adf_id_t **ids)
|
||||
|
@ -115,46 +111,29 @@ int adf_get_device_data(struct adf_device *dev, struct adf_device_data *data)
|
|||
if (err < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if (data->n_attachments) {
|
||||
data->attachments = malloc(sizeof(data->attachments[0]) *
|
||||
data->n_attachments);
|
||||
if (!data->attachments)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (data->n_attachments)
|
||||
data->attachments = new adf_attachment_config[data->n_attachments];
|
||||
|
||||
if (data->n_allowed_attachments) {
|
||||
if (data->n_allowed_attachments)
|
||||
data->allowed_attachments =
|
||||
malloc(sizeof(data->allowed_attachments[0]) *
|
||||
data->n_allowed_attachments);
|
||||
if (!data->allowed_attachments) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
new adf_attachment_config[data->n_allowed_attachments];
|
||||
|
||||
if (data->custom_data_size) {
|
||||
data->custom_data = malloc(data->custom_data_size);
|
||||
if (!data->custom_data) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (data->custom_data_size)
|
||||
data->custom_data = new char[data->custom_data_size];
|
||||
|
||||
err = ioctl(dev->fd, ADF_GET_DEVICE_DATA, data);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
ret = -errno;
|
||||
|
||||
done:
|
||||
if (ret < 0)
|
||||
adf_free_device_data(data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void adf_free_device_data(struct adf_device_data *data)
|
||||
{
|
||||
free(data->attachments);
|
||||
free(data->allowed_attachments);
|
||||
free(data->custom_data);
|
||||
delete [] data->attachments;
|
||||
delete [] data->allowed_attachments;
|
||||
delete [] static_cast<char *>(data->custom_data);
|
||||
}
|
||||
|
||||
int adf_device_post(struct adf_device *dev,
|
||||
|
@ -252,39 +231,17 @@ ssize_t adf_interfaces_for_overlay_engine(struct adf_device *dev,
|
|||
adf_id_t overlay_engine, adf_id_t **interfaces)
|
||||
{
|
||||
struct adf_device_data data;
|
||||
ssize_t n = 0;
|
||||
ssize_t ret;
|
||||
adf_id_t *ids_ret = NULL;
|
||||
auto err = adf_get_device_data(dev, &data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
ret = adf_get_device_data(dev, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
std::vector<adf_id_t> ids;
|
||||
for (size_t i = 0; i < data.n_allowed_attachments; i++)
|
||||
if (data.allowed_attachments[i].overlay_engine == overlay_engine)
|
||||
ids.push_back(data.allowed_attachments[i].interface);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < data.n_allowed_attachments; i++) {
|
||||
if (data.allowed_attachments[i].overlay_engine != overlay_engine)
|
||||
continue;
|
||||
|
||||
adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
|
||||
if (!new_ids) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ids_ret = new_ids;
|
||||
ids_ret[n] = data.allowed_attachments[i].interface;
|
||||
n++;
|
||||
}
|
||||
|
||||
ret = n;
|
||||
|
||||
done:
|
||||
adf_free_device_data(&data);
|
||||
if (ret < 0)
|
||||
free(ids_ret);
|
||||
else
|
||||
*interfaces = ids_ret;
|
||||
return ret;
|
||||
return adf_id_vector_to_array(ids, interfaces);
|
||||
}
|
||||
|
||||
static ssize_t adf_interfaces_filter(struct adf_device *dev,
|
||||
|
@ -292,46 +249,23 @@ static ssize_t adf_interfaces_filter(struct adf_device *dev,
|
|||
bool (*filter)(struct adf_interface_data *data, __u32 match),
|
||||
__u32 match)
|
||||
{
|
||||
size_t n = 0;
|
||||
ssize_t ret;
|
||||
adf_id_t *ids_ret = NULL;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < n_in; i++) {
|
||||
std::vector<adf_id_t> ids;
|
||||
for (size_t i = 0; i < n_in; i++) {
|
||||
int fd = adf_interface_open(dev, in[i], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ret = fd;
|
||||
goto done;
|
||||
}
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
struct adf_interface_data data;
|
||||
ret = adf_get_interface_data(fd, &data);
|
||||
auto ret = adf_get_interface_data(fd, &data);
|
||||
close(fd);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
return ret;
|
||||
|
||||
if (!filter(&data, match))
|
||||
continue;
|
||||
|
||||
adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
|
||||
if (!new_ids) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ids_ret = new_ids;
|
||||
ids_ret[n] = in[i];
|
||||
n++;
|
||||
if (filter(&data, match))
|
||||
ids.push_back(in[i]);
|
||||
}
|
||||
|
||||
ret = n;
|
||||
|
||||
done:
|
||||
if (ret < 0)
|
||||
free(ids_ret);
|
||||
else
|
||||
*out = ids_ret;
|
||||
return ret;
|
||||
return adf_id_vector_to_array(ids, out);
|
||||
}
|
||||
|
||||
static bool adf_interface_type_filter(struct adf_interface_data *data,
|
||||
|
@ -385,35 +319,24 @@ int adf_get_interface_data(int fd, struct adf_interface_data *data)
|
|||
if (err < 0)
|
||||
return -errno;
|
||||
|
||||
if (data->n_available_modes) {
|
||||
data->available_modes = malloc(sizeof(data->available_modes[0]) *
|
||||
data->n_available_modes);
|
||||
if (!data->available_modes)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (data->n_available_modes)
|
||||
data->available_modes = new drm_mode_modeinfo[data->n_available_modes];
|
||||
|
||||
if (data->custom_data_size) {
|
||||
data->custom_data = malloc(data->custom_data_size);
|
||||
if (!data->custom_data) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (data->custom_data_size)
|
||||
data->custom_data = new char[data->custom_data_size];
|
||||
|
||||
err = ioctl(fd, ADF_GET_INTERFACE_DATA, data);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
ret = -errno;
|
||||
|
||||
done:
|
||||
if (ret < 0)
|
||||
adf_free_interface_data(data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void adf_free_interface_data(struct adf_interface_data *data)
|
||||
{
|
||||
free(data->available_modes);
|
||||
free(data->custom_data);
|
||||
delete [] data->available_modes;
|
||||
delete [] static_cast<char *>(data->custom_data);
|
||||
}
|
||||
|
||||
int adf_interface_blank(int fd, __u8 mode)
|
||||
|
@ -522,39 +445,16 @@ ssize_t adf_overlay_engines_for_interface(struct adf_device *dev,
|
|||
adf_id_t interface, adf_id_t **overlay_engines)
|
||||
{
|
||||
struct adf_device_data data;
|
||||
ssize_t n = 0;
|
||||
ssize_t ret;
|
||||
adf_id_t *ids_ret = NULL;
|
||||
auto err = adf_get_device_data(dev, &data);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
ret = adf_get_device_data(dev, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
std::vector<adf_id_t> ids;
|
||||
for (size_t i = 0; i < data.n_allowed_attachments; i++)
|
||||
if (data.allowed_attachments[i].interface == interface)
|
||||
ids.push_back(data.allowed_attachments[i].overlay_engine);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < data.n_allowed_attachments; i++) {
|
||||
if (data.allowed_attachments[i].interface != interface)
|
||||
continue;
|
||||
|
||||
adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
|
||||
if (!new_ids) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ids_ret = new_ids;
|
||||
ids_ret[n] = data.allowed_attachments[i].overlay_engine;
|
||||
n++;
|
||||
}
|
||||
|
||||
ret = n;
|
||||
|
||||
done:
|
||||
adf_free_device_data(&data);
|
||||
if (ret < 0)
|
||||
free(ids_ret);
|
||||
else
|
||||
*overlay_engines = ids_ret;
|
||||
return ret;
|
||||
return adf_id_vector_to_array(ids, overlay_engines);
|
||||
}
|
||||
|
||||
static ssize_t adf_overlay_engines_filter(struct adf_device *dev,
|
||||
|
@ -562,46 +462,24 @@ static ssize_t adf_overlay_engines_filter(struct adf_device *dev,
|
|||
bool (*filter)(struct adf_overlay_engine_data *data, void *cookie),
|
||||
void *cookie)
|
||||
{
|
||||
size_t n = 0;
|
||||
ssize_t ret;
|
||||
adf_id_t *ids_ret = NULL;
|
||||
|
||||
std::vector<adf_id_t> ids;
|
||||
size_t i;
|
||||
for (i = 0; i < n_in; i++) {
|
||||
int fd = adf_overlay_engine_open(dev, in[i], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ret = fd;
|
||||
goto done;
|
||||
}
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
struct adf_overlay_engine_data data;
|
||||
ret = adf_get_overlay_engine_data(fd, &data);
|
||||
auto ret = adf_get_overlay_engine_data(fd, &data);
|
||||
close(fd);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
return ret;
|
||||
|
||||
if (!filter(&data, cookie))
|
||||
continue;
|
||||
|
||||
adf_id_t *new_ids = realloc(ids_ret, (n + 1) * sizeof(ids_ret[0]));
|
||||
if (!new_ids) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ids_ret = new_ids;
|
||||
ids_ret[n] = in[i];
|
||||
n++;
|
||||
if (filter(&data, cookie))
|
||||
ids.push_back(in[i]);
|
||||
}
|
||||
|
||||
ret = n;
|
||||
|
||||
done:
|
||||
if (ret < 0)
|
||||
free(ids_ret);
|
||||
else
|
||||
*out = ids_ret;
|
||||
return ret;
|
||||
return adf_id_vector_to_array(ids, out);
|
||||
}
|
||||
|
||||
struct format_filter_cookie {
|
||||
|
@ -612,7 +490,7 @@ struct format_filter_cookie {
|
|||
static bool adf_overlay_engine_format_filter(
|
||||
struct adf_overlay_engine_data *data, void *cookie)
|
||||
{
|
||||
struct format_filter_cookie *c = cookie;
|
||||
auto c = static_cast<format_filter_cookie *>(cookie);
|
||||
size_t i;
|
||||
for (i = 0; i < data->n_supported_formats; i++) {
|
||||
size_t j;
|
||||
|
@ -656,35 +534,24 @@ int adf_get_overlay_engine_data(int fd, struct adf_overlay_engine_data *data)
|
|||
if (err < 0)
|
||||
return -errno;
|
||||
|
||||
if (data->n_supported_formats) {
|
||||
data->supported_formats = malloc(sizeof(data->supported_formats[0]) *
|
||||
data->n_supported_formats);
|
||||
if (!data->supported_formats)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (data->n_supported_formats)
|
||||
data->supported_formats = new __u32[data->n_supported_formats];
|
||||
|
||||
if (data->custom_data_size) {
|
||||
data->custom_data = malloc(data->custom_data_size);
|
||||
if (!data->custom_data) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (data->custom_data_size)
|
||||
data->custom_data = new char[data->custom_data_size];
|
||||
|
||||
err = ioctl(fd, ADF_GET_OVERLAY_ENGINE_DATA, data);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
ret = -errno;
|
||||
|
||||
done:
|
||||
if (ret < 0)
|
||||
adf_free_overlay_engine_data(data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void adf_free_overlay_engine_data(struct adf_overlay_engine_data *data)
|
||||
{
|
||||
free(data->supported_formats);
|
||||
free(data->custom_data);
|
||||
delete [] data->supported_formats;
|
||||
delete [] static_cast<char *>(data->custom_data);
|
||||
}
|
||||
|
||||
bool adf_overlay_engine_supports_format(int fd, __u32 format)
|
||||
|
@ -724,12 +591,12 @@ int adf_set_event(int fd, enum adf_event_type type, bool enabled)
|
|||
int adf_read_event(int fd, struct adf_event **event)
|
||||
{
|
||||
struct adf_event header;
|
||||
struct {
|
||||
struct event_with_data {
|
||||
struct adf_event base;
|
||||
uint8_t data[0];
|
||||
} *event_ret;
|
||||
};
|
||||
using unique_event = std::unique_ptr<event_with_data, decltype(&free)>;
|
||||
size_t data_size;
|
||||
int ret = 0;
|
||||
|
||||
int err = read(fd, &header, sizeof(header));
|
||||
if (err < 0)
|
||||
|
@ -739,28 +606,23 @@ int adf_read_event(int fd, struct adf_event **event)
|
|||
if (header.length < sizeof(header))
|
||||
return -EIO;
|
||||
|
||||
event_ret = malloc(header.length);
|
||||
// Again, we can't use new[] since the existing API says the caller should
|
||||
// free() the returned event
|
||||
auto event_ptr = static_cast<event_with_data *>(malloc(header.length));
|
||||
unique_event event_ret{event_ptr, free};
|
||||
if (!event_ret)
|
||||
return -ENOMEM;
|
||||
data_size = header.length - sizeof(header);
|
||||
|
||||
memcpy(event_ret, &header, sizeof(header));
|
||||
memcpy(event_ret.get(), &header, sizeof(header));
|
||||
ssize_t read_size = read(fd, &event_ret->data, data_size);
|
||||
if (read_size < 0) {
|
||||
ret = -errno;
|
||||
goto done;
|
||||
}
|
||||
if ((size_t)read_size < data_size) {
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
}
|
||||
if (read_size < 0)
|
||||
return -errno;
|
||||
if ((size_t)read_size < data_size)
|
||||
return -EIO;
|
||||
|
||||
*event = &event_ret->base;
|
||||
|
||||
done:
|
||||
if (ret < 0)
|
||||
free(event_ret);
|
||||
return ret;
|
||||
*event = &event_ret.release()->base;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adf_format_str(__u32 format, char buf[ADF_FORMAT_STR_SIZE])
|
|
@ -188,7 +188,7 @@ const __u32 AdfTest::fmt8888[] = {
|
|||
const size_t AdfTest::n_fmt8888 = sizeof(fmt8888) / sizeof(fmt8888[0]);
|
||||
|
||||
TEST(adf, devices) {
|
||||
adf_id_t *devs;
|
||||
adf_id_t *devs = nullptr;
|
||||
ssize_t n_devs = adf_devices(&devs);
|
||||
free(devs);
|
||||
|
||||
|
|
Loading…
Reference in New Issue