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

📄 amcc_orig.cpp

📁 The PCI Local bus concept was developed to break the PC data I/O bottleneck and clearly opens the d
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*

Function Name:

	SheldonFIFOWrite

Routine Description:

    Write to the FIFO.

Arguments:

	Irp - I/O request being serviced

	pdx - pointer to the device extension.

Return Value:

    STATUS_SUCCESS

*/
NTSTATUS SheldonFIFOWrite(PIRP Irp, PDEVICE_EXTENSION pdx)
{
	PULONG params;

	// get a ULONG pointer to the mailbox number
	params = (PULONG) Irp->AssociatedIrp.SystemBuffer;
	

	// write the data
/////////////////
// IO and memory mapped
/////////////////
	if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
		// make sure the write FIFO is not full, as writing to a full FIFO locks 
		// the machine with this PCI controller
		if(READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR) & AMCC_WRITE_FIFO_FULL_MASK)
			return STATUS_BUFFER_TOO_SMALL;

		WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_FIFO, *params);
	}
	else {
		// make sure the write FIFO is not full, as writing to a full FIFO locks 
		// the machine with this PCI controller
		if(READ_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR) & AMCC_WRITE_FIFO_FULL_MASK)
			return STATUS_BUFFER_TOO_SMALL;

		WRITE_PORT_ULONG(pdx->base[AMCC_OPREGS] + AMCC_FIFO, *params);
	}

/////////////////
// Memory mapped Only
/////////////////
//	// make sure the write FIFO is not full, as writing to a full FIFO locks 
//	// the machine with this PCI controller
//	if(READ_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_MCSR) & AMCC_WRITE_FIFO_FULL_MASK)
//		return STATUS_BUFFER_TOO_SMALL;
//
//	WRITE_REGISTER_ULONG(pdx->base[AMCC_OPREGS] + AMCC_FIFO, *params);

	return STATUS_SUCCESS;
}

