阅读:1634回复:1
请教设备复位的问题
在驱动中初始化设备时对端口进行复位操作,总是失败。可以肯定地是设备没有问题,因为相同的设备用以前的测试驱动都可以复位端口。有关代码如下:
1. 在初始化设备时初始化硬件接口: NDIS_STATUS MiniportInitialize( OUT PNDIS_STATUS openStatus, OUT PUINT selectedMediumIndex, IN PNDIS_MEDIUM mediumArray, IN UINT mediumArraySize, IN NDIS_HANDLE miniportHandle, IN NDIS_HANDLE wrapperConfigurationContext) { NDIS_STATUS status; PADAPTER_CONTEXT adapter; UINT index; UINT txd; #if DBG LARGE_INTEGER ts, td, te; #endif DBGTRACE( "====>MiniportInitialize, miniportHandle = %p\n", miniportHandle ); #if DBG NdisGetCurrentSystemTime(&ts); #endif adapter = NULL; do { // --------------------------------------------------------------------- // Select the medium supported by this Miniport // --------------------------------------------------------------------- for( index = 0; index < mediumArraySize; index++ ) { if( CFG_MP_MEDIUM_TYPE == mediumArray[index] ) { *selectedMediumIndex = index; break; } } if( index >= mediumArraySize ) { status = NDIS_STATUS_UNSUPPORTED_MEDIA; DBGERROR( " No supported media found!\n" ); break; } DBGINFO( " Selected medium type: %X, index: %d\n", mediumArray[index], index ); // --------------------------------------------------------------------- // Allocate adapter context area // --------------------------------------------------------------------- status = AllocateAdapterContext( miniportHandle, &adapter); if( NDIS_STATUS_SUCCESS != status ) { status = NDIS_STATUS_RESOURCES; DBGERROR( " Failed to allocate adapter context!\n" ); break; } // --------------------------------------------------------------------- // Read configurations from registry // --------------------------------------------------------------------- //LoadRegistryConfiguration( wrapperConfigurationContext, adapter ); // --------------------------------------------------------------------- // Initialize NIC // --------------------------------------------------------------------- adapter->referenceCount++; SetFlag( adapter->miniportState, fACMPS_INITIALIZING ); NdisMSetAttributesEx( miniportHandle, adapter, 0,//CFG_MP_CHECK_FOR_HANG_INTERVAL, NDIS_ATTRIBUTE_DESERIALIZE | NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK, NdisInterfaceInternal); DBGINFO( " NIC features:\n" " Check for hang interval: %d\n" " Abbribute flags: %X\n" " Bus type: %d\n", CFG_MP_CHECK_FOR_HANG_INTERVAL, NDIS_ATTRIBUTE_DESERIALIZE | NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK, NdisInterfaceInternal ); // // After NdisMSetAttributesEx returned, anything would happen... // That means other MiniportXxx routines may be called, since it has // the attribute NDIS_ATTRIBUTE_DESERIALIZE. Supprising removal is an // example. // // --------------------------------------------------------------------- // Initialize interface module (hardware) // --------------------------------------------------------------------- status = IfInit( adapter ); if( NDIS_STATUS_SUCCESS != status ) { DBGERROR( " Failed to initialize hardware interface!\n" ); break; } …… } while( FALSE ); …… } 2. 初始化硬件接口的函数中初始化设备端口: NDIS_STATUS IfInit( IN OUT PADAPTER_CONTEXT adapter) { NDIS_STATUS finalStatus; NTSTATUS status; FIRMWARE_VERSION_INFO firmwareVersionInfo; ULONG deviceID; ULONG deviceDescriptorLength; USB_DEVICE_DESCRIPTOR deviceDescriptor; DBGTRACE("====>IfInit, adapter = %X\n", adapter); finalStatus = NDIS_STATUS_ADAPTER_NOT_FOUND; deviceDescriptorLength = sizeof(deviceDescriptor); do { // --------------------------------------------------------------------- // Get and save lower device object // --------------------------------------------------------------------- NdisMGetDeviceProperty( adapter->miniportHandle, &adapter->thisPDO, &adapter->thisFDO, &adapter->usbLowerDevice, NULL, NULL); if( NULL == adapter->usbLowerDevice ) { DBGERROR(" Cannot get lower USB device!\n"); break; } DBGINFO( " PhysicalDeviceObject = %p, FunctionalDeviceObject = %p, NextDeviceObject = %p\n", adapter->thisPDO, adapter->thisFDO, adapter->usbLowerDevice ); // --------------------------------------------------------------------- // Reset the usb port // --------------------------------------------------------------------- status = UsbResetPort(adapter); if( !NT_SUCCESS(status) ) { DBGERROR(" Failed to reset usb port[STATUS = %X]!\n", status); break; } …… } while( FALSE ); …… } 3. 端口复位操作的代码: NTSTATUS UsbResetPort( IN PADAPTER_CONTEXT adapter) { NTSTATUS status; status = UsbSyncCallUSBD( adapter, IOCTL_INTERNAL_USB_RESET_PORT, NULL, NULL); return status; } NTSTATUS UsbSyncCallUSBD( IN PADAPTER_CONTEXT adapter, IN ULONG controlCode, IN PVOID arg1, IN PVOID arg2) { NTSTATUS status; IO_STATUS_BLOCK statusBlock; KEVENT irpDone; PIRP irp; PIO_STACK_LOCATION lowerIrpStack; LARGE_INTEGER waitTime; status = STATUS_UNSUCCESSFUL; do { // --------------------------------------------------------------------- // Initialize IRP completion notification event // --------------------------------------------------------------------- KeInitializeEvent( &irpDone, NotificationEvent, FALSE ); // --------------------------------------------------------------------- // Build internal IOCTL IRP // --------------------------------------------------------------------- irp = IoBuildDeviceIoControlRequest( controlCode, adapter->usbLowerDevice, NULL, 0, NULL, 0, TRUE, &irpDone, &statusBlock); if( NULL == irp ) { DBGERROR( " Failed to allocate irp for USB syncronous operation!\n" ); status = STATUS_INSUFFICIENT_RESOURCES; break; } lowerIrpStack = IoGetNextIrpStackLocation( irp ); ASSERT( lowerIrpStack != NULL ); if( arg1 ) lowerIrpStack->Parameters.Others.Argument1 = arg1; if( arg2 ) lowerIrpStack->Parameters.Others.Argument2 = arg2; if( AcquireAdapter(adapter) ) { // ----------------------------------------------------------------- // Submit the IRP and wait if necessary // ----------------------------------------------------------------- status = IoCallDriver( adapter->usbLowerDevice, irp ); if( STATUS_PENDING == status ) { waitTime.QuadPart = -CFG_HW_USB_TIMEOUT; status = KeWaitForSingleObject( &irpDone, Executive, KernelMode, FALSE, NULL );//&waitTime ); if( STATUS_SUCCESS == status ) { status = statusBlock.Status; } else { DBGERROR( " Usb operation error, status = %X!\n", status ); IoCancelIrp( irp ); status = STATUS_CANCELLED; // I/O manager will free the irp itself after we cancel it } } ReleaseAdapter( adapter ); } } while( FALSE ); return status; } 进行端口复位操作时,向USBD提交IRP后,等待irpDone事件,等待成功,但IO_STATUS_BLOCK中的状态有错,为C000009C(STATUS_DEVICE_DATA_ERROR)。 复位操作的代码实在看不出有什么问题,恳请高手不吝赐教 |
|
沙发#
发布于:2007-08-30 22:09
奇怪的是,跳过端口复位,直接读描述符也可以
请问USBD在收到控制码为 IOCTL_INTERNAL_USB_RESET_PORT的IRP后具体都做了些什么?在设备端(固件)会有什么样的反应? |
|