virtio: changed a bit the driver API by adding a driverCookie.

* the processing of requests in drivers is eased a bit with this change, but
this could be improved for instance by enabling a driver to dequeue items
in a service thread instead of the interrupt handler.
* made a few methods const.
This commit is contained in:
Jérôme Duval 2013-07-17 17:30:18 +02:00
parent b3a0911eb7
commit ed4a8e4d11
8 changed files with 42 additions and 31 deletions

View File

@ -53,7 +53,7 @@ typedef void* virtio_device;
// queue cookie, issued by virtio bus manager
typedef void* virtio_queue;
// callback function for requests
typedef void (*virtio_callback_func)(void *cookie);
typedef void (*virtio_callback_func)(void* driverCookie, void *cookie);
// callback function for interrupts
typedef void (*virtio_intr_func)(void *cookie);
@ -105,7 +105,7 @@ typedef struct {
virtio_queue *queues);
status_t (*setup_interrupt)(virtio_device cookie,
virtio_intr_func config_handler, void* configCookie);
virtio_intr_func config_handler, void* driverCookie);
status_t (*queue_request)(virtio_queue queue,
const physical_entry *readEntry,

View File

@ -58,7 +58,10 @@ VirtioDevice::VirtioDevice(device_node *node)
fCookie(NULL),
fStatus(B_NO_INIT),
fQueues(NULL),
fFeatures(0)
fFeatures(0),
fAlignment(0),
fConfigHandler(NULL),
fDriverCookie(NULL)
{
device_node *parent = gDeviceManager->get_parent_node(node);
fStatus = gDeviceManager->get_driver(parent,
@ -172,11 +175,10 @@ err:
status_t
VirtioDevice::SetupInterrupt(virtio_intr_func configHandler,
void* configCookie)
VirtioDevice::SetupInterrupt(virtio_intr_func configHandler, void *driverCookie)
{
fConfigHandler = configHandler;
fConfigCookie = configCookie;
fDriverCookie = driverCookie;
status_t status = fController->setup_interrupt(fCookie, fQueueCount);
if (status != B_OK)
return status;
@ -228,7 +230,7 @@ status_t
VirtioDevice::ConfigInterrupt()
{
if (fConfigHandler != NULL)
fConfigHandler(fConfigCookie);
fConfigHandler(fDriverCookie);
return B_OK;
}

View File

@ -96,11 +96,11 @@ virtio_alloc_queues(virtio_device cookie, size_t count, virtio_queue *queues)
status_t
virtio_setup_interrupt(virtio_device cookie, virtio_intr_func config_handler,
void* configCookie)
void *driverCookie)
{
CALLED();
VirtioDevice *device = (VirtioDevice *)cookie;
return device->SetupInterrupt(config_handler, configCookie);
return device->SetupInterrupt(config_handler, driverCookie);
}

View File

@ -23,7 +23,8 @@
#else
# define TRACE(x...)
#endif
#define ERROR(x...) dprintf("\33[33mvirtio:\33[0m " x)
#define TRACE_ALWAYS(x...) dprintf("\33[33mvirtio:\33[0m " x)
#define ERROR(x...) TRACE_ALWAYS(x)
#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
@ -56,10 +57,12 @@ public:
status_t AllocateQueues(size_t count,
virtio_queue *queues);
status_t SetupInterrupt(virtio_intr_func config_handler,
void* configCookie);
void *driverCookie);
uint16 Alignment() { return fAlignment; }
uint32 Features() { return fFeatures; }
uint16 Alignment() const { return fAlignment; }
uint32 Features() const { return fFeatures; }
void* DriverCookie() { return fDriverCookie; }
status_t SetupQueue(uint16 queueNumber,
phys_addr_t physAddr);
@ -85,7 +88,7 @@ private:
uint16 fAlignment;
virtio_intr_func fConfigHandler;
void* fConfigCookie;
void* fDriverCookie;
};
@ -102,8 +105,10 @@ public:
void NotifyHost();
status_t Interrupt();
bool IsFull() { return fRingFree == 0; }
bool IsEmpty() { return fRingFree == fRingSize; }
bool IsFull() const { return fRingFree == 0; }
bool IsEmpty() const { return fRingFree == fRingSize; }
VirtioDevice* Device() { return fDevice; }
status_t QueueRequest(const physical_entry* vector,
size_t readVectorCount,

View File

@ -50,7 +50,8 @@ alloc_mem(void **virt, phys_addr_t *phy, size_t size, uint32 protection,
class TransferDescriptor {
public:
TransferDescriptor(uint16 size,
TransferDescriptor(VirtioQueue* queue,
uint16 size,
virtio_callback_func callback,
void *callbackCookie);
~TransferDescriptor();
@ -58,6 +59,7 @@ public:
void Callback();
uint16 Size() { return fDescriptorCount; }
private:
VirtioQueue* fQueue;
void* fCookie;
virtio_callback_func fCallback;
struct vring_desc* fIndirect;
@ -67,9 +69,10 @@ private:
};
TransferDescriptor::TransferDescriptor(uint16 size,
TransferDescriptor::TransferDescriptor(VirtioQueue* queue, uint16 size,
virtio_callback_func callback, void *callbackCookie)
: fCookie(callbackCookie),
: fQueue(queue),
fCookie(callbackCookie),
fCallback(callback),
fDescriptorCount(size)
{
@ -85,7 +88,7 @@ void
TransferDescriptor::Callback()
{
if (fCallback != NULL)
fCallback(fCookie);
fCallback(fQueue->Device()->DriverCookie(), fCookie);
}
@ -226,8 +229,8 @@ VirtioQueue::QueueRequest(const physical_entry* vector, size_t readVectorCount,
return B_BUSY;
uint16 insertIndex = fRingHeadIndex;
fDescriptors[insertIndex] = new(std::nothrow) TransferDescriptor(count,
callback, callbackCookie);
fDescriptors[insertIndex] = new(std::nothrow) TransferDescriptor(this,
count, callback, callbackCookie);
if (fDescriptors[insertIndex] == NULL)
return B_NO_MEMORY;

View File

@ -84,7 +84,7 @@ VirtioSCSIController::VirtioSCSIController(device_node *node)
fEventVirtioQueue = virtioQueues[1];
fRequestVirtioQueue = virtioQueues[2];
fStatus = fVirtio->setup_interrupt(fVirtioDevice, NULL, NULL);
fStatus = fVirtio->setup_interrupt(fVirtioDevice, NULL, this);
if (fStatus != B_OK) {
ERROR("interrupt setup failed (%s)\n", strerror(fStatus));
return;
@ -206,7 +206,7 @@ VirtioSCSIController::ExecuteRequest(scsi_ccb *ccb)
}
fVirtio->queue_request_v(fRequestVirtioQueue, entries,
outCount, inCount, VirtioSCSIController::RequestCallback, this);
outCount, inCount, VirtioSCSIController::_RequestCallback, NULL);
result = fInterruptConditionEntry.Wait(B_RELATIVE_TIMEOUT,
fRequest->Timeout());
@ -247,16 +247,16 @@ VirtioSCSIController::Control(uint8 targetID, uint32 op, void *buffer,
void
VirtioSCSIController::RequestCallback(void* cookie)
VirtioSCSIController::_RequestCallback(void* driverCookie, void* cookie)
{
CALLED();
VirtioSCSIController* controller = (VirtioSCSIController*)cookie;
controller->_Interrupt();
VirtioSCSIController* controller = (VirtioSCSIController*)driverCookie;
controller->_RequestInterrupt();
}
void
VirtioSCSIController::_Interrupt()
VirtioSCSIController::_RequestInterrupt()
{
SpinLocker locker(fInterruptLock);
fInterruptCondition.NotifyAll();

View File

@ -60,8 +60,9 @@ public:
void* buffer, size_t length);
private:
static void RequestCallback(void *cookie);
void _Interrupt();
static void _RequestCallback(void* driverCookie,
void *cookie);
void _RequestInterrupt();
device_node* fNode;
scsi_bus fBus;

View File

@ -160,7 +160,7 @@ log2(uint32 x)
static void
virtio_block_callback(void* cookie)
virtio_block_callback(void* driverCookie, void* cookie)
{
virtio_block_driver_info* info = (virtio_block_driver_info*)cookie;