/*

Function Name:

	SheldonNVRead

Routine Description:

    Read from the NVRam.

Arguments:

	Irp - I/O request being serviced

	pdx - pointer to the device extension.

Return Value:

    STATUS_SUCCESS if successful
	STATUS_TIMEOUT if timeout occurs

*/
NTSTATUS SheldonNVRamRead(PIRP Irp, PDEVICE_EXTENSION pdx)
{
	PULONG params;
	PUCHAR NV_Control_Reg, NV_Data_Reg;
	ULONG Attempts = 0;

	params = (PULONG) Irp->AssociatedIrp.SystemBuffer;		
	NV_Control_Reg = ((PUCHAR) (pdx->base[AMCC_OPREGS])) + AMCC_NV_CONTROL_REG_OFFSET;
	NV_Data_Reg=((PUCHAR) (pdx->base[AMCC_OPREGS])) + AMCC_NV_DATA_REG_OFFSET;

/////////////////
// IO and memory mapped
/////////////////
	if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
		// wait while device busy
		while(Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_REGISTER_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
			Attempts++;

		if(Attempts == AMCC_NV_MAX_ATTEMPTS)
			return STATUS_TIMEOUT;

		// once free, set the control reg for low address
		WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_LOW_ADDRESS_COMMAND);
		// then write the low part of the address
		WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) (*params & 0x000000FF));
		// set up for high half of address
		WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_HIGH_ADDRESS_COMMAND);
		// then write the high part of the address
		WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) ((*params >> 8) & 0x000000FF));
		// now send the read command
		WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_READ_COMMAND);

		Attempts = 0;	// reset the timeout counter

		// wait while device busy
		while(Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_REGISTER_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
			Attempts++;

		if(Attempts == AMCC_NV_MAX_ATTEMPTS)
			return STATUS_TIMEOUT;

		// now read the data and put it into the outgoing buffer
		*params = (ULONG) READ_REGISTER_UCHAR(NV_Data_Reg);
	}
	else {
		// wait while device busy
		while(Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_PORT_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
			Attempts++;

		if(Attempts == AMCC_NV_MAX_ATTEMPTS)
			return STATUS_TIMEOUT;

		// once free, set the control reg for low address
		WRITE_PORT_UCHAR(NV_Control_Reg, AMCC_NV_LOW_ADDRESS_COMMAND);
		// then write the low part of the address
		WRITE_PORT_UCHAR(NV_Data_Reg, (UCHAR) (*params & 0x000000FF));
		// set up for high half of address
		WRITE_PORT_UCHAR(NV_Control_Reg, AMCC_NV_HIGH_ADDRESS_COMMAND);
		// then write the high part of the address
		WRITE_PORT_UCHAR(NV_Data_Reg, (UCHAR) ((*params >> 8) & 0x000000FF));
		// now send the read command
		WRITE_PORT_UCHAR(NV_Control_Reg, AMCC_NV_READ_COMMAND);

		Attempts = 0;	// reset the timeout counter

		// wait while device busy
		while(Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_PORT_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
			Attempts++;

		if(Attempts == AMCC_NV_MAX_ATTEMPTS)
			return STATUS_TIMEOUT;

		// now read the data and put it into the outgoing buffer
		*params = (ULONG) READ_PORT_UCHAR(NV_Data_Reg);
	}

/////////////////
// Memory mapped Only
/////////////////
//	// wait while device busy
//	while(Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_REGISTER_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
//		Attempts++;
//
//	if(Attempts == AMCC_NV_MAX_ATTEMPTS)
//		return STATUS_TIMEOUT;
//
//	// once free, set the control reg for low address
//	WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_LOW_ADDRESS_COMMAND);
//	// then write the low part of the address
//	WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) (*params & 0x000000FF));
//	// set up for high half of address
//	WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_HIGH_ADDRESS_COMMAND);
//	// then write the high part of the address
//	WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) ((*params >> 8) & 0x000000FF));
//	// now send the read command
//	WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_READ_COMMAND);
//
//	Attempts = 0;	// reset the timeout counter
//
//	// wait while device busy
//	while(Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_REGISTER_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
//		Attempts++;
//
//	if(Attempts == AMCC_NV_MAX_ATTEMPTS)
//		return STATUS_TIMEOUT;
//
//	// now read the data and put it into the outgoing buffer
//	*params = (ULONG) READ_REGISTER_UCHAR(NV_Data_Reg);

	return STATUS_SUCCESS;
}

/*

Function Name:

	SheldonNVRAMWrite

Routine Description:

    Write to the NVRam.

Arguments:

	Irp - I/O request being serviced

	pdx - pointer to the device extension.

Return Value:

    STATUS_SUCCESS if successful
	STATUS_TIMEOUT if timeout occurs

*/
NTSTATUS SheldonNVRamWrite(PIRP Irp, PDEVICE_EXTENSION pdx)
{
	PULONG params;
	PUCHAR NV_Control_Reg, NV_Data_Reg;
	ULONG Attempts = 0;

	params = (PULONG) Irp->AssociatedIrp.SystemBuffer;		
	NV_Control_Reg = ((PUCHAR) (pdx->base[AMCC_OPREGS])) + AMCC_NV_CONTROL_REG_OFFSET;
	NV_Data_Reg=((PUCHAR) (pdx->base[AMCC_OPREGS])) + AMCC_NV_DATA_REG_OFFSET;

/////////////////
// IO and memory mapped
/////////////////
	if( (ULONG)pdx->base[AMCC_OPREGS] & 0xffff0000 ) {
		// wait while device busy
		while (Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_REGISTER_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
			Attempts++;

		if (Attempts == AMCC_NV_MAX_ATTEMPTS)
			return STATUS_TIMEOUT;

		// once free, set the control reg for low address
		WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_LOW_ADDRESS_COMMAND);
		// then write the low part of the address
		WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) (params[SI_NV_OFFSET_INDEX] & 0x000000FF));
		// set up for high half of address
		WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_HIGH_ADDRESS_COMMAND);
		// then write the high part of the address
		WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) ((params[SI_NV_OFFSET_INDEX] >> 8) & 0x000000FF));
		// now send a dummy command to latch the address
		WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_NO_COMMAND);
		// now set the data into the data reg
		WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) params[SI_NV_WRITE_DATA_INDEX]);
		// now send the write command
		WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_WRITE_COMMAND);

		// wait while device busy
		while (Attempts<AMCC_NV_MAX_ATTEMPTS && (READ_REGISTER_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
			Attempts++;

		if (Attempts == AMCC_NV_MAX_ATTEMPTS)
			return STATUS_TIMEOUT;
	}
	else {
		// wait while device busy
		while (Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_PORT_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
			Attempts++;

		if (Attempts == AMCC_NV_MAX_ATTEMPTS)
			return STATUS_TIMEOUT;

		// once free, set the control reg for low address
		WRITE_PORT_UCHAR(NV_Control_Reg, AMCC_NV_LOW_ADDRESS_COMMAND);
		// then write the low part of the address
		WRITE_PORT_UCHAR(NV_Data_Reg, (UCHAR) (params[SI_NV_OFFSET_INDEX] & 0x000000FF));
		// set up for high half of address
		WRITE_PORT_UCHAR(NV_Control_Reg, AMCC_NV_HIGH_ADDRESS_COMMAND);
		// then write the high part of the address
		WRITE_PORT_UCHAR(NV_Data_Reg, (UCHAR) ((params[SI_NV_OFFSET_INDEX] >> 8) & 0x000000FF));
		// now send a dummy command to latch the address
		WRITE_PORT_UCHAR(NV_Control_Reg, AMCC_NV_NO_COMMAND);
		// now set the data into the data reg
		WRITE_PORT_UCHAR(NV_Data_Reg, (UCHAR) params[SI_NV_WRITE_DATA_INDEX]);
		// now send the write command
		WRITE_PORT_UCHAR(NV_Control_Reg, AMCC_NV_WRITE_COMMAND);

		// wait while device busy
		while (Attempts<AMCC_NV_MAX_ATTEMPTS && (READ_PORT_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
			Attempts++;

		if (Attempts == AMCC_NV_MAX_ATTEMPTS)
			return STATUS_TIMEOUT;
	}

/////////////////
// Memory mapped Only
/////////////////
//	// wait while device busy
//	while (Attempts < AMCC_NV_MAX_ATTEMPTS && (READ_REGISTER_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
//		Attempts++;
//
//	if (Attempts == AMCC_NV_MAX_ATTEMPTS)
//		return STATUS_TIMEOUT;
//
//	// once free, set the control reg for low address
//	WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_LOW_ADDRESS_COMMAND);
//	// then write the low part of the address
//	WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) (params[SI_NV_OFFSET_INDEX] & 0x000000FF));
//	// set up for high half of address
//	WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_HIGH_ADDRESS_COMMAND);
//	// then write the high part of the address
//	WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) ((params[SI_NV_OFFSET_INDEX] >> 8) & 0x000000FF));
//	// now send a dummy command to latch the address
//	WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_NO_COMMAND);
//	// now set the data into the data reg
//	WRITE_REGISTER_UCHAR(NV_Data_Reg, (UCHAR) params[SI_NV_WRITE_DATA_INDEX]);
//	// now send the write command
//	WRITE_REGISTER_UCHAR(NV_Control_Reg, AMCC_NV_WRITE_COMMAND);
//
//	// wait while device busy
//	while (Attempts<AMCC_NV_MAX_ATTEMPTS && (READ_REGISTER_UCHAR(NV_Control_Reg) & AMCC_NV_BUSY_MASK))
//		Attempts++;
//
//	if (Attempts == AMCC_NV_MAX_ATTEMPTS)
//		return STATUS_TIMEOUT;

	return STATUS_SUCCESS;
}

/*

Function Name:

	SheldonMapDirect

Routine Description:

    Enables the user application to directly access the memory map of the device.

Arguments:

	Irp - I/O request being serviced

	pdx - pointer to the device extension.

Return Value:

    STATUS_SUCCESS if successful
	NT status code

*/
NTSTATUS SheldonMapDirect(PIRP Irp, PDEVICE_EXTENSION pdx)
{
	PULONG params;
	NTSTATUS ntStatus = STATUS_SUCCESS;
	int i;

	ULONG				length;
	UNICODE_STRING		physicalMemoryUnicodeString;
	OBJECT_ATTRIBUTES	objectAttributes;
	HANDLE				physicalMemoryHandle  = NULL;
	PVOID				PhysicalMemorySection = NULL;
	PHYSICAL_ADDRESS	viewBase;
	ULONG				virtualAddress;

	KdPrint(("SIWDM - Entering SheldonMapDirect\n"));

	// get a ULONG pointer to the mailbox number	
	params = (PULONG) Irp->AssociatedIrp.SystemBuffer;

	for(i=0;i<PCI_TYPE0_ADDRESSES;i++)
	{
		// Section Used
		if(pdx->base[i])
		{
			pdx->Mdl[i] = IoAllocateMdl((PVOID) pdx->base[i], 
										pdx->base_len[i], FALSE, 
										FALSE, NULL);

			if(pdx->Mdl[i] == NULL)
			{
				SheldonUnMapDirect(pdx);

				return STATUS_NO_MEMORY;
			}

			__try
			{
				MmBuildMdlForNonPagedPool(pdx->Mdl[i]);
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				KdPrint(("SIWDM - SheldonMapDirect: MmBuildMdlForNonPagedPool Exception\n"));
				SheldonUnMapDirect(pdx);

				return STATUS_NO_MEMORY;
			}

			__try
			{
				pdx->Direct_Baddr[i] = 
					((PULONG) (((ULONG) PAGE_ALIGN(MmMapLockedPages(pdx->Mdl[i], UserMode)))
					 + MmGetMdlByteOffset(pdx->Mdl[i])));
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				KdPrint(("SIWDM - SheldonMapDirect: MmMapLockedPages Exception\n"));
				SheldonUnMapDirect(pdx);

				return STATUS_NO_MEMORY;
			}

			params[i] = (ULONG) pdx->Direct_Baddr[i];
		}
		// not used
		else
			params[i] = 0;
	}

	KdPrint(("SIWDM - Exiting SheldonMapDirect\n"));

	return ntStatus;
}

/*

Function Name:

	SheldonUnMapDirect

Routine Description:

    Frees the memory allocated by SheldonMapDirect.

Arguments:

	pdx - pointer to the device extension.

⌨️ 快捷键说明

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