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

📄 ax88172.c

📁 Axis ax88172 USB 界面网卡驱动源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		&NextDeviceObject,
		&AllocatedResources,
		&AllocatedResourcesTranslated
		);


	USBD_GetUSBDIVersion( &UsbVersionInfo );
	if ( (UsbVersionInfo.USBDI_Version < AcceptedUSBDIVersion) ||
		(UsbVersionInfo.Supported_USB_Version < AcceptedUSBVersion) )
		return NDIS_STATUS_NOT_SUPPORTED;

	siz = sizeof(USB_CONFIGURATION_DESCRIPTOR) +128;
	while (TRUE)
	{
		Adapter->UsbConfigurationDescriptor =
				ExAllocatePool(
					NonPagedPool,
					siz
					);
		UsbBuildGetDescriptorRequest(
			&Urb,
			(USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
			USB_CONFIGURATION_DESCRIPTOR_TYPE,
			0,
			0,
			Adapter->UsbConfigurationDescriptor,
			NULL,
			siz,
			NULL
			);
		if ( !NT_SUCCESS(BulkUsb_CallUSBD(Adapter, &Urb)) )
			return NDIS_STATUS_HARD_ERRORS;
		if (Urb.UrbControlDescriptorRequest.TransferBufferLength > 0 &&
			Adapter->UsbConfigurationDescriptor->wTotalLength > siz)
		{
			siz = Adapter->UsbConfigurationDescriptor->wTotalLength;
			ExFreePool(Adapter->UsbConfigurationDescriptor);
			Adapter->UsbConfigurationDescriptor = NULL;
		}
		else
			break;  // we got it!
	}

	i = Adapter->UsbConfigurationDescriptor->bNumInterfaces;
	tmp = interfaceList = ExAllocatePool(
					NonPagedPool,
					sizeof(USBD_INTERFACE_LIST_ENTRY)*(i+1)
					);
	for ( i=0; i<Adapter->UsbConfigurationDescriptor->bNumInterfaces; i++ )
	{
		// Get the next matching descriptor. Here we implicitly use
		// the fact that the interface descriptors are laid out in order in memory.
		UsbInterfaceDescriptor =
				USBD_ParseConfigurationDescriptorEx(
					Adapter->UsbConfigurationDescriptor,
					Adapter->UsbConfigurationDescriptor,
					i,	// interface number
					-1,	// alternate setting
					-1,
					-1,
					-1
					);
		interfaceList->InterfaceDescriptor = UsbInterfaceDescriptor;
		interfaceList++;
	}
	interfaceList->InterfaceDescriptor = NULL;

	pUrb = USBD_CreateConfigurationRequestEx(
			Adapter->UsbConfigurationDescriptor,
			tmp
			);
	ExFreePool(tmp);
	if (!pUrb)
		return NDIS_STATUS_ADAPTER_NOT_FOUND;

	Adapter->UsbConfigurationHandle = pUrb->UrbSelectConfiguration.ConfigurationHandle;
	UsbInterface = &pUrb->UrbSelectConfiguration.Interface;
	if ( !NT_SUCCESS(BulkUsb_CallUSBD(Adapter, pUrb)) )
	{
		ExFreePool(pUrb);
		return NDIS_STATUS_HARD_ERRORS;
	}
	for (i=0; i< UsbInterface->NumberOfPipes; i++)
	{
		PUSBD_PIPE_INFORMATION	PipeInfo = &UsbInterface->Pipes[i];

		switch (PipeInfo->PipeType)
		{
		case UsbdPipeTypeBulk:
			Adapter->MaximumPacketSize = PipeInfo->MaximumPacketSize;
			if (PipeInfo->EndpointAddress & 0x80)
				Adapter->ReceivePipe = PipeInfo->PipeHandle;
			else
				Adapter->TransmitPipe = PipeInfo->PipeHandle;
			break;
		case UsbdPipeTypeInterrupt:
			Adapter->InterruptPipe = PipeInfo->PipeHandle;
			break;
		default:
			break;
		}
	}
	ExFreePool(pUrb);

	UsbBuildVendorRequest(
		&Urb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
		0,
		0x1c,
		0,
		0,
		MiiData,
		NULL,
		1,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);
	Adapter->ChipVersion = MiiData[0];

	//Read SROM - MiiPhy Address (ID)
	UsbBuildVendorRequest(
		&Urb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
		0,
		25,
		0,
		0,
		MiiData,
		NULL,
		2,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);
	Adapter->SecondaryPhy = MiiData[0]&0x1f;
	Adapter->SecondaryPhyType = (MiiData[0]>>5)&7;
	Adapter->PrimaryPhy = MiiData[1]&0x1f;
	Adapter->PrimaryPhyType = (MiiData[1]>>5)&7;

	//Read Multicast Filtering Array
	UsbBuildVendorRequest(
		&Urb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
		0,
		0x15,
		0,
		0,
		Adapter->mcFilter,
		NULL,
		8,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);

	///
	// PHY Connection Type Setup!
	///
	PhyInitial( Adapter );

	//
	// Initialize the receive variables.
	Adapter->PendingInterrupt.Adapter = Adapter;
	Adapter->PendingTransmit.Adapter = Adapter;
	Adapter->PendingReceive.Adapter = Adapter;

	///
	// USB Initialize!
	///

	///
	// Reads in the Ethernet address from the ASIX AX88172.
	// The address is stored in Adapter->PermanentAddress,
	// and StationAddress if it is currently zero.
	///

	UsbBuildVendorRequest(
		&Urb,
		URB_FUNCTION_VENDOR_DEVICE,
		sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
		USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK,
		0,
		0x17,
		0,
		0,
		&Adapter->PermanentAddress[0],
		NULL,
		6,
		NULL
		);
	BulkUsb_CallUSBD(Adapter, &Urb);

	//
	// Use the burned in address as the station address, unless the
	// registry specified an override value.
	if ( (Adapter->StationAddress[0] |Adapter->StationAddress[1]
		|Adapter->StationAddress[2] |Adapter->StationAddress[3]
		|Adapter->StationAddress[4] |Adapter->StationAddress[5]) == 0 )
	{
		NdisMoveMemory(
			Adapter->StationAddress,
			Adapter->PermanentAddress,
			AX88172_LENGTH_OF_ADDRESS
			);
	}

	return NDIS_STATUS_SUCCESS;

}


#pragma NDIS_PAGEABLE_FUNCTION(AX88172Initialize)
//extern
NDIS_STATUS
AX88172Initialize(
	OUT PNDIS_STATUS	OpenErrorStatus,
	OUT PUINT	SelectedMediumIndex,
	IN PNDIS_MEDIUM	MediumArray,
	IN UINT		MediumArraySize,
	IN NDIS_HANDLE	MiniportAdapterHandle,
	IN NDIS_HANDLE	ConfigurationHandle
	)

/*++

Routine Description:

    AX88172Initialize starts an adapter and registers resources with the
    wrapper.

Arguments:

    OpenErrorStatus - Extra status bytes for opening token ring adapters.
    SelectedMediumIndex - Index of the media type chosen by the driver.
    MediumArray - Array of media types for the driver to chose from.
    MediumArraySize - Number of entries in the array.
    MiniportAdapterHandle - Handle for passing to the wrapper when
	referring to this adapter.

    ConfigurationHandle - A handle to pass to NdisOpenConfiguration.

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_PENDING

--*/

{
	//
	// Temporary looping variable.
	UINT	i;

	//
	// Status of Ndis calls.
	NDIS_STATUS	Status;

	//
	// Pointer to our newly allocated adapter.
	PAX_ADAPTER	Adapter;

	//
	// The handle for reading from the registry.
	NDIS_HANDLE	ConfigHandle;

	//
	// The value read from the registry.
	PNDIS_CONFIGURATION_PARAMETER	ReturnedValue;

	//
	// String names of all the parameters that will be read.
	NDIS_STRING	ConnectionTypeStr = NDIS_STRING_CONST("ConnectionType");
	NDIS_STRING	RemoteWakeupStr = NDIS_STRING_CONST("RemoteWakeup");
	NDIS_STRING	FlowControlStr = NDIS_STRING_CONST("FlowControl");
	NDIS_STRING	PhoneLineStr = NDIS_STRING_CONST("PhoneLine");

	//
	// Search for the medium type (802.3) in the given array.
	for (i = 0; i < MediumArraySize; i++)
		if (MediumArray[i] == NdisMedium802_3)
			break;
	if (i == MediumArraySize)
		return NDIS_STATUS_UNSUPPORTED_MEDIA;
	*SelectedMediumIndex = i;


	//
	// Allocate memory for the adapter block now.
	Status =
		NdisAllocateMemoryWithTag(
			(PVOID *)&Adapter,
			sizeof(struct _AX_ADAPTER),
			'ASIX'
			);
	if (Status != NDIS_STATUS_SUCCESS)
		return Status;

	//
	// Clear out the adapter block,
	// which sets all default values to FALSE or NULL.
	NdisZeroMemory (Adapter, sizeof(struct _AX_ADAPTER));

	//
	// Open the configuration space.
	NdisOpenConfiguration(
		&Status,
		&ConfigHandle,
		ConfigurationHandle
		);
	if (Status == NDIS_STATUS_SUCCESS)
	{
		//
		// connection type.
		NdisReadConfiguration(
			&Status,
			&ReturnedValue,
			ConfigHandle,
			&ConnectionTypeStr,
			NdisParameterInteger
			);
		if (Status == NDIS_STATUS_SUCCESS)
			Adapter->uConnectionType = (UINT)ReturnedValue->ParameterData.IntegerData;

		//
		// remote wakeup.
		NdisReadConfiguration(
			&Status,
			&ReturnedValue,
			ConfigHandle,
			&RemoteWakeupStr,
			NdisParameterInteger
			);
		if (Status == NDIS_STATUS_SUCCESS)
			Adapter->uRemoteWakeup = (USHORT)ReturnedValue->ParameterData.IntegerData & 0x000e;

		//
		// flow control.
		NdisReadConfiguration(
			&Status,
			&ReturnedValue,
			ConfigHandle,
			&FlowControlStr,
			NdisParameterHexInteger
			);
		if (Status == NDIS_STATUS_SUCCESS)
			Adapter->FlowControl = ReturnedValue->ParameterData.IntegerData? TRUE:FALSE;

		//
		// phone line configure.
		NdisReadConfiguration(
			&Status,
			&ReturnedValue,
			ConfigHandle,
			&PhoneLineStr,
			NdisParameterHexInteger
			);
		if (Status == NDIS_STATUS_SUCCESS)
			Adapter->uPhoneLine = ((USHORT)ReturnedValue->ParameterData.IntegerData &6) |0x0040;
		else
			Adapter->uPhoneLine = 0x0044;

		//
		// Close the configuration space.
		NdisCloseConfiguration(ConfigHandle);
	}


	//
	// Now to use this information and register with the wrapper
	// and initialize the adapter.
	//


	//
	// Inform the wrapper of the physical attributes of this adapter.
	NdisMSetAttributesEx(
		MiniportAdapterHandle,
		(NDIS_HANDLE)Adapter,
		2,
		NDIS_ATTRIBUTE_DESERIALIZE,
		NdisInterfacePci
		);

	Adapter->MiniportAdapterHandle = MiniportAdapterHandle;

	//
	// Set up the parameters.
	Adapter->MaxLookAhead = AX88172_MAX_LOOKAHEAD;

	Adapter->FixedPhy = TRUE;
	switch (Adapter->uConnectionType)
	{
	case 2:
		Adapter->uConnectionType = MiiPhyNway10BaseT
				|MiiPhyExtendedCapabilities;
		break;
	case 3:
		Adapter->uConnectionType = MiiPhyNway10BaseT
				|MiiPhyNway10BaseTFD
				|MiiPhyNwayPauseEnable
				|MiiPhyExtendedCapabilities;
		break;
	case 8:
		Adapter->uConnectionType = MiiPhyNway10BaseT
				|MiiPhyNway10BaseTFD
				|MiiPhyNway100BaseTx
				|MiiPhyExtendedCapabilities;
		break;
	default:
		switch (Adapter->uConnectionType)
		{
		case 102:
		case 108:
			Adapter->PhoneNetworkMedia = TRUE;
			Adapter->uConnectionType -= 100;
			break;
		default:
			Adapter->uConnectionType = 0;
			break;
		}
		if ( Adapter->uConnectionType )
			break;
	case 0:
		Adapter->FixedPhy = FALSE;
	case 9:
		Adapter->uConnectionType = MiiPhyNway10BaseT
				|MiiPhyNway10BaseTFD
				|MiiPhyNway100BaseTx
				|MiiPhyNway100BaseTxFD
				|MiiPhyNwayPauseEnable
				|MiiPhyExtendedCapabilities;
		break;
	}

	Status = AX88172RegisterAdapter( Adapter );
	if ( Adapter->UsbConfigurationDescriptor )
	{
		if ( ~Adapter->UsbConfigurationDescriptor->bmAttributes&0x20 )
			Adapter->uRemoteWakeup = 0;
		ExFreePool(Adapter->UsbConfigurationDescriptor);
	}
	if (Status != NDIS_STATUS_SUCCESS)
	{
		NdisFreeMemory(
			Adapter,
			sizeof(struct _AX_ADAPTER),
			0
			);
		return Status;
	}

	Adapter->NextAdapter = AX88172MiniportBlock.AdapterQueue;
	AX88172MiniportBlock.AdapterQueue = Adapter;


	NdisMInitializeTimer(
		&Adapter->ReceiveTimer,
		MiniportAdapterHandle,
		(PNDIS_TIMER_FUNCTION)&AXWaitReceive,
		(PVOID)Adapter
		);
	NdisMInitializeTimer(
		&Adapter->ReceiveHandleTimer,
		MiniportAdapterHandle,
		(PNDIS_TIMER_FUNCTION)&AXReceiveHandler,
		(PVOID)Adapter
		);
	NdisMInitializeTimer(
		&Adapter->TransmitTimer,
		MiniportAdapterHandle,
		(PNDIS_TIMER_FUNCTION)&AXWaitTransmit,
		(PVOID)Adapter
		);
	NdisMInitializeTimer(
		&Adapter->TransmitHandleTimer,
		MiniportAdapterHandle,
		(PNDIS_TIMER_FUNCTION)&AXTransmitHandler,
		(PVOID)Adapter
		);
	NdisMInitializeTimer(
		&Adapter->InterruptTimer,
		MiniportAdapterHandle,
		(PNDIS_TIMER_FUNCTION)&AXWaitInterrupt,
		(PVOID)Adapter
		);

	NdisAllocateSpinLock( &Adapter->TransmitSpinLock );
	NdisAllocateSpinLock( &Adapter->ReceiveIoCountSpinLock );
	NdisAllocateSpinLock( &Adapter->TransmitIoCountSpinLock );

	//
	// Start up the adapter.
	CardStart(Adapter);

	return NDIS_STATUS_SUCCESS;

}



VOID
AX88172Halt(
    IN NDIS_HANDLE MiniportAdapterContext
    )

//++
//
//Routine Description:
//	AX88172Halt removes an adapter that was previously initialized.
//
//Arguments:
//	MiniportAdapterContext - The context value that the Miniport returned
//		from AX88172Initialize; actually as pointer to an AX_ADAPTER.
//
//Return Value:
//	None.
//
//--

{
	PAX_ADAPTER	Adapter = PAX_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);


	CardStop( Adapter );

	NdisFreeSpinLock( &Adapter->TransmitIoCountSpinLock );
	NdisFreeSpinLock( &Adapter->ReceiveIoCountSpinLock );
	NdisFreeSpinLock( &Adapter->TransmitSpinLock );

	//
	// Remove the adapter from the global queue of adapters.
	if (AX88172MiniportBlock.AdapterQueue == Adapter)
		AX88172MiniportBlock.AdapterQueue = Adapter->NextAdapter;
	else
	{
		PAX_ADAPTER TmpAdapter = AX88172MiniportBlock.AdapterQueue;

		while ( TmpAdapter )
		{
			if (TmpAdapter->NextAdapter == Adapter)
			{
				TmpAdapter->NextAdapter = Adapter->NextAdapter;
				break;
			}
			TmpAdapter = TmpAdapter->NextAdapter;
		}
	}
	NdisFreeMemory(
		Adapter,
		sizeof(struct _AX_ADAPTER),
		0
		);

	if (AX88172MiniportBlock.AdapterQueue == NULL)
		NdisTerminateWrapper(
			AX88172MiniportBlock.NdisWrapperHandle,
			NULL
			);

}


BOOLEAN
AXCheckForHang(
	IN NDIS_HANDLE	MiniportAdapterContext
	)
{
	PAX_ADAPTER	Adapter = (PAX_ADAPTER)(MiniportAdapterContext);

	if ( Adapter->HaltEvents )
		CardStop( Adapter );
	if ( !Adapter->fgReady )
		return FALSE;
	if ( Adapter->fgBusy )
		return Adapter->fgBusy = FALSE;

	return FALSE;

}


NDIS_STATUS
AX88172QueryInformation(
	IN NDIS_HANDLE	MiniportAdapterContext,
	IN NDIS_OID	Oid,
	IN PVOID	InformationBuffer,
	IN ULONG	InformationBufferLength,
	OUT PULONG	BytesWritten,
	OUT PULONG	BytesNeeded
	)

//++
//Routine Description:
//	The AX88172QueryInformation process a Query request for
//	NDIS_OIDs that are specific about the Driver.
//
//Arguments:
//	MiniportAdapterContext - a pointer to the adapter.
//	Oid - the NDIS_OID to process.
//	InformationBuffer -  a pointer into the NdisRequest->InformationBuffer
//		into which store the result of the query.
//	InformationBufferLength - a pointer to the number of bytes left in the
//		InformationBuffer.
//	BytesWritten - a pointer to the number of bytes written into the
//		InformationBuffer.
//	BytesNeeded - If there is not enough room in the information buffer then
//		this will contain the number of bytes needed to complete the request.
//
//Return Value:
//	The function value is the status of the operation.
//
//--
{
	//
	// Pointer to the adapter structure.
	PAX_ADAPTER	Adapter = (PAX_ADAPTER)MiniportAdapterContext;

	NDIS_STATUS	StatusToReturn = NDIS_STATUS_SUCCESS;
	NDIS_MEDIUM	Medium;
	NDIS_HARDWARE_STATUS	HardwareStatus;

	//
	// This variable holds result of query
	union {
		ULONG	lValue;
		USHORT	sValue;
		UCHAR	cArray[6];
	} GenericData;
	UINT	MoveBytes = sizeof(ULONG);
	PVOID	MoveSource = (PVOID)(&GenericData.lValue);
	URB	Urb;

	//
	// Make sure that int is 4 bytes,
	// else GenericData.lValue must change to something of size 4.
	ASSERT(sizeof(ULONG) == 4);

    switch (Oid)
    {
    case OID_GEN_MAC_OPTIONS:

	GenericData.lValue = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND	|
				NDIS_MAC_OPTION_RECEIVE_SERIALIZED	|
				NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA	|
				NDIS_MAC_OPTION_FULL_DUPLEX		|
				NDIS_MAC_OPTION_NO_LOOPBACK);
	break;

    case OID_GEN_SUPPORTED_LIST:

	MoveSource = (PVOID)(AX88172SupportedOids);
	MoveBytes = sizeof(AX88172SupportedOids);
	break;

    case OID_GEN_HARDWARE_STATUS:

	HardwareStatus = NdisHardwareStatusReady;
	MoveSource = (PVOID)(&HardwareStatus);
	MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
	break;

    case OID_GEN_MEDIA_SUPPORTED:
    case OID_GEN_MEDIA_IN_USE:

	Medium = NdisMedium802_3;

⌨️ 快捷键说明

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