static void WriteVirtIODeviceByte(ULONG_PTR ulRegister, u8 bValue)
{
    if (ulRegister & ~PORT_MASK) {
        StorPortWriteRegisterUchar(NULL, (PUCHAR)(ulRegister), (UCHAR)(bValue));
    } else {
        StorPortWritePortUchar(NULL, (PUCHAR)(ulRegister), (UCHAR)(bValue));
    }
}
void WriteVirtIODeviceByte(ULONG_PTR ulRegister, u8 bValue)
{
    StorPortWritePortUchar(NULL, (PUCHAR)(ulRegister),(UCHAR)(bValue));
}
BOOLEAN
VioScsiHwInitialize(
    IN PVOID DeviceExtension
    )
{
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
    PVOID              ptr      = adaptExt->uncachedExtensionVa;
    ULONG              i;

#if (MSI_SUPPORTED == 1)
    MESSAGE_INTERRUPT_INFORMATION msi_info;
#endif
    
ENTER_FN();
    adaptExt->msix_vectors = 0;
#if (MSI_SUPPORTED == 1)
    while(StorPortGetMSIInfo(DeviceExtension, adaptExt->msix_vectors, &msi_info) == STOR_STATUS_SUCCESS) {
        RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageId = %x\n", msi_info.MessageId));
        RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageData = %x\n", msi_info.MessageData));
        RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptVector = %x\n", msi_info.InterruptVector));
        RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptLevel = %x\n", msi_info.InterruptLevel));
        RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptMode = %s\n", msi_info.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"));
        RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageAddress = %p\n\n", msi_info.MessageAddress));
        ++adaptExt->msix_vectors;
    }
    if(!adaptExt->dump_mode && (adaptExt->msix_vectors > 1)) {
        adaptExt->vq[0] = FindVirtualQueue(adaptExt, 0, 1);
    }
    if(!adaptExt->dump_mode && (adaptExt->msix_vectors > 2)) {
        adaptExt->vq[1] = FindVirtualQueue(adaptExt, 1, 2);
    }
    if(!adaptExt->dump_mode && (adaptExt->msix_vectors > 3)) {
        adaptExt->vq[2] = FindVirtualQueue(adaptExt, 2, 3);
    }
#endif
    if (!adaptExt->vq[0]) {
        adaptExt->vq[0] = FindVirtualQueue(adaptExt, 0, 0);
    }
    if (!adaptExt->vq[0]) {
        RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find virtual queue 0\n"));
        return FALSE;
    }

    if (!adaptExt->vq[1]) {
        adaptExt->vq[1] = FindVirtualQueue(adaptExt, 1, 0);
    }

    if (!adaptExt->vq[1]) {
        RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find virtual queue 1\n"));
        return FALSE;
    }

    if (!adaptExt->vq[2]) {
        adaptExt->vq[2] = FindVirtualQueue(adaptExt, 2, 0);
    }

    if (!adaptExt->vq[2]) {
        RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find virtual queue 2\n"));
        return FALSE;
    }
    adaptExt->tmf_cmd.SrbExtension = (PSRB_EXTENSION)((ULONG_PTR)adaptExt->uncachedExtensionVa + adaptExt->offset[3]);
    adaptExt->events = (PVirtIOSCSIEventNode)((ULONG_PTR)adaptExt->uncachedExtensionVa + adaptExt->offset[4]);

    if (!adaptExt->dump_mode && CHECKBIT(adaptExt->features, VIRTIO_SCSI_F_HOTPLUG)) {
        PVirtIOSCSIEventNode events = adaptExt->events;
        for (i = 0; i < 8; i++) {
           if (!KickEvent(DeviceExtension, (PVOID)(&events[i]))) {
                RhelDbgPrint(TRACE_LEVEL_FATAL, ("Can't add event %d\n", i));
           }
        }
    }

    StorPortWritePortUshort(DeviceExtension,
           (PUSHORT)(adaptExt->device_base + VIRTIO_PCI_GUEST_FEATURES),
           (USHORT)((1 << VIRTIO_SCSI_F_HOTPLUG) | (1 << VIRTIO_SCSI_F_CHANGE)));
    StorPortWritePortUchar(DeviceExtension,
           (PUCHAR)(adaptExt->device_base + VIRTIO_PCI_STATUS),
           (UCHAR)VIRTIO_CONFIG_S_DRIVER_OK);
EXIT_FN();
    return TRUE;
}