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:
parent
b3a0911eb7
commit
ed4a8e4d11
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue