📄 whusb20usb.c
字号:
//////////////////////////////////////////////////////////////////////////////
//文件名称: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 + -