예제 #1
0
VOID
ShutDown(
    IN PVOID DeviceExtension
    )
{
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
ENTER_FN();
    VirtIODeviceReset(&adaptExt->vdev);
    StorPortWritePortUshort(DeviceExtension, (PUSHORT)(adaptExt->device_base + VIRTIO_PCI_GUEST_FEATURES), 0);
    if (adaptExt->vq[0]) {
       adaptExt->vq[0]->vq_ops->shutdown(adaptExt->vq[0]);
       VirtIODeviceDeleteQueue(adaptExt->vq[0], NULL);
       adaptExt->vq[0] = NULL;
    }
    if (adaptExt->vq[1]) {
       adaptExt->vq[1]->vq_ops->shutdown(adaptExt->vq[1]);
       VirtIODeviceDeleteQueue(adaptExt->vq[1], NULL);
       adaptExt->vq[1] = NULL;
    }
    if (adaptExt->vq[2]) {
       adaptExt->vq[2]->vq_ops->shutdown(adaptExt->vq[2]);
       VirtIODeviceDeleteQueue(adaptExt->vq[2], NULL);
       adaptExt->vq[2] = NULL;
    }
EXIT_FN();
}
예제 #2
0
VOID
BalloonTerm(
    IN WDFOBJECT    WdfDevice,
    IN BOOLEAN      bFinal
    )
{
    PDEVICE_CONTEXT     devCtx = GetDeviceContext(WdfDevice);
    PVOID p;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> BalloonTerm\n");

    VirtIODeviceRemoveStatus(&devCtx->VDevice , VIRTIO_CONFIG_S_DRIVER_OK);

    if(devCtx->DefVirtQueue)
    {
        devCtx->DefVirtQueue->vq_ops->shutdown(devCtx->DefVirtQueue);
        if (bFinal)
        {
           VirtIODeviceDeleteQueue(devCtx->DefVirtQueue, &p);
           MmFreeContiguousMemory(p);
           devCtx->DefVirtQueue = NULL;
        }
    }

    if(devCtx->InfVirtQueue)
    {
        devCtx->InfVirtQueue->vq_ops->shutdown(devCtx->InfVirtQueue);
        if (bFinal)
        {
           VirtIODeviceDeleteQueue(devCtx->InfVirtQueue, &p);
           MmFreeContiguousMemory(p);
           devCtx->InfVirtQueue = NULL;
        }
    }

    if(devCtx->StatVirtQueue)
    {
        devCtx->StatVirtQueue->vq_ops->shutdown(devCtx->StatVirtQueue);
        if (bFinal)
        {
           VirtIODeviceDeleteQueue(devCtx->StatVirtQueue, &p);
           MmFreeContiguousMemory(p);
           devCtx->StatVirtQueue = NULL;
        }
    }

    if (bFinal)
    {
       VirtIODeviceReset(&devCtx->VDevice);
    }
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- BalloonTerm\n");
}
static struct virtqueue *FindVirtualQueue(PADAPTER_EXTENSION adaptExt, ULONG index, ULONG vector)
{
	struct virtqueue *vq = NULL;
	if (adaptExt->uncachedExtensionVa)
	{
		ULONG len;
		PHYSICAL_ADDRESS pa = ScsiPortGetPhysicalAddress(adaptExt, NULL, adaptExt->uncachedExtensionVa, &len);
		if (pa.QuadPart)
			vq = VirtIODevicePrepareQueue(&adaptExt->vdev, index, pa, adaptExt->uncachedExtensionVa, len, NULL);
	}

	if (vq && vector)
	{
		unsigned res;
		ScsiPortWritePortUshort((PUSHORT)(adaptExt->vdev.addr + VIRTIO_MSI_QUEUE_VECTOR),(USHORT)vector);
		res = ScsiPortReadPortUshort((PUSHORT)(adaptExt->vdev.addr + VIRTIO_MSI_QUEUE_VECTOR));
		RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> VIRTIO_MSI_QUEUE_VECTOR vector = %d, res = 0x%x\n", __FUNCTION__, vector, res));
		if(res == VIRTIO_MSI_NO_VECTOR) {
			VirtIODeviceDeleteQueue(vq, NULL);
			vq = NULL;
			RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> Cannot create vq vector\n", __FUNCTION__));
			return NULL;
		}
	}

