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
cd_ioctl(void* cookie, uint32 op, void* buffer, size_t length)
{
@@ -1186,8 +1146,8 @@ struct device_module_info sSCSICDDevice = {
cd_open,
cd_close,
cd_free,
cd_read,
cd_write,
NULL, // read
NULL, // write
cd_io,
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
das_io(void *cookie, io_request *request)
{
@@ -702,8 +654,8 @@ struct device_module_info sSCSIDiskDevice = {
das_open,
das_close,
das_free,
das_read,
das_write,
NULL, // read
NULL, // write
das_io,
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
virtio_block_io(void *cookie, io_request *request)
{
@@ -655,8 +604,8 @@ struct device_module_info sVirtioBlockDevice = {
virtio_block_open,
virtio_block_close,
virtio_block_free,
virtio_block_read,
virtio_block_write,
NULL, // read
NULL, // write
virtio_block_io,
virtio_block_ioctl,
@@ -7,6 +7,8 @@
#include "AbstractModuleDevice.h"
#include "IORequest.h"
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
AbstractModuleDevice::Read(void* cookie, off_t pos, void* buffer, size_t* _length)
{
if (Module()->read == NULL)
return BaseDevice::Read(cookie, pos, buffer, _length);
if (Module()->read == NULL) {
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);
}
@@ -77,8 +102,12 @@ AbstractModuleDevice::Read(void* cookie, off_t pos, void* buffer, size_t* _lengt
status_t
AbstractModuleDevice::Write(void* cookie, off_t pos, const void* buffer, size_t* _length)
{
if (Module()->write == NULL)
return BaseDevice::Write(cookie, pos, buffer, _length);
if (Module()->write == NULL) {
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);
}
@@ -45,6 +45,10 @@ public:
virtual status_t Close(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:
device_node* fNode;
int32 fInitialized;