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(); }
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; }
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; } }
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__); }
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(); }