[haiku-commits] haiku: hrev45896 - src/add-ons/kernel/bus_managers/virtio

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 23 Jul 2013 23:24:19 +0200 (CEST)

hrev45896 adds 2 changesets to branch 'master'
old head: 79a2f0c70c6a13c5454b9b7699c14559f5739396
new head: b5ccadd7c26d425ce2d20050e3096d11c664f0e7
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=b5ccadd+%5E79a2f0c

----------------------------------------------------------------------------

17c5599: Virtio SCSI: add a description for CHANGE feature.

b5ccadd: Virtio: implemented indirect descriptors feature.
  
  * indirect descriptors count hardcoded to 128.
  * already activated for virtio_block driver.

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

4 files changed, 107 insertions(+), 19 deletions(-)
.../kernel/bus_managers/virtio/VirtioDevice.cpp  |   3 +-
.../kernel/bus_managers/virtio/VirtioPrivate.h   |   2 +
.../kernel/bus_managers/virtio/VirtioQueue.cpp   | 118 ++++++++++++++++---
.../busses/scsi/virtio/VirtioSCSIController.cpp  |   3 +-

############################################################################

Commit:      17c55998dc49cc84c859f564fae0e0a442194e49
URL:         http://cgit.haiku-os.org/haiku/commit/?id=17c5599
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Tue Jul 23 20:59:01 2013 UTC

Virtio SCSI: add a description for CHANGE feature.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp 
b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp
index 0be4903..2a39367 100644
--- a/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp
+++ b/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIController.cpp
@@ -21,6 +21,8 @@ get_feature_name(uint32 feature)
                        return "in out";
                case VIRTIO_SCSI_F_HOTPLUG:
                        return "hotplug";
+               case VIRTIO_SCSI_F_CHANGE:
+                       return "change";
        }
        return NULL;
 }
@@ -348,4 +350,3 @@ VirtioSCSIController::_RescanChildBus(void *cookie)
        TRACE("rescan done %p\n", childNode);
        gDeviceManager->put_node(childNode);
 }
-

############################################################################

Revision:    hrev45896
Commit:      b5ccadd7c26d425ce2d20050e3096d11c664f0e7
URL:         http://cgit.haiku-os.org/haiku/commit/?id=b5ccadd
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Tue Jul 23 21:00:20 2013 UTC

Virtio: implemented indirect descriptors feature.

* indirect descriptors count hardcoded to 128.
* already activated for virtio_block driver.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp 
b/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp
index 320d16d..4364748 100644
--- a/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp
+++ b/src/add-ons/kernel/bus_managers/virtio/VirtioDevice.cpp
@@ -115,7 +115,7 @@ VirtioDevice::NegociateFeatures(uint32 supported, uint32* 
negociated,
 
        // filter our own features
        fFeatures &= (VIRTIO_FEATURE_TRANSPORT_MASK
-               /*| VIRTIO_FEATURE_RING_INDIRECT_DESC*/ | 
VIRTIO_FEATURE_RING_EVENT_IDX);
+               | VIRTIO_FEATURE_RING_INDIRECT_DESC | 
VIRTIO_FEATURE_RING_EVENT_IDX);
 
        *negociated = fFeatures;
 
@@ -254,4 +254,3 @@ VirtioDevice::DumpFeatures(const char* title, uint32 
features,
        }
        TRACE("%s: %s\n", title, features_string);
 }
-
diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h 
b/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h
index 02844c6..a83eaf8 100644
--- a/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h
+++ b/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h
@@ -145,6 +145,8 @@ private:
                        size_t                          fAreaSize;
                        area_id                         fArea;
 
+                       uint16                          fIndirectMaxSize;
+
                        TransferDescriptor**    fDescriptors;
 };
 
diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp 
b/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp
index 9fa4157..5977785 100644
--- a/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp
+++ b/src/add-ons/kernel/bus_managers/virtio/VirtioQueue.cpp
@@ -51,36 +51,69 @@ alloc_mem(void **virt, phys_addr_t *phy, size_t size, 
uint32 protection,
 class TransferDescriptor {
 public:
                                                                
TransferDescriptor(VirtioQueue* queue,
-                                                                       uint16 
size,
-                                                                       
virtio_callback_func callback,
-                                                                       void 
*callbackCookie);
+                                                                       uint16 
indirectMaxSize);
                                                                
~TransferDescriptor();
 
+                       status_t                        InitCheck() { return 
fStatus; }
+
                        void                            Callback();
                        uint16                          Size() { return 
fDescriptorCount; }
+                       void                            SetTo(uint16 size,
+                                                                       
virtio_callback_func callback,
+                                                                       void 
*callbackCookie);
+                       void                            Unset();
+                       struct vring_desc*      Indirect() { return fIndirect; }
+                       phys_addr_t                     PhysAddr() { return 
fPhysAddr; }
 private:
+                       status_t                        fStatus;
                        VirtioQueue*            fQueue;
                        void*                           fCookie;
                        virtio_callback_func fCallback;
+
                        struct vring_desc*      fIndirect;
                        size_t                          fAreaSize;
                        area_id                         fArea;
+                       phys_addr_t             fPhysAddr;
                        uint16                          fDescriptorCount;
 };
 
 
-TransferDescriptor::TransferDescriptor(VirtioQueue* queue, uint16 size,
-       virtio_callback_func callback, void *callbackCookie)
+TransferDescriptor::TransferDescriptor(VirtioQueue* queue, uint16 
indirectMaxSize)
        : fQueue(queue),
-       fCookie(callbackCookie),
-       fCallback(callback),
-       fDescriptorCount(size)
+       fCookie(NULL),
+       fCallback(NULL),
+       fIndirect(NULL),
+       fAreaSize(0),
+       fArea(-1),
+       fDescriptorCount(0)
 {
+       fStatus = B_OK;
+       struct vring_desc* virtAddr;
+       phys_addr_t physAddr;
+
+       if (indirectMaxSize > 0) {
+               fAreaSize = indirectMaxSize * sizeof(struct vring_desc);
+               fArea = alloc_mem((void **)&virtAddr, &physAddr, fAreaSize, 0,
+                       "virtqueue");
+               if (fArea < B_OK) {
+                       fStatus = fArea;
+                       return;
+               }
+               memset(virtAddr, 0, fAreaSize);
+               fIndirect = virtAddr;
+               fPhysAddr = physAddr;
+
+               for (uint16 i = 0; i < indirectMaxSize - 1; i++)
+                       fIndirect[i].next = i + 1;
+               fIndirect[indirectMaxSize - 1].next = UINT16_MAX;
+       }
 }
 
 
 TransferDescriptor::~TransferDescriptor()
 {
+       if (fArea > B_OK)
+               delete_area(fArea);
 }
 
 
@@ -92,6 +125,25 @@ TransferDescriptor::Callback()
 }
 
 
+void
+TransferDescriptor::SetTo(uint16 size, virtio_callback_func callback,
+       void *callbackCookie)
+{
+       fCookie = callbackCookie;
+       fCallback = callback;
+       fDescriptorCount = size;
+}
+
+
+void
+TransferDescriptor::Unset()
+{
+       fCookie = NULL;
+       fCallback = NULL;
+       fDescriptorCount = 0;
+}
+
+
 //     #pragma mark -
 
 
