Skip to content

Commit

Permalink
pcie backend: fix throwing exception for small DMA transfers
Browse files Browse the repository at this point in the history
This was breaking the abstraction and is actually possible to implement. Real tests with actual hardware still need to be done. See #138
  • Loading branch information
mhier committed Apr 21, 2020
1 parent 6eaf188 commit 198d3ac
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 16 deletions.
30 changes: 16 additions & 14 deletions device_backends/pcie/src/PcieBackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,6 @@ namespace ChimeraTK {
throw ChimeraTK::logic_error("Device closed");
}

// safety check: the requested dma size (size of the data buffer) has to be at
// least
// the size of the dma struct, because the latter has to be copied into the
// data buffer.
if(sizeInBytes < sizeof(device_ioctrl_dma)) {
throw ChimeraTK::logic_error("Reqested dma size is too small");
}

// prepare the struct
device_ioctrl_dma DMA_RW;
DMA_RW.dma_cmd = 0; // FIXME: Why is it 0? => read driver code
Expand All @@ -273,12 +265,22 @@ namespace ChimeraTK {
DMA_RW.dma_reserved1 = 0; // FIXME: is this a correct value?
DMA_RW.dma_reserved2 = 0; // FIXME: is this a correct value?

// the ioctrl_dma struct is copied to the beginning of the data buffer,
// so the information about size and offset are passed to the driver.
memcpy((void*)data, &DMA_RW, sizeof(device_ioctrl_dma));
int ret = ioctl(_deviceID, _ioctlDMA, (void*)data);
if(ret) {
throw ChimeraTK::runtime_error(createErrorStringWithErrnoText("Cannot read data from device "));
if(sizeInBytes >= sizeof(device_ioctrl_dma)) {
// the ioctrl_dma struct is copied to the beginning of the data buffer,
// so the information about size and offset are passed to the driver.
memcpy((void*)data, &DMA_RW, sizeof(device_ioctrl_dma));
int ret = ioctl(_deviceID, _ioctlDMA, (void*)data);
if(ret) {
throw ChimeraTK::runtime_error(createErrorStringWithErrnoText("Cannot read data from device "));
}
}
else {
// the ioctrl_dma struct is used as a dma buffer and the read data is later copied out
int ret = ioctl(_deviceID, _ioctlDMA, (void*)&DMA_RW);
if(ret) {
throw ChimeraTK::runtime_error(createErrorStringWithErrnoText("Cannot read data from device "));
}
memcpy(&DMA_RW, (void*)data, sizeInBytes);
}
}

Expand Down
6 changes: 4 additions & 2 deletions tests/executables_src/testDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,10 @@ BOOST_AUTO_TEST_CASE(testCompatibilityLayer14) {
device->open(testBackend);
int32_t adcdata[2];
size_t dataSizeInBytes = 2 * 4;

BOOST_CHECK_THROW(device->readDMA("AREA_DMA_VIA_DMA", adcdata, dataSizeInBytes), ChimeraTK::logic_error);
// this test checks that small dma transfers are also possible... this wasn't the case before and the test expected
// a logic_error, but this would break abstraction.
device->readDMA("AREA_DMA_VIA_DMA", adcdata, dataSizeInBytes);
// todo check if data properly read?
}

BOOST_AUTO_TEST_CASE(testCompatibilityLayer15) {
Expand Down

0 comments on commit 198d3ac

Please sign in to comment.