⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcidp_if.cpp

📁 一个amccs5933芯片的驱动程序开发源程序和部分文档
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	else
		RTNStatus = ERROR_INVALID_HANDLE;

	return RTNStatus;
}



// ----------------------------------------------------------------------------
// MapBaseRegister -
// ----------------------------------------------------------------------------
unsigned long Krnl_MapBaseRegister(
	in unsigned long PCIDPHandle,
	in unsigned long RegisterNumber,
	in out unsigned long* Length,
	out unsigned long** Address,
	out unsigned long* IOAddress,
	out unsigned long* IOSpace
){

	// Declare variables.
	unsigned long RTNStatus;
	PCIDP00_MAP_BASE_REGS_SEND Input;
	PCIDP00_MAP_BASE_REGS_RECV Output;
	unsigned long BoardNumber;

	// Initialize variables.
	Input.RegNumber = RegisterNumber;
	Input.Length = *Length;

	// Validate the handle.
	if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){

		// Request the kernel service Map Base Regs.
		BoardNumber = PCIDPHandle & 0x7;
		RTNStatus = RequestService(
			BoardNumber, 
			IOCTL_PCIDP00_MAP_BASE_REGS,
			&Input,
			&Output,
			sizeof(Input),
			sizeof(Output)
		);

		if(RTNStatus == ERROR_SUCCESS){
			*Length = Output.Length;
			*IOSpace = Output.IOSpace;

			if(*IOSpace == 0)
				*Address = (unsigned long*)Output.Address;
			else
				*IOAddress = Output.Address;
		}
	}

	else
		RTNStatus = ERROR_INVALID_HANDLE;

	return RTNStatus;
}


// ----------------------------------------------------------------------------
// UnMapBaseRegister -
// ----------------------------------------------------------------------------
unsigned long Krnl_UnMapBaseRegister(
	in unsigned long PCIDPHandle,
	in unsigned long* Address
){

	// Declare variables.
	unsigned long RTNStatus;
	PCIDP00_UNMAP_SEND Input;
	unsigned long BoardNumber;

	// Initialize variables.
	Input.VirtualAddress = (unsigned long)Address;

	// Validate the handle.
	if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){

		// Request the kernel service Unmap.
		BoardNumber = PCIDPHandle & 0x7;
		RTNStatus = RequestService(
			BoardNumber, 
			IOCTL_PCIDP00_UNMAP,
			&Input,
			NULL,
			sizeof(Input),
			0
		);

	}

	else
		RTNStatus = ERROR_INVALID_HANDLE;

	return RTNStatus;
}


// ----------------------------------------------------------------------------
// MapDMAMemory - 
// ----------------------------------------------------------------------------
unsigned long Krnl_MapDMAMemory(
	in unsigned long PCIDPHandle,
	out unsigned long** LinearAddress, 
	out unsigned long* PhysicalAddress
){

	// Declare variables.
	unsigned long RTNStatus;
	PCIDP00_MAP_DMA_MEM_RECV Output;
	unsigned long BoardNumber;

	// Validate the handle.
	if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){

		// Request the kernel service Map DMA Mem.
		BoardNumber = PCIDPHandle & 0x7;
		RTNStatus = RequestService(
			BoardNumber, 
			IOCTL_PCIDP00_MAP_DMA_MEM,
			NULL,
			&Output,
			0,
			sizeof(Output)
		);

		if(RTNStatus == ERROR_SUCCESS){
			*LinearAddress = (unsigned long*)Output.LinearAddress;
			*PhysicalAddress = Output.PhysicalAddress;
			CancelMapDMAMemory(PCIDPHandle, *LinearAddress);
		}
	}

	else
		RTNStatus = ERROR_INVALID_HANDLE;

	return RTNStatus;
}



// ----------------------------------------------------------------------------
// UnMapDMAMemory - 
// ----------------------------------------------------------------------------
unsigned long Krnl_UnMapDMAMemory(
	in unsigned long PCIDPHandle,
	in unsigned long* Address
){

	// Declare variables.
	unsigned long RTNStatus;
	PCIDP00_UNMAP_DMA_SEND Input;
	unsigned long BoardNumber;

	// Initialize variables.
	Input.LinearAddress = (unsigned long)Address;

	// Validate the handle.
	if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){

		// Request the kernel service Unmap.
		BoardNumber = PCIDPHandle & 0x7;
		RTNStatus = RequestService(
			BoardNumber, 
			IOCTL_PCIDP00_UNMAP_DMA,
			&Input,
			NULL,
			sizeof(Input),
			0
		);

	}

	else
		RTNStatus = ERROR_INVALID_HANDLE;

	return RTNStatus;
}


// ----------------------------------------------------------------------------
// GetPCIConfigurationSpace - 
// ----------------------------------------------------------------------------
unsigned long Krnl_GetPCIConfigurationSpace(
	in unsigned long PCIDPHandle,
	out unsigned long* PCIConfiguration
){
	// Declare variables.
	unsigned long RTNStatus;
	PCIDP00_GET_PCI_CONFIG_REGS_RECV Output;
	unsigned long BoardNumber;
	unsigned long i;

	// Validate the handle.
	if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){

		// Request the kernel service Get PCI Config Regs.
		BoardNumber = PCIDPHandle & 0x7;
		RTNStatus = RequestService(
			BoardNumber, 
			IOCTL_PCIDP00_GET_PCI_CONFIG_REGS,
			NULL,
			&Output,
			0,
			sizeof(Output)
		);

		if(RTNStatus == ERROR_SUCCESS){
			for(i=0; i<16; i++)
				PCIConfiguration[i] = Output.PCIConfigRegs[i];
		}
	}

	else
		RTNStatus = ERROR_INVALID_HANDLE;

	return RTNStatus;
}



// ----------------------------------------------------------------------------
// SetPCIConfigurationSpace - 
// ----------------------------------------------------------------------------
unsigned long Krnl_SetPCIConfigurationSpace(
	in unsigned long PCIDPHandle,
	in unsigned long* PCIConfiguration
){
	// Declare variables.
	unsigned long RTNStatus;
	PCIDP00_SET_PCI_CONFIG_REGS_SEND Input;
	unsigned long BoardNumber;
	unsigned long i;

	// Validate the handle.
	if((PCIDPHandle & 0xFFFFF000) == 0xF0CEB000){

		for(i=0; i<16; i++)
			Input.PCIConfigRegs[i] = PCIConfiguration[i];

		// Request the kernel service Get PCI Config Regs.
		BoardNumber = PCIDPHandle & 0x7;
		RTNStatus = RequestService(
			BoardNumber, 
			IOCTL_PCIDP00_SET_PCI_CONFIG_REGS,
			&Input,
			NULL,
			sizeof(Input),
			0
		);
	}

	else
		RTNStatus = ERROR_INVALID_HANDLE;

	return RTNStatus;
}