@@ -104,7 +156,8 @@ VirtioQueue::VirtioQueue(VirtioDevice* device, uint16 
queueNumber,
        fRingFree(ringSize),
        fRingHeadIndex(0),
        fRingUsedIndex(0),
-       fStatus(B_OK)
+       fStatus(B_OK),
+       fIndirectMaxSize(0)
 {
        fDescriptors = new(std::nothrow) TransferDescriptor*[fRingSize];
        if (fDescriptors == NULL) {
@@ -128,6 +181,17 @@ VirtioQueue::VirtioQueue(VirtioDevice* device, uint16 
queueNumber,
                fRing.desc[i].next = i + 1;
        fRing.desc[fRingSize - 1].next = UINT16_MAX;
 
+       if ((fDevice->Features() & VIRTIO_FEATURE_RING_INDIRECT_DESC) != 0)
+               fIndirectMaxSize = 128;
+
+       for (uint16 i = 0; i < fRingSize; i++) {
+               fDescriptors[i] = new TransferDescriptor(this, 
fIndirectMaxSize);
+               if (fDescriptors[i] == NULL || fDescriptors[i]->InitCheck() != 
B_OK) {
+                       fStatus = B_NO_MEMORY;
+                       return;
+               }
+       }
+
        DisableInterrupt();
 
        device->SetupQueue(fQueueNumber, physAddr);
@@ -137,6 +201,9 @@ VirtioQueue::VirtioQueue(VirtioDevice* device, uint16 
queueNumber,
 VirtioQueue::~VirtioQueue()
 {
        delete_area(fArea);
+       for (uint16 i = 0; i < fRingSize; i++) {
+               delete fDescriptors[i];
+       }
        delete[] fDescriptors;
 }
 
@@ -191,6 +258,7 @@ VirtioQueue::Finish()
 
        fDescriptors[descriptorIndex]->Callback();
        uint16 size = fDescriptors[descriptorIndex]->Size();
+       fDescriptors[descriptorIndex]->Unset();
        fRingFree += size;
        size--;
 
@@ -203,8 +271,6 @@ VirtioQueue::Finish()
        if (size > 0)
                panic("VirtioQueue::Finish() descriptors left %d\n", size);
 
-       // TODO TransferDescriptors are leaked, can't delete in interrupt 
handler.
-
        fRing.desc[index].next = fRingHeadIndex;
        fRingHeadIndex = descriptorIndex;
        TRACE("Finish() fRingHeadIndex: %u\n", fRingHeadIndex);
@@ -229,10 +295,8 @@ VirtioQueue::QueueRequest(const physical_entry* vector, 
size_t readVectorCount,
                return B_BUSY;
 
        uint16 insertIndex = fRingHeadIndex;
-       fDescriptors[insertIndex] = new(std::nothrow) TransferDescriptor(this,
-               count, callback, callbackCookie);
-       if (fDescriptors[insertIndex] == NULL)
-               return B_NO_MEMORY;
+       fDescriptors[insertIndex]->SetTo(count, callback,
+               callbackCookie);
 
        // enqueue
        uint16 index = QueueVector(insertIndex, fRing.desc, vector,
@@ -254,7 +318,29 @@ VirtioQueue::QueueRequestIndirect(const physical_entry* 
vector,
        size_t readVectorCount, size_t writtenVectorCount,
        virtio_callback_func callback, void *callbackCookie)
 {
-       // TODO
+       CALLED();
+       size_t count = readVectorCount + writtenVectorCount;
+       if (count > fRingFree || count > fIndirectMaxSize)
+               return B_BUSY;
+
+       uint16 insertIndex = fRingHeadIndex;
+       fDescriptors[insertIndex]->SetTo(1, callback,
+               callbackCookie);
+
+       // enqueue
+       uint16 index = QueueVector(0, fDescriptors[insertIndex]->Indirect(),
+               vector, readVectorCount, writtenVectorCount);
+
+       fRing.desc[insertIndex].addr = fDescriptors[insertIndex]->PhysAddr();
+       fRing.desc[insertIndex].len = index * sizeof(struct vring_desc);
+       fRing.desc[insertIndex].flags = VRING_DESC_F_INDIRECT;
+       fRingHeadIndex = fRing.desc[insertIndex].next;
+       fRingFree--;
+
+       UpdateAvailable(insertIndex);
+
+       NotifyHost();
+
        return B_OK;
 }
 


Other related posts:

  • » [haiku-commits] haiku: hrev45896 - src/add-ons/kernel/bus_managers/virtio - korli