AbstractModuleDevice: Add generic read/write hooks via "io" hook.

This substitutes for the already-existing behavior of scsi_cd, scsi_disk,
and virtio_block, so we can delete their hooks and let them use
these new generic fallbacks.

Some other drivers perform clamping, and so using these fallbacks would
constitute a behavioral change.

Change-Id: I9a2e503f2e03abc276bdfc02d1cff1565a9742e9
This commit is contained in:
Augustin Cavalier
2023-04-27 16:24:08 -04:00
parent be67f14dcb
commit 103c671ef0
5 changed files with 43 additions and 149 deletions
@@ -761,46 +761,6 @@ cd_io(void* cookie, io_request* request)
} }
static status_t
cd_read(void* cookie, off_t pos, void* buffer, size_t* _length)
{
size_t length = *_length;
IORequest request;
status_t status = request.Init(pos, (addr_t)buffer, length, false, 0);
if (status != B_OK)
return status;
status = cd_io(cookie, &request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
*_length = request.TransferredBytes();
return status;
}
static status_t
cd_write(void* cookie, off_t pos, const void* buffer, size_t* _length)
{
size_t length = *_length;
IORequest request;
status_t status = request.Init(pos, (addr_t)buffer, length, true, 0);
if (status != B_OK)
return status;
status = cd_io(cookie, &request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
*_length = request.TransferredBytes();
return status;
}
static status_t static status_t
cd_ioctl(void* cookie, uint32 op, void* buffer, size_t length) cd_ioctl(void* cookie, uint32 op, void* buffer, size_t length)
{ {
@@ -1186,8 +1146,8 @@ struct device_module_info sSCSICDDevice = {
cd_open, cd_open,
cd_close, cd_close,
cd_free, cd_free,
cd_read, NULL, // read
cd_write, NULL, // write
cd_io, cd_io,
cd_ioctl, cd_ioctl,
@@ -325,54 +325,6 @@ das_free(void* cookie)
} }
static status_t
das_read(void* cookie, off_t pos, void* buffer, size_t* _length)
{
das_handle* handle = (das_handle*)cookie;
size_t length = *_length;
IORequest request;
status_t status = request.Init(pos, (addr_t)buffer, length, false, 0);
if (status != B_OK)
return status;
status = handle->info->io_scheduler->ScheduleRequest(&request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
*_length = request.TransferredBytes();
if (status != B_OK)
dprintf("das_read: request.Wait() returned: %s\n", strerror(status));
return status;
}
static status_t
das_write(void* cookie, off_t pos, const void* buffer, size_t* _length)
{
das_handle* handle = (das_handle*)cookie;
size_t length = *_length;
IORequest request;
status_t status = request.Init(pos, (addr_t)buffer, length, true, 0);
if (status != B_OK)
return status;
status = handle->info->io_scheduler->ScheduleRequest(&request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
*_length = request.TransferredBytes();
if (status != B_OK)
dprintf("das_write: request.Wait() returned: %s\n", strerror(status));
return status;
}
static status_t static status_t
das_io(void *cookie, io_request *request) das_io(void *cookie, io_request *request)
{ {
@@ -702,8 +654,8 @@ struct device_module_info sSCSIDiskDevice = {
das_open, das_open,
das_close, das_close,
das_free, das_free,
das_read, NULL, // read
das_write, NULL, // write
das_io, das_io,
das_ioctl, das_ioctl,
@@ -335,57 +335,6 @@ virtio_block_free(void* cookie)
} }
static status_t
virtio_block_read(void* cookie, off_t pos, void* buffer, size_t* _length)
{
CALLED();
virtio_block_handle* handle = (virtio_block_handle*)cookie;
size_t length = *_length;
IORequest request;
status_t status = request.Init(pos, (addr_t)buffer, length, false, 0);
if (status != B_OK)
return status;
status = handle->info->io_scheduler->ScheduleRequest(&request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
*_length = request.TransferredBytes();
if (status != B_OK)
dprintf("virtio_block_read: request.Wait() returned: %s\n", strerror(status));
return status;
}
static status_t
virtio_block_write(void* cookie, off_t pos, const void* buffer,
size_t* _length)
{
CALLED();
virtio_block_handle* handle = (virtio_block_handle*)cookie;
size_t length = *_length;
IORequest request;
status_t status = request.Init(pos, (addr_t)buffer, length, true, 0);
if (status != B_OK)
return status;
status = handle->info->io_scheduler->ScheduleRequest(&request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
*_length = request.TransferredBytes();
if (status != B_OK)
dprintf("virtio_block_write: request.Wait() returned: %s\n", strerror(status));
return status;
}
static status_t static status_t
virtio_block_io(void *cookie, io_request *request) virtio_block_io(void *cookie, io_request *request)
{ {
@@ -655,8 +604,8 @@ struct device_module_info sVirtioBlockDevice = {
virtio_block_open, virtio_block_open,
virtio_block_close, virtio_block_close,
virtio_block_free, virtio_block_free,
virtio_block_read, NULL, // read
virtio_block_write, NULL, // write
virtio_block_io, virtio_block_io,
virtio_block_ioctl, virtio_block_ioctl,
@@ -7,6 +7,8 @@
#include "AbstractModuleDevice.h" #include "AbstractModuleDevice.h"
#include "IORequest.h"
AbstractModuleDevice::AbstractModuleDevice() AbstractModuleDevice::AbstractModuleDevice()
: :
@@ -65,11 +67,34 @@ AbstractModuleDevice::Open(const char* path, int openMode, void** _cookie)
} }
status_t
AbstractModuleDevice::_DoIO(void* cookie, off_t pos,
void* buffer, size_t* _length, bool isWrite)
{
IORequest request;
status_t status = request.Init(pos, (addr_t)buffer, *_length, isWrite, 0);
if (status != B_OK)
return status;
status = IO(cookie, &request);
if (status != B_OK)
return status;
status = request.Wait(0, 0);
*_length = request.TransferredBytes();
return status;
}
status_t status_t
AbstractModuleDevice::Read(void* cookie, off_t pos, void* buffer, size_t* _length) AbstractModuleDevice::Read(void* cookie, off_t pos, void* buffer, size_t* _length)
{ {
if (Module()->read == NULL) if (Module()->read == NULL) {
return BaseDevice::Read(cookie, pos, buffer, _length); if (Module()->io == NULL)
return BaseDevice::Read(cookie, pos, buffer, _length);
return _DoIO(cookie, pos, buffer, _length, false);
}
return Module()->read(cookie, pos, buffer, _length); return Module()->read(cookie, pos, buffer, _length);
} }
@@ -77,8 +102,12 @@ AbstractModuleDevice::Read(void* cookie, off_t pos, void* buffer, size_t* _lengt
status_t status_t
AbstractModuleDevice::Write(void* cookie, off_t pos, const void* buffer, size_t* _length) AbstractModuleDevice::Write(void* cookie, off_t pos, const void* buffer, size_t* _length)
{ {
if (Module()->write == NULL) if (Module()->write == NULL) {
return BaseDevice::Write(cookie, pos, buffer, _length); if (Module()->io == NULL)
return BaseDevice::Write(cookie, pos, buffer, _length);
return _DoIO(cookie, pos, const_cast<void*>(buffer), _length, true);
}
return Module()->write(cookie, pos, buffer, _length); return Module()->write(cookie, pos, buffer, _length);
} }
@@ -45,6 +45,10 @@ public:
virtual status_t Close(void* cookie); virtual status_t Close(void* cookie);
virtual status_t Free(void* cookie); virtual status_t Free(void* cookie);
protected:
status_t _DoIO(void* cookie, off_t pos,
void* buffer, size_t* _length, bool isWrite);
protected: protected:
device_node* fNode; device_node* fNode;
int32 fInitialized; int32 fInitialized;