// ----------------------------------------------------------------------------
// RegisterInterrupt - 
// ----------------------------------------------------------------------------
unsigned long Krnl_RegisterInterrupt(
	in unsigned long PCIDPHandle,
	in unsigned long InterruptType,
	out void** InterruptID,
	out void** InterruptEvent
){

	// Declare variables.
	BOOL Status;
	unsigned long RTNStatus;
	unsigned long BoardNumber;
  unsigned long HThread;
	unsigned long BytesReturned;
	char* Device;
	unsigned long DeviceLength = 200;
  pTHREAD_PARAMS ThreadParams = new THREAD_PARAMS;

	// Validate the handle.
	if((PCIDPHandle & 0xFFFFF000) != 0xF0CEB000){
		RTNStatus = ERROR_INVALID_HANDLE;
		goto ExitRoutine;
	}

	// Create the nameless events for the interrupt setup. One event
	// will used each time the interrupt occurs.  The other will be
	// used to cancel the interrupt.
	ThreadParams->SyncEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if(ThreadParams->SyncEvent == NULL){
		RTNStatus = GetLastError();
		goto ExitA;
	}

	ThreadParams->EndEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if(ThreadParams->EndEvent == NULL){
		RTNStatus = GetLastError();
		goto ExitB;
	}

	ThreadParams->IntEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if(ThreadParams->IntEvent == NULL){
		RTNStatus = GetLastError();
		goto ExitC;
	}

	// Open the connection between the application and the driver.
	// This connection supports asynchonous I/O so we can return
	// immedidately.

	// Set up the device name based on board number.
	BoardNumber = PCIDPHandle & 0x7;
	Device = new char[DeviceLength];
	RTNStatus = EnumerateBoards(BoardNumber, Device, DeviceLength);
	if(RTNStatus == DeviceLength){
		delete Device;
		DeviceLength *= 2;
		Device = new char[DeviceLength];
		RTNStatus = EnumerateBoards(BoardNumber, Device, DeviceLength);
	}

	// Create a "file" object with which to communicate I/O requests.
	ThreadParams->HDriver = CreateFile(
		Device,
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_OVERLAPPED,
		NULL
	);
	delete Device;

	if(ThreadParams->HDriver == INVALID_HANDLE_VALUE){
		RTNStatus = GetLastError();
		goto ExitD;
	}

	// Set up the information structure for the DeviceIoControl call.
	ThreadParams->Input.InterruptType = InterruptType | 0xF0C00000;
	ThreadParams->AsyncOvl.hEvent = ThreadParams->SyncEvent;

	// Now "call" the driver to register the interrupt using the system
	// DeviceIoControl service.
	Status = DeviceIoControl(
		ThreadParams->HDriver,
		(DWORD) IOCTL_PCIDP00_REGISTER_INTERRUPT,
		&ThreadParams->Input,
		sizeof(PCIDP00_REGISTER_INTERRUPT_SEND),
		NULL,
		0,
		&BytesReturned,
		&ThreadParams->AsyncOvl
	);
	RTNStatus = GetLastError();
	if(RTNStatus != ERROR_IO_PENDING)
		goto ExitE;

	// Now create the thread which will handle the interrupt
	// I/O between the application and the driver.
	HThread = _beginthread(
		InterruptThread,
		0x1000,
		(LPVOID)ThreadParams
	);
	if(HThread == (ULONG)-1){
		RTNStatus = errno;
		goto ExitF;
	}

	// The service is a success.  Interrupt handling is in place.
	Sleep(500);
	RTNStatus = ERROR_SUCCESS;
	*InterruptID = ThreadParams->EndEvent;
	*InterruptEvent = ThreadParams->IntEvent;
	goto ExitRoutine;

	ExitF:
		DeviceIoControl(
			ThreadParams->HDriver,
			(DWORD) IOCTL_PCIDP00_UNREGISTER_INTERRUPT,
			&ThreadParams->Input,
			sizeof(PCIDP00_REGISTER_INTERRUPT_SEND),
			NULL,
			0,
			&BytesReturned,
			NULL
		);

	ExitE:
		CloseHandle(ThreadParams->HDriver);
	ExitD:
		CloseHandle(ThreadParams->IntEvent);
	ExitC:
		CloseHandle(ThreadParams->EndEvent);
	ExitB:
		CloseHandle(ThreadParams->SyncEvent);
	ExitA:
		delete ThreadParams;

	ExitRoutine:
		return RTNStatus;
}




// ----------------------------------------------------------------------------
// UnregisterInterrupt - 
// ----------------------------------------------------------------------------
unsigned long Krnl_UnRegisterInterrupt(
	in unsigned long PCIDPHandle,
	in void* InterruptID
){

  SetEvent(InterruptID);
	Sleep(500);

	return ERROR_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -