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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user