	return vq;
}
예제 #4
0
static struct virtqueue *FindVirtualQueue(PADAPTER_EXTENSION adaptExt, ULONG index, ULONG vector)
{
    struct virtqueue *vq = NULL;
    if (adaptExt->uncachedExtensionVa)
    {
        ULONG len;
        PVOID  ptr = (PVOID)((ULONG_PTR)adaptExt->uncachedExtensionVa + adaptExt->offset[index]);
        PHYSICAL_ADDRESS pa = StorPortGetPhysicalAddress(adaptExt, NULL, ptr, &len);
        if (pa.QuadPart)
        {
           vq = VirtIODevicePrepareQueue(&adaptExt->vdev, index, pa, ptr, len, NULL, FALSE);
        }

        if (vq == NULL)
        {
           RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> cannot create virtual queue index = %d vector = % pa = %08I64X\n", __FUNCTION__, index, vector, pa.QuadPart));
           return NULL;
        }
        if (vector)
        {
           unsigned res;
           StorPortWritePortUshort(adaptExt, (PUSHORT)(adaptExt->vdev.addr + VIRTIO_MSI_QUEUE_VECTOR),(USHORT)vector);
           res = StorPortReadPortUshort(adaptExt, (PUSHORT)(adaptExt->vdev.addr + VIRTIO_MSI_QUEUE_VECTOR));
           RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> VIRTIO_MSI_QUEUE_VECTOR vector = %d, res = 0x%x\n", __FUNCTION__, vector, res));
           if(res == VIRTIO_MSI_NO_VECTOR)
           {
              VirtIODeviceDeleteQueue(vq, NULL);
              vq = NULL;
              RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> Cannot create vq vector\n", __FUNCTION__));
              return NULL;
           }
           StorPortWritePortUshort(adaptExt, (PUSHORT)(adaptExt->vdev.addr + VIRTIO_MSI_CONFIG_VECTOR),(USHORT)vector);
           res = StorPortReadPortUshort(adaptExt, (PUSHORT)(adaptExt->vdev.addr + VIRTIO_MSI_CONFIG_VECTOR));
           if (res != vector)
           {
              VirtIODeviceDeleteQueue(vq, NULL);
              vq = NULL;
              RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> Cannot set config vector\n", __FUNCTION__));
              return NULL;
           }
        }
    }
    return vq;
}
VOID
RhelShutDown(
    IN PVOID DeviceExtension
    )
{
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;

    VirtIODeviceReset(&adaptExt->vdev);
    ScsiPortWritePortUshort((PUSHORT)(adaptExt->vdev.addr + VIRTIO_PCI_GUEST_FEATURES), 0);
    if (adaptExt->vq) {
       adaptExt->vq->vq_ops->shutdown(adaptExt->vq);
       VirtIODeviceDeleteQueue(adaptExt->vq, NULL);
       adaptExt->vq = NULL;
    }
}
예제 #6
0
static void DeleteQueue(struct virtqueue **ppq)
{
    PVOID p;
    struct virtqueue *pq = *ppq;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s\n", __FUNCTION__);

    if (pq)
    {
        VirtIODeviceDeleteQueue(pq, &p);
        *ppq = NULL;
        MmFreeContiguousMemory(p);
    }

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__);
}
예제 #7
0
VOID
ShutDown(
    IN PVOID DeviceExtension
    )
{
    ULONG index;
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
ENTER_FN();
    VirtIODeviceReset(adaptExt->pvdev);
    StorPortWritePortUshort(DeviceExtension, (PUSHORT)(adaptExt->device_base + VIRTIO_PCI_GUEST_FEATURES), 0);
    for (index = VIRTIO_SCSI_CONTROL_QUEUE; index < adaptExt->num_queues + VIRTIO_SCSI_REQUEST_QUEUE_0; ++index) {
        if (adaptExt->vq[index]) {
            virtqueue_shutdown(adaptExt->vq[index]);
            VirtIODeviceDeleteQueue(adaptExt->vq[index], NULL);
            adaptExt->vq[index] = NULL;
        }
    }
EXIT_FN();
}