static void *pci_map_address_range(void *context, int bar, size_t offset, size_t maxlen) { PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context; if (bar < PCI_TYPE0_ADDRESSES) { PVIRTIO_BAR pBar = &adaptExt->pci_bars[bar]; if (pBar->pBase == NULL) { #ifndef USE_STORPORT if (!ScsiPortValidateRange( adaptExt, PCIBus, adaptExt->system_io_bus_number, pBar->BasePA, pBar->uLength, !!pBar->bPortSpace)) { LogError(adaptExt, SP_INTERNAL_ADAPTER_ERROR, __LINE__); RhelDbgPrint(TRACE_LEVEL_FATAL, ("Range validation failed %I64x for %x bytes\n", pBar->BasePA.QuadPart, pBar->uLength)); return NULL; } #endif pBar->pBase = ScsiPortGetDeviceBase( adaptExt, PCIBus, adaptExt->system_io_bus_number, pBar->BasePA, pBar->uLength, !!pBar->bPortSpace); } if (pBar->pBase != NULL && offset < pBar->uLength) { return (PUCHAR)pBar->pBase + offset; } } return NULL; }
ULONG VirtIoFindAdapter( IN PVOID DeviceExtension, IN PVOID HwContext, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again ) { PACCESS_RANGE accessRange; PADAPTER_EXTENSION adaptExt; ULONG_PTR deviceBase; ULONG allocationSize; ULONG pageNum; #ifdef MSI_SUPPORTED PPCI_COMMON_CONFIG pPciConf = NULL; UCHAR pci_cfg_buf[256]; ULONG pci_cfg_len; #endif UNREFERENCED_PARAMETER( HwContext ); UNREFERENCED_PARAMETER( BusInformation ); UNREFERENCED_PARAMETER( ArgumentString ); UNREFERENCED_PARAMETER( Again ); adaptExt = (PADAPTER_EXTENSION)DeviceExtension; adaptExt->dump_mode = IsCrashDumpMode; ConfigInfo->Master = TRUE; ConfigInfo->ScatterGather = TRUE; ConfigInfo->DmaWidth = Width32Bits; ConfigInfo->Dma32BitAddresses = TRUE; ConfigInfo->Dma64BitAddresses = TRUE; ConfigInfo->WmiDataProvider = FALSE; ConfigInfo->AlignmentMask = 0x3; #ifdef USE_STORPORT ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS; ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex; #ifdef MSI_SUPPORTED ConfigInfo->HwMSInterruptRoutine = VirtIoMSInterruptRoutine; ConfigInfo->InterruptSynchronizationMode=InterruptSynchronizePerMessage; #endif #else ConfigInfo->MapBuffers = TRUE; #endif accessRange = &(*ConfigInfo->AccessRanges)[0]; ASSERT (FALSE == accessRange->RangeInMemory) ; RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("Port Resource [%08I64X-%08I64X]\n", accessRange->RangeStart.QuadPart, accessRange->RangeStart.QuadPart + accessRange->RangeLength)); if ( accessRange->RangeLength < IO_PORT_LENGTH) { LogError(DeviceExtension, SP_INTERNAL_ADAPTER_ERROR, __LINE__); RhelDbgPrint(TRACE_LEVEL_FATAL, ("Wrong access range %x bytes\n", accessRange->RangeLength)); return SP_RETURN_NOT_FOUND; } #ifndef USE_STORPORT if (!ScsiPortValidateRange(DeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, accessRange->RangeStart, accessRange->RangeLength, (BOOLEAN)!accessRange->RangeInMemory)) { LogError(DeviceExtension, SP_INTERNAL_ADAPTER_ERROR, __LINE__); RhelDbgPrint(TRACE_LEVEL_FATAL, ("Range validation failed %x for %x bytes\n", (*ConfigInfo->AccessRanges)[0].RangeStart.LowPart, (*ConfigInfo->AccessRanges)[0].RangeLength)); return SP_RETURN_ERROR; } #endif ConfigInfo->NumberOfBuses = 1; ConfigInfo->MaximumNumberOfTargets = 1; ConfigInfo->MaximumNumberOfLogicalUnits = 1; deviceBase = (ULONG_PTR)ScsiPortGetDeviceBase(DeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, accessRange->RangeStart, accessRange->RangeLength, (BOOLEAN)!accessRange->RangeInMemory); if (deviceBase == (ULONG_PTR)NULL) { LogError(DeviceExtension, SP_INTERNAL_ADAPTER_ERROR, __LINE__); RhelDbgPrint(TRACE_LEVEL_FATAL, ("Couldn't map %x for %x bytes\n", (*ConfigInfo->AccessRanges)[0].RangeStart.LowPart, (*ConfigInfo->AccessRanges)[0].RangeLength)); return SP_RETURN_ERROR; } VirtIODeviceInitialize(&adaptExt->vdev, deviceBase, sizeof(adaptExt->vdev)); VirtIODeviceAddStatus(&adaptExt->vdev, VIRTIO_CONFIG_S_DRIVER); adaptExt->msix_enabled = FALSE; #ifdef MSI_SUPPORTED pci_cfg_len = StorPortGetBusData (DeviceExtension, PCIConfiguration, ConfigInfo->SystemIoBusNumber, (ULONG)ConfigInfo->SlotNumber, (PVOID)pci_cfg_buf, (ULONG)256); if (pci_cfg_len == 256) { UCHAR CapOffset; PPCI_MSIX_CAPABILITY pMsixCapOffset; pPciConf = (PPCI_COMMON_CONFIG)pci_cfg_buf; if ( (pPciConf->Status & PCI_STATUS_CAPABILITIES_LIST) == 0) { RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("NO CAPABILITIES_LIST\n")); } else { if ( (pPciConf->HeaderType & (~PCI_MULTIFUNCTION)) == PCI_DEVICE_TYPE ) { CapOffset = pPciConf->u.type0.CapabilitiesPtr; while (CapOffset != 0) { pMsixCapOffset = (PPCI_MSIX_CAPABILITY)(pci_cfg_buf + CapOffset); if ( pMsixCapOffset->Header.CapabilityID == PCI_CAPABILITY_ID_MSIX ) { RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageControl.TableSize = %d\n", pMsixCapOffset->MessageControl.TableSize)); RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageControl.FunctionMask = %d\n", pMsixCapOffset->MessageControl.FunctionMask)); RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageControl.MSIXEnable = %d\n", pMsixCapOffset->MessageControl.MSIXEnable)); RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageTable = %p\n", pMsixCapOffset->MessageTable)); RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("PBATable = %d\n", pMsixCapOffset->PBATable)); adaptExt->msix_enabled = (pMsixCapOffset->MessageControl.MSIXEnable == 1); break; } else { CapOffset = pMsixCapOffset->Header.Next; RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("CapabilityID = %x, Next CapOffset = %x\n", pMsixCapOffset->Header.CapabilityID, CapOffset)); } } VirtIODeviceSetMSIXUsed(&adaptExt->vdev, adaptExt->msix_enabled); } else { RhelDbgPrint(TRACE_LEVEL_FATAL, ("NOT A PCI_DEVICE_TYPE\n")); } } } else { RhelDbgPrint(TRACE_LEVEL_FATAL, ("CANNOT READ PCI CONFIGURATION SPACE %d\n", pci_cfg_len)); } #endif VirtIODeviceReset(&adaptExt->vdev); VirtIODeviceAddStatus(&adaptExt->vdev, VIRTIO_CONFIG_S_ACKNOWLEDGE); WriteVirtIODeviceWord(adaptExt->vdev.addr + VIRTIO_PCI_QUEUE_SEL, (USHORT)0); if (adaptExt->dump_mode) { WriteVirtIODeviceWord(adaptExt->vdev.addr + VIRTIO_PCI_QUEUE_PFN, (USHORT)0); } adaptExt->features = ReadVirtIODeviceRegister(adaptExt->vdev.addr + VIRTIO_PCI_HOST_FEATURES); ConfigInfo->CachesData = CHECKBIT(adaptExt->features, VIRTIO_BLK_F_WCACHE) ? TRUE : FALSE; if (ConfigInfo->CachesData) { u32 GuestFeatures = 0; VirtIOFeatureEnable(GuestFeatures, VIRTIO_BLK_F_WCACHE); VirtIODeviceWriteGuestFeatures(&adaptExt->vdev, GuestFeatures); } RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_WCACHE = %d\n", ConfigInfo->CachesData)); VirtIODeviceQueryQueueAllocation(&adaptExt->vdev, 0, &pageNum, &allocationSize); if(adaptExt->dump_mode) { ConfigInfo->NumberOfPhysicalBreaks = 8; } else { ConfigInfo->NumberOfPhysicalBreaks = MAX_PHYS_SEGMENTS + 1; } ConfigInfo->MaximumTransferLength = 0x00FFFFFF; adaptExt->queue_depth = pageNum / ConfigInfo->NumberOfPhysicalBreaks - 1; #if (INDIRECT_SUPPORTED) if(!adaptExt->dump_mode) { adaptExt->indirect = CHECKBIT(adaptExt->features, VIRTIO_RING_F_INDIRECT_DESC); } if(adaptExt->indirect) { adaptExt->queue_depth = pageNum; } #else adaptExt->indirect = 0; #endif RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("breaks_number = %x queue_depth = %x\n", ConfigInfo->NumberOfPhysicalBreaks, adaptExt->queue_depth)); adaptExt->uncachedExtensionVa = ScsiPortGetUncachedExtension(DeviceExtension, ConfigInfo, allocationSize); if (!adaptExt->uncachedExtensionVa) { LogError(DeviceExtension, SP_INTERNAL_ADAPTER_ERROR, __LINE__); RhelDbgPrint(TRACE_LEVEL_FATAL, ("Couldn't get uncached extension\n")); return SP_RETURN_ERROR; } InitializeListHead(&adaptExt->list_head); #ifdef USE_STORPORT InitializeListHead(&adaptExt->complete_list); #endif return SP_RETURN_FOUND; }
static ULONG XenScsi_HwScsiFindAdapter(PVOID DeviceExtension, PVOID Reserved1, PVOID Reserved2, PCHAR ArgumentString, PPORT_CONFIGURATION_INFORMATION ConfigInfo, PUCHAR Reserved3) { ULONG i; PXENSCSI_DEVICE_DATA xsdd = DeviceExtension; PACCESS_RANGE access_range; PUCHAR ptr; USHORT type; PCHAR setting, value, value2; vscsiif_sring_t *sring; CHAR path[128]; UNREFERENCED_PARAMETER(Reserved1); UNREFERENCED_PARAMETER(Reserved2); UNREFERENCED_PARAMETER(ArgumentString); UNREFERENCED_PARAMETER(Reserved3); FUNCTION_ENTER(); KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql())); xsdd->scsiport_paused = TRUE; /* wait for initial scan */ KdPrint((__DRIVER_NAME " BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel)); KdPrint((__DRIVER_NAME " BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector)); if (!ConfigInfo->BusInterruptVector) { KdPrint((__DRIVER_NAME " No Interrupt assigned\n")); return SP_RETURN_BAD_CONFIG; } if (ConfigInfo->NumberOfAccessRanges != 1) { KdPrint((__DRIVER_NAME " NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges)); return SP_RETURN_BAD_CONFIG; } ptr = NULL; access_range = &((*(ConfigInfo->AccessRanges))[0]); KdPrint((__DRIVER_NAME " RangeStart = %08x, RangeLength = %08x\n", access_range->RangeStart.LowPart, access_range->RangeLength)); ptr = ScsiPortGetDeviceBase( DeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, access_range->RangeStart, access_range->RangeLength, !access_range->RangeInMemory); if (!ptr) { KdPrint((__DRIVER_NAME " Unable to map range\n")); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } sring = NULL; xsdd->event_channel = 0; while((type = GET_XEN_INIT_RSP(&ptr, &setting, &value, &value2)) != XEN_INIT_TYPE_END) { switch(type) { case XEN_INIT_TYPE_RING: /* frontend ring */ KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_RING - %s = %p\n", setting, value)); if (strcmp(setting, "ring-ref") == 0) { sring = (vscsiif_sring_t *)value; FRONT_RING_INIT(&xsdd->ring, sring, PAGE_SIZE); } break; //case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */ case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel */ KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_EVENT_CHANNEL - %s = %d\n", setting, PtrToUlong(value))); if (strcmp(setting, "event-channel") == 0) { xsdd->event_channel = PtrToUlong(value); } break; case XEN_INIT_TYPE_READ_STRING_BACK: case XEN_INIT_TYPE_READ_STRING_FRONT: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value)); break; case XEN_INIT_TYPE_VECTORS: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n")); if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) || ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC) { KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n", ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length)); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } else memcpy(&xsdd->vectors, value, sizeof(XENPCI_VECTORS)); break; case XEN_INIT_TYPE_GRANT_ENTRIES: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_GRANT_ENTRIES - %d\n", PtrToUlong(value))); xsdd->grant_entries = (USHORT)PtrToUlong(value); memcpy(&xsdd->grant_free_list, value2, sizeof(grant_ref_t) * xsdd->grant_entries); xsdd->grant_free = xsdd->grant_entries; break; default: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type)); break; } } if (sring == NULL || xsdd->event_channel == 0) { KdPrint((__DRIVER_NAME " Missing settings\n")); KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n")); return SP_RETURN_BAD_CONFIG; } ConfigInfo->ScatterGather = TRUE; ConfigInfo->NumberOfPhysicalBreaks = VSCSIIF_SG_TABLESIZE - 1; ConfigInfo->MaximumTransferLength = VSCSIIF_SG_TABLESIZE * PAGE_SIZE; ConfigInfo->CachesData = FALSE; ConfigInfo->NumberOfBuses = 4; //SCSI_MAXIMUM_BUSES; //8 ConfigInfo->MaximumNumberOfTargets = 16; ConfigInfo->MaximumNumberOfLogicalUnits = SCSI_MAXIMUM_LOGICAL_UNITS; // 8 ConfigInfo->BufferAccessScsiPortControlled = TRUE; if (ConfigInfo->Dma64BitAddresses == SCSI_DMA64_SYSTEM_SUPPORTED) { ConfigInfo->Master = TRUE; ConfigInfo->Dma64BitAddresses = SCSI_DMA64_MINIPORT_SUPPORTED; KdPrint((__DRIVER_NAME " Dma64BitAddresses supported\n")); } else { ConfigInfo->Master = FALSE; KdPrint((__DRIVER_NAME " Dma64BitAddresses not supported\n")); } ConfigInfo->InitiatorBusId[0] = 7; ConfigInfo->InitiatorBusId[1] = 7; ConfigInfo->InitiatorBusId[2] = 7; ConfigInfo->InitiatorBusId[3] = 7; xsdd->shadow_free = 0; memset(xsdd->shadows, 0, sizeof(vscsiif_shadow_t) * SHADOW_ENTRIES); for (i = 0; i < SHADOW_ENTRIES; i++) { xsdd->shadows[i].req.rqid = (USHORT)i; put_shadow_on_freelist(xsdd, &xsdd->shadows[i]); } if (!dump_mode) { InitializeListHead(&xsdd->dev_list_head); /* should do something if we haven't enumerated in a certain time */ RtlStringCbCopyA(path, ARRAY_SIZE(path), xsdd->vectors.backend_path); RtlStringCbCatA(path, ARRAY_SIZE(path), "/vscsi-devs"); xsdd->vectors.XenBus_AddWatch(xsdd->vectors.context, XBT_NIL, path, XenScsi_DevWatch, xsdd); } FUNCTION_EXIT(); return SP_RETURN_FOUND; }
BOOLEAN AdapterPresent( IN PVOID HwDeviceExtension, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN OUT PULONG AdapterCount ) /*++ Routine Description: Determine if WD7000EX SCSI adapter is installed in system by reading the EISA board configuration registers for each EISA slot looking for the correct signature. Arguments: HwDeviceExtension - HBA miniport driver's adapter data storage ConfigInfo - Supplies the configuration information stucture. If an adapter is found the access range is update. AdapterCount - Supplies the count of slots which have already been checked. Return Value: TRUE if adapter present. --*/ { PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension; ULONG eisaSlotNumber; PEISA_CONTROLLER eisaController; // // Check to see if adapter present in system. // for (eisaSlotNumber=*AdapterCount + 1; eisaSlotNumber<MAXIMUM_EISA_SLOTS; eisaSlotNumber++) { // // Update the adapter count. // (*AdapterCount)++; // // Get the system address for this card. The card uses I/O space. // If ConfigInfo already has default information about this // controller, use it. If not, then we derive our own. This // is for Chicago compatibility. // if (ScsiPortConvertPhysicalAddressToUlong( (*ConfigInfo->AccessRanges)[0].RangeStart) != 0) { eisaController = ScsiPortGetDeviceBase( deviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, (*ConfigInfo->AccessRanges)[0].RangeStart, (*ConfigInfo->AccessRanges)[0].RangeLength, (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory)); } else { eisaController = ScsiPortGetDeviceBase( deviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, ScsiPortConvertUlongToPhysicalAddress(0x1000 * eisaSlotNumber), 0x1000, TRUE); } eisaController = (PEISA_CONTROLLER)((PUCHAR)eisaController + EISA_ADDRESS_BASE); if ((ScsiPortReadPortUchar(&eisaController->BoardId[0]) == 0x5C) && (ScsiPortReadPortUchar(&eisaController->BoardId[1]) == 0x83) && (ScsiPortReadPortUchar(&eisaController->BoardId[2]) == 0x20)) { deviceExtension->EisaController = eisaController; return TRUE; } // // The card is not here so clean up. // ScsiPortFreeDeviceBase(deviceExtension, (PUCHAR)eisaController - EISA_ADDRESS_BASE); } // end for (eisaSlotNumber ... // // Clear the adapter count for the next bus. // *AdapterCount = 0; return FALSE; } // end AdapterPresent()