Files
external_libcamera/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
Jacopo Mondi 2ad832fa6e libcamera: raspberrypi: dmaheaps: Improve device open
Improve the device opening at class construction time by testing all
the available device paths and printout the appropriate error message.

While at it, initialize dmaHeapHandle_ to -1 and check for its value
at destruction time.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-08-28 18:19:13 +02:00

97 lines
1.9 KiB
C++

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2020, Raspberry Pi (Trading) Limited
*
* dma_heaps.h - Helper class for dma-heap allocations.
*/
#include "dma_heaps.h"
#include <array>
#include <fcntl.h>
#include <linux/dma-buf.h>
#include <linux/dma-heap.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "libcamera/internal/log.h"
/*
* /dev/dma-heap/linux,cma is the dma-heap allocator, which allows dmaheap-cma
* to only have to worry about importing.
*
* Annoyingly, should the cma heap size be specified on the kernel command line
* instead of DT, the heap gets named "reserved" instead.
*/
static constexpr std::array<const char *, 2> heapNames = {
"/dev/dma_heap/linux,cma",
"/dev/dma_heap/reserved"
};
namespace libcamera {
LOG_DECLARE_CATEGORY(RPI)
namespace RPi {
DmaHeap::DmaHeap()
: dmaHeapHandle_(-1)
{
for (const char *name : heapNames) {
int ret = ::open(name, O_RDWR, 0);
if (ret < 0) {
ret = errno;
LOG(RPI, Debug) << "Failed to open " << name << ": "
<< strerror(ret);
continue;
}
dmaHeapHandle_ = ret;
break;
}
if (dmaHeapHandle_ < 0)
LOG(RPI, Error) << "Could not open any dmaHeap device";
}
DmaHeap::~DmaHeap()
{
if (dmaHeapHandle_ > -1)
::close(dmaHeapHandle_);
}
FileDescriptor DmaHeap::alloc(const char *name, std::size_t size)
{
int ret;
if (!name)
return FileDescriptor();
struct dma_heap_allocation_data alloc = {};
alloc.len = size;
alloc.fd_flags = O_CLOEXEC | O_RDWR;
ret = ::ioctl(dmaHeapHandle_, DMA_HEAP_IOCTL_ALLOC, &alloc);
if (ret < 0) {
LOG(RPI, Error) << "dmaHeap allocation failure for "
<< name;
return FileDescriptor();
}
ret = ::ioctl(alloc.fd, DMA_BUF_SET_NAME, name);
if (ret < 0) {
LOG(RPI, Error) << "dmaHeap naming failure for "
<< name;
::close(alloc.fd);
return FileDescriptor();
}
return FileDescriptor(std::move(alloc.fd));
}
} /* namespace RPi */
} /* namespace libcamera */