static u8 ReadVirtIODeviceByte(ULONG_PTR ulRegister) { if (ulRegister & ~PORT_MASK) { return ScsiPortReadRegisterUchar((PUCHAR)(ulRegister)); } else { return ScsiPortReadPortUchar((PUCHAR)(ulRegister)); } }
BOOLEAN Wd7000ExAdapterState( IN PVOID DeviceExtension, IN PVOID AdaptersFound, IN BOOLEAN SaveState ) /*++ Routine Description: Saves/restores adapter's real-mode configuration state. Arguments: DeviceExtension - Adapter object device extension. AdaptersFound - Passed through from DriverEntry as additional context for the call. SaveState - TRUE = Save adapter state, FALSE = restore state. Return Value: The spec did not intend for this routine to have a return value. Whoever did the header file just forgot to change the BOOLEAN to a VOID. We will just return FALSE to shot the compiler up. --*/ { PHW_DEVICE_EXTENSION deviceExtension = DeviceExtension; if (SaveState) { // // Remember system interrupt state. // deviceExtension->InterruptState = ScsiPortReadPortUchar( &deviceExtension->EisaController->SystemInterruptEnable); } else { // // Restore system interrupt state. // ScsiPortWritePortUchar(&deviceExtension->EisaController->SystemInterruptEnable, deviceExtension->InterruptState); } return FALSE; }
ULONG Wd7000ExFindAdapter( IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again ) /*++ Routine Description: This function is called by the OS-specific port driver after the necessary storage has been allocated, to gather information about the adapter's configuration. Arguments: HwDeviceExtension - HBA miniport driver's adapter data storage ConfigInfo - Configuration information structure describing HBA Return Value: TRUE if adapter present in system --*/ { PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension; PEISA_CONTROLLER eisaController; PULONG adapterCount = Context; PNONCACHED_EXTENSION ncExtension; ULONG eisaSlotNumber; PICB icb; PADAPTER_INQUIRY adapterInquiry; ULONG physicalIcb; ULONG i; ULONG length; UCHAR status; // // Check to see if adapter present in system. // if (!AdapterPresent(deviceExtension, ConfigInfo, Context)) { DebugPrint((1,"Wd7000EX: SCSI adapter not present\n")); *Again = FALSE; return SP_RETURN_NOT_FOUND; } // // There is still more to look at. // *Again = FALSE; // // Fill in the access array information only if there are no // default parameters already there. // if (ScsiPortConvertPhysicalAddressToUlong( (*ConfigInfo->AccessRanges)[0].RangeStart) == 0) { *Again = TRUE; (*ConfigInfo->AccessRanges)[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0x1000 * (*((PULONG) Context)) + EISA_ADDRESS_BASE); (*ConfigInfo->AccessRanges)[0].RangeLength = sizeof(EISA_CONTROLLER); (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE; // // Indicate maximum transfer length in bytes. // ConfigInfo->MaximumTransferLength = MAXIMUM_TRANSFER_SIZE; // // Maximum number of physical segments is 32. // ConfigInfo->NumberOfPhysicalBreaks = MAXIMUM_SDL_SIZE; // // Set the configuration parameters for this card. // ConfigInfo->NumberOfBuses = 1; deviceExtension->NumberOfBuses = 1; ConfigInfo->ScatterGather = TRUE; ConfigInfo->Master = TRUE; // // Get a noncached extension for an adapter inquiry command. // ncExtension = ScsiPortGetUncachedExtension( deviceExtension, ConfigInfo, sizeof(NONCACHED_EXTENSION)); if (ncExtension == NULL) { // // Log error. // ScsiPortLogError( deviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 6 << 16 ); return SP_RETURN_ERROR; } length = sizeof(NONCACHED_EXTENSION); // // Convert virtual to physical address. // physicalIcb = ScsiPortConvertPhysicalAddressToUlong( ScsiPortGetPhysicalAddress(deviceExtension, NULL, ncExtension, &length)); // // Initialize the pointers. // icb = &ncExtension->Icb; adapterInquiry = &ncExtension->AdapterInquiry; // // Create ICB for Adapter Inquiry Command. // icb->IcbFlags = 0; icb->CompletionStatus = 0; icb->Reserved = 0; icb->DataBufferAddress = ScsiPortConvertPhysicalAddressToUlong( ScsiPortGetPhysicalAddress( deviceExtension, NULL, adapterInquiry, &length)); icb->TransferCount = sizeof(ADAPTER_INQUIRY); icb->OpCode = ADAPTER_INQUIRY_COMMAND; // // Get ICB physical address. // physicalIcb = ScsiPortConvertPhysicalAddressToUlong( ScsiPortGetPhysicalAddress( deviceExtension, NULL, icb, &length)); // // Disable system interrupts. // ScsiPortWritePortUchar(&deviceExtension->EisaController->SystemInterruptEnable, SYSTEM_INTERRUPTS_DISABLE); // // Write ICB physical address and command to mailbox. // SendCommand(PROCESS_ICB, physicalIcb, deviceExtension); // // Poll for ICB completion. // i = 0; while ((status = ScsiPortReadPortUchar( &deviceExtension->EisaController->ResponseRegister)) == 0) { i++; if (i > 100000) { break; } ScsiPortStallExecution(10); } if (status == 0) { // // The request timed out. Log an error and return. // ScsiPortLogError( deviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 7 << 16 ); return SP_RETURN_ERROR; } DebugPrint((1, "Wd7000ExFindAdapter: Get configuration request time = %d.\n", i * 10)); // // Acknowledge interrupt. // ScsiPortWritePortUchar(&deviceExtension->EisaController->ResponseRegister, 0xFF); // // Enable system interrupts. // ScsiPortWritePortUchar(&deviceExtension->EisaController->SystemInterruptEnable, SYSTEM_INTERRUPTS_ENABLE); // // Check returned status for success. // if (status != COMPLETE_SUCCESS) { // // Give up. // DebugPrint((1,"Wd7000Ex: Response register %x\n", status)); DebugPrint((1,"Wd7000Ex: Adapter inquiry failed\n")); // // Log error. // ScsiPortLogError( deviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 8 << 16 ); return SP_RETURN_ERROR; } // // NOTE: Delay here. I don't understand this latency between // when the device interrupts and the status of the ICB // is success and when the data is actually available in // the buffer. // ScsiPortStallExecution(300); if (adapterInquiry->AdapterInformation & DUAL_CHANNEL) { // // There are two buses on the adapter. // ConfigInfo->InitiatorBusId[1] = (adapterInquiry->ChannelInformation >> 4) & BUS_ID_MASK; ConfigInfo->NumberOfBuses = 2; deviceExtension->NumberOfBuses = 2; }
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()