1/* 2 * Copyright 2021, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef _VIRTIODEVICE_H_ 6#define _VIRTIODEVICE_H_ 7 8 9#include <virtio.h> 10#include <virtio_defs.h> 11#include <AutoDeleter.h> 12#include <AutoDeleterOS.h> 13#include <Referenceable.h> 14#include <util/AutoLock.h> 15#include <util/Bitmap.h> 16 17 18//#define TRACE_VIRTIO 19#ifdef TRACE_VIRTIO 20# define TRACE(x...) dprintf("virtio_mmio: " x) 21#else 22# define TRACE(x...) ; 23#endif 24 25#define TRACE_ALWAYS(x...) dprintf("virtio_mmio: " x) 26#define ERROR(x...) dprintf("virtio_mmio: " x) 27 28 29struct VirtioIrqHandler; 30struct VirtioDevice; 31 32struct VirtioQueue { 33 VirtioDevice *fDev; 34 int32 fId; 35 size_t fQueueLen; 36 size_t fDescCount; 37 AreaDeleter fArea; 38 volatile VirtioDesc *fDescs; 39 volatile VirtioAvail *fAvail; 40 volatile VirtioUsed *fUsed; 41 Bitmap fAllocatedDescs; 42 uint16 fLastUsed; 43 ArrayDeleter<void*> fCookies; 44 45 BReference<VirtioIrqHandler> fQueueHandlerRef; 46 virtio_callback_func fQueueHandler; 47 void *fQueueHandlerCookie; 48 49 VirtioQueue(VirtioDevice *dev, int32 id); 50 ~VirtioQueue(); 51 status_t Init(); 52 53 int32 AllocDesc(); 54 void FreeDesc(int32 idx); 55 56 status_t Enqueue( 57 const physical_entry* vector, 58 size_t readVectorCount, size_t writtenVectorCount, 59 void* cookie 60 ); 61 62 bool Dequeue(void** _cookie, uint32* _usedLength); 63}; 64 65 66struct VirtioIrqHandler: public BReferenceable 67{ 68 VirtioDevice* fDev; 69 70 VirtioIrqHandler(VirtioDevice* dev); 71 72 virtual void FirstReferenceAcquired(); 73 virtual void LastReferenceReleased(); 74 75 static int32 Handle(void* data); 76}; 77 78 79struct VirtioDevice 80{ 81 AreaDeleter fRegsArea; 82 volatile VirtioRegs *fRegs; 83 int32 fIrq; 84 int32 fQueueCnt; 85 ArrayDeleter<ObjectDeleter<VirtioQueue> > fQueues; 86 87 VirtioIrqHandler fIrqHandler; 88 89 BReference<VirtioIrqHandler> fConfigHandlerRef; 90 virtio_intr_func fConfigHandler; 91 void* fConfigHandlerCookie; 92 93 VirtioDevice(); 94 status_t Init(phys_addr_t regs, size_t regsLen, int32 irq, int32 queueCnt); 95}; 96 97 98#endif // _VIRTIODEVICE_H_ 99