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

📄 whusb20usb.c

📁 linux 下的驱动程序 欢迎下载
💻 C
📖 第 1 页 / 共 3 页
字号:
//////////////////////////////////////////////////////////////////////////////
//文件名称:Whceb01Usb.cpp
//文件功能:所有的与USB通讯相关的函数实现
//文件作者:张伟标
//工作部门:研究一室
//创建时间:2004年1月9日
//修改记录:
//版权所有:维豪信息技术有限公司
//
//Copyright 2004 WellHope Information Technology Corporation, Ltd.
//All rights reserved.
/////////////////////////////////////////////////////////////////////////////
#include "Whusb20.h"



/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
//	UsbGetPortStatus:	Issue Get Port Status IOCTL
NTSTATUS UsbGetPortStatus( IN PWHCEB01_DEVICE_EXTENSION dx, OUT ULONG* PortStatus)
{
	NTSTATUS status ;

	*PortStatus = 0;

	status = CallUSBDI( dx, PortStatus, IOCTL_INTERNAL_USB_GET_PORT_STATUS , 0 );

	TRACE1( "Got port status. PortStatus = %x", *PortStatus);

	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbResetPort:	Reset port
NTSTATUS UsbResetPort( IN PWHCEB01_DEVICE_EXTENSION dx)
{
	NTSTATUS status ;

	status = CallUSBDI( dx, NULL, IOCTL_INTERNAL_USB_RESET_PORT , 0 );
#ifdef DEBUG_INTERFACE
	TRACE1( "Port reset %x", status);
#endif//DEBUG_INTERFACE
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbResetDevice:	Reset device if port not enabled
NTSTATUS UsbResetDevice( IN PWHCEB01_DEVICE_EXTENSION dx)
{
	ULONG PortStatus = 0 ;

	NTSTATUS status ;

	status = UsbGetPortStatus( dx, &PortStatus);

	if( !NT_SUCCESS(status))
		return status;

	// Give up if device not connected
	if( !(PortStatus & USBD_PORT_CONNECTED))
		return STATUS_NO_SUCH_DEVICE;

	// Return OK if port enabled
	if( PortStatus & USBD_PORT_ENABLED)
		return status;

	// Port disabled so attempt reset
	status = UsbResetPort(dx);
	if( !NT_SUCCESS(status))
		return status;

	// See if it is now working
	status = UsbGetPortStatus( dx, &PortStatus);
	if( !NT_SUCCESS(status))
		return status;
	if( !(PortStatus & USBD_PORT_CONNECTED) ||
		!(PortStatus & USBD_PORT_ENABLED))
		return STATUS_NO_SUCH_DEVICE;
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbGetUsbInfo:	Get some USB information (W2000 only)
NTSTATUS UsbGetUsbInfo( IN PWHCEB01_DEVICE_EXTENSION dx)
{
	int len = 0;
	PUSB_HUB_NAME HubName ;
#if _WIN32_WINNT>=0x0500
	USB_BUS_NOTIFICATION BusInfo;
	//DebugPrintMsg("Getting bus info");
	NTSTATUS status ;
	status = CallUSBDI( dx, &BusInfo, IOCTL_INTERNAL_USB_GET_BUS_INFO , 0 );
#ifdef DEBUG_INTERFACE	
	TRACE3("Bus info: TotalBandwidth %d, ConsumedBandwidth %d and ControllerNameLength %d",
		BusInfo.TotalBandwidth, BusInfo.ConsumedBandwidth, BusInfo.ControllerNameLength);
#endif//DEBUG_INTERFACE
	len = BusInfo.ControllerNameLength+50;
	HubName = (PUSB_HUB_NAME)ExAllocatePool( NonPagedPool, len);
	RtlZeroMemory( HubName, len);
	if( HubName==NULL)
		return STATUS_INSUFFICIENT_RESOURCES;

	status = CallUSBDI( dx, HubName, IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME, BusInfo.ControllerNameLength);
#ifdef DEBUG_INTERFACE
	if( NT_SUCCESS(status))
		TRACE2(" %d Controller name is %*S", HubName->ActualLength, HubName->HubName);
	else
		TRACE0("Cannot get controller name");
#endif//DEBUG_INTERFACE
	ExFreePool(HubName);
	return status;
#else
	return STATUS_NOT_SUPPORTED;
#endif
}

/////////////////////////////////////////////////////////////////////////////
//	UsbGetDeviceDescriptor:	Get device descriptor (allocate memory for it)
//							Remember to ExFreePool this memory
NTSTATUS UsbGetDeviceDescriptor( IN PWHCEB01_DEVICE_EXTENSION dx,
								 OUT PUSB_DEVICE_DESCRIPTOR deviceDescriptor,
								 OUT ULONG* Size)
{
	NTSTATUS status ;
	// Allocate memory for URB
	USHORT UrbSize = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
	ULONG sizeDescriptor = sizeof(USB_DEVICE_DESCRIPTOR);
	PURB urb;

#ifdef DEBUG_INTERFACE
	TRACE0("进入UsbGetDeviceDescriptor(),开始读取设备描述符");
#endif//DEBUG_INTERFACE

	urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize);
	if( urb==NULL)
	{
//		DebugPrintMsg("No URB memory");
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Allocate memory for device descriptor
	
	deviceDescriptor = (PUSB_DEVICE_DESCRIPTOR)ExAllocatePool(NonPagedPool, sizeDescriptor);
	if( deviceDescriptor==NULL)
	{
		ExFreePool(urb);

		TRACE0("No descriptor memory");

		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Build the Get Descriptor URB
	UsbBuildGetDescriptorRequest(
		urb, UrbSize, 
		USB_DEVICE_DESCRIPTOR_TYPE, 0, 0,	// Types, Index & LanguageId
		deviceDescriptor, NULL, sizeDescriptor,    // Transfer buffer
		NULL);	// Link URB

	// Call the USB driver
	//DebugPrintMsg("Getting device descriptor");
	status = CallUSBDI( dx, urb,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	// Check statuses
	if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))
	{
		TRACE2("status %x URB status %x", status, urb->UrbHeader.Status);
		status = STATUS_UNSUCCESSFUL;
	}
	// Remember count of bytes actually transferred
	*Size = urb->UrbControlDescriptorRequest.TransferBufferLength;

	TRACE0("设备描述符信息");
	TRACE1("***** bLength = %x", deviceDescriptor->bLength);
	TRACE1("***** bDescriptorType = %x", deviceDescriptor->bDescriptorType);
	TRACE1("***** bcdUSB = %x", deviceDescriptor->bcdUSB);
	TRACE1("***** bDeviceClass = %x", deviceDescriptor->bDeviceClass);
	TRACE1("***** bDeviceSubClass = %x", deviceDescriptor->bDeviceSubClass);
	TRACE1("***** bDeviceProtocol = %x", deviceDescriptor->bDeviceProtocol);
	TRACE1("***** bMaxPacketSize0 = %x", deviceDescriptor->bMaxPacketSize0);
	TRACE1("***** idVendor = %x", deviceDescriptor->idVendor);
	TRACE1("***** idProduct = %x", deviceDescriptor->idProduct);
	TRACE1("***** bcdDevice = %x", deviceDescriptor->bcdDevice);
	TRACE1("***** iManufacturer = %x", deviceDescriptor->iManufacturer);
	TRACE1("***** iProduct = %x", deviceDescriptor->iProduct);
	TRACE1("***** iSerialNumber = %x", deviceDescriptor->iSerialNumber);
	TRACE1("***** bNumConfigurations = %x", deviceDescriptor->bNumConfigurations);

	ExFreePool(urb);

	TRACE0("退出UsbGetDeviceDescriptor(),读取设备描述符结束");

	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbGetConfigurationDescriptors:	Get specified Config and associated descriptors
//									Allocate memory for descriptors.
//									Remember to ExFreePool this memory

NTSTATUS UsbGetConfigurationDescriptors( IN PWHCEB01_DEVICE_EXTENSION dx, 
										 OUT PUSB_CONFIGURATION_DESCRIPTOR *descriptors,
										 IN UCHAR ConfigIndex,
										 OUT ULONG* DescriptorsSize)
{
	NTSTATUS status;

	// Allocate memory for URB
	USHORT UrbSize = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
	PURB urb;
	
	TRACE0(" Enter UsbGetConfigurationDescriptors()");

	urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize);
	if( urb==NULL)
	{
		TRACE0("No URB memory");
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Allocate memory just for basic config descriptor
	*DescriptorsSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
	*descriptors = (PUSB_CONFIGURATION_DESCRIPTOR)ExAllocatePool(NonPagedPool, *DescriptorsSize+16);
	if( *descriptors==NULL)
	{
		TRACE0("No initial descriptor memory");
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Build the Get Descriptor URB
	UsbBuildGetDescriptorRequest(
		urb, UrbSize,
		USB_CONFIGURATION_DESCRIPTOR_TYPE, ConfigIndex, 0,
		*descriptors, NULL, *DescriptorsSize,
		NULL);

	// Call the USB driver
	TRACE0("Getting basic configuration descriptor");
	status = CallUSBDI( dx, urb,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	// Check statuses
	if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))
	{
		TRACE2("status %x URB status %x", status, urb->UrbHeader.Status);
		status = STATUS_UNSUCCESSFUL;
		goto fail;
	}


	TRACE0("Configuration Descriptor:");
	TRACE1("***** bLength = %x", (*descriptors)->bLength);
	TRACE1("***** bDescriptorType = %x", (*descriptors)->bDescriptorType);
	TRACE1("***** wTotalLength = %x", (*descriptors)->wTotalLength);
	TRACE1("***** bNumInterfaces = %x", (*descriptors)->bNumInterfaces);
	TRACE1("***** bConfigurationValue = %x", (*descriptors)->bConfigurationValue);
	TRACE1("***** iConfiguration = %x", (*descriptors)->iConfiguration);
	TRACE1("***** bmAttributes = %x", (*descriptors)->bmAttributes);
	TRACE1("***** MaxPower = %x", (*descriptors)->MaxPower);


	// Reallocate memory for config descriptor and associated descriptors
	*DescriptorsSize = (*descriptors)->wTotalLength;
	ExFreePool( *descriptors );
	*descriptors = NULL;
	*descriptors = (PUSB_CONFIGURATION_DESCRIPTOR)ExAllocatePool(NonPagedPool, *DescriptorsSize+16);
	if( *descriptors==NULL)
	{
		TRACE0("No full descriptors memory");
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	// Build the Get Descriptor URB
	UsbBuildGetDescriptorRequest(
		urb, UrbSize, 
		USB_CONFIGURATION_DESCRIPTOR_TYPE, ConfigIndex, 0,
		*descriptors, NULL, *DescriptorsSize,
		NULL);

	// Call the USB driver
	TRACE0("Getting full configuration descriptors");
	status = CallUSBDI( dx, urb ,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	// Check statuses
	if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))
	{
		TRACE2("status %x URB status %x", status, urb->UrbHeader.Status);
		status = STATUS_UNSUCCESSFUL;
		goto fail;
	}
	// Remember count of bytes actually transferred
	*DescriptorsSize = urb->UrbControlDescriptorRequest.TransferBufferLength;

	TRACE0("Configuration Descriptor2:");
	TRACE1("***** bLength = %x", (*descriptors)->bLength);
	TRACE1("***** bDescriptorType = %x", (*descriptors)->bDescriptorType);
	TRACE1("***** wTotalLength = %x", (*descriptors)->wTotalLength);
	TRACE1("***** bNumInterfaces = %x", (*descriptors)->bNumInterfaces);
	TRACE1("***** bConfigurationValue = %x", (*descriptors)->bConfigurationValue);
	TRACE1("***** iConfiguration = %x", (*descriptors)->iConfiguration);
	TRACE1("***** bmAttributes = %x", (*descriptors)->bmAttributes);
	TRACE1("***** MaxPower = %x", (*descriptors)->MaxPower);


	TRACE0("Exit UsbGetConfigurationDescriptors()");

fail:
	ExFreePool(urb);
	TRACE1( "descriptors = 0x%x" , *descriptors );
	return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbGetSpecifiedDescriptor:	Get specified descriptor of given size
//								Allocate memory for descriptor.
//								Remember to ExFreePool this memory

NTSTATUS UsbGetSpecifiedDescriptor( IN PWHCEB01_DEVICE_EXTENSION dx,
									OUT PVOID Descriptor,
									IN UCHAR DescriptorType,
									IN OUT ULONG* Size)
{
	// Allocate memory for URB
	USHORT UrbSize = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
	PURB urb ;
	NTSTATUS status ;

	urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize);
	if( urb==NULL)
	{
#ifdef DEBUG_INTERFACE
		TRACE0("No URB memory");
#endif//DEBUG_INTERFACE
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Allocate memory for descriptor
	Descriptor = ExAllocatePool(NonPagedPool, *Size);
	if( Descriptor==NULL)
	{
		ExFreePool(urb);
#ifdef DEBUG_INTERFACE
		TRACE0("No descriptor memory");
#endif//DEBUG_INTERFACE
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Build the Get Descriptor URB
	UsbBuildGetDescriptorRequest(
		urb, UrbSize,
		DescriptorType,	0, 0,	// Types, Index & LanguageId
		Descriptor, NULL, *Size,	// Transfer buffer
		NULL);	// Link URB

	// Call the USB driver
#ifdef DEBUG_INTERFACE
	TRACE1("Getting descriptor type %2x", DescriptorType);
#endif//DEBUG_INTERFACE
	status = CallUSBDI( dx, urb,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	// Check statuses
	if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))
	{
#ifdef DEBUG_INTERFACE
		TRACE2("status %x URB status %x", status, urb->UrbHeader.Status);
#endif//DEBUG_INTERFACE
		status = STATUS_UNSUCCESSFUL;
	}

	*Size = urb->UrbControlDescriptorRequest.TransferBufferLength;

	ExFreePool(urb);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbSelectConfiguration:	Select first config if it has interface

NTSTATUS UsbSelectConfiguration( IN PWHCEB01_DEVICE_EXTENSION dx)
{
	PUSB_CONFIGURATION_DESCRIPTOR Descriptors = NULL;
	ULONG size = 0;
	NTSTATUS status ;
	PUSB_INTERFACE_DESCRIPTOR id ;
	USBD_INTERFACE_LIST_ENTRY ilist[2];
	PURB urb ;
	PUSBD_INTERFACE_INFORMATION InterfaceInfo ;
	ULONG i=0;
	
	status = UsbGetConfigurationDescriptors( dx, &Descriptors, 0, &size);

	// Get all first configuration descriptors

	if( !NT_SUCCESS(status))
	{
		TRACE1("UsbGetConfigurationDescriptors failed %x", status);
		FreeIfAllocated( Descriptors );
		return status;
	}

	TRACE1( "before Parse! Descriptors = 0x%x" , Descriptors );
	// Search for an interface with HID keyboard device class
	id = USBD_ParseConfigurationDescriptorEx(
		Descriptors, Descriptors,
		-1, -1,	-1,-1,-1);
	if( id==NULL)
	{
		TRACE0("No matching interface found");

		FreeIfAllocated( Descriptors );
		return STATUS_NO_SUCH_DEVICE;
	}
	TRACE0( "after Parse!" );
    //////此处默认设备只支持一个接口,但是ADSP21535支持1个配置,此配置可以支持2个接口,
    //////每个设备支持2个alterate setting。这一点在调试时要注意。

		TRACE0("Interface Descriptor:");
		TRACE1("***** bLength = %x *****", id->bLength);
		TRACE1("***** bDescriptorType = %x *****", id->bDescriptorType);

⌨️ 快捷键说明

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