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
|
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) {
|
||||||
|
if (Module()->io == NULL)
|
||||||
return BaseDevice::Read(cookie, pos, buffer, _length);
|
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) {
|
||||||
|
if (Module()->io == NULL)
|
||||||
return BaseDevice::Write(cookie, pos, buffer, _length);
|
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;
|
||||||
|
|||||||
Reference in New Issue
Block a user