From ed4a8e4d11d7972d6fb6f025c108915ad06c73af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Wed, 17 Jul 2013 17:30:18 +0200 Subject: [PATCH] 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. --- headers/private/virtio/virtio.h | 4 ++-- .../bus_managers/virtio/VirtioDevice.cpp | 12 +++++++----- .../bus_managers/virtio/VirtioModule.cpp | 4 ++-- .../bus_managers/virtio/VirtioPrivate.h | 19 ++++++++++++------- .../bus_managers/virtio/VirtioQueue.cpp | 15 +++++++++------ .../scsi/virtio/VirtioSCSIController.cpp | 12 ++++++------ .../busses/scsi/virtio/VirtioSCSIPrivate.h | 5 +++-- .../virtual/virtio_block/virtio_block.cpp | 2 +- 8 files changed, 42 insertions(+), 31 deletions(-) diff --git a/headers/private/virtio/virtio.h b/headers/private/virtio/virtio.h index 94642c9c7f..fffe0d7512 100644 --- a/headers/private/virtio/virtio.h +++ b/headers/private/virtio/virtio.h @@ -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, diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp b/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp index 03c514a8ce..d2a12f0f13 100644 --- a/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp @@ -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; } diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp b/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp index 8229fc7e8c..de6328e867 100644 --- a/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp @@ -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); } diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h b/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h index 1b312015f9..4097bdd556 100644 --- a/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h @@ -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, diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp b/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp index 5133348170..6f8acf3dc2 100644 --- a/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp @@ -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; diff --git a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp index dcde6c8589..d66d2ce348 100644 --- a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp +++ b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp @@ -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(); diff --git a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIPrivate.h b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIPrivate.h index 0dddad1fcf..8e48c01a9d 100644 --- a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIPrivate.h +++ b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIPrivate.h @@ -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; diff --git a/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_block.cpp b/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_block.cpp index 0fa462d92e..131b527233 100644 --- a/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_block.cpp +++ b/src/add-ons/kernel/drivers/disk/virtual/virtio_block/virtio_block.cpp @@ -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;