阅读:1273回复:0
完成函数的诡异问题
在进行USB Bulkout操作时,设置了完成函数。但传入完成函数的参数却与设置完成函数时指定的不一样,很诡异。。。
发送的代码如下: VOID IfSendFrame( IN PADAPTER_CONTEXT adapter, IN PTX_PACKET packet ) { NTSTATUS status; PIF_IO_CONTEXT ioContext; PIO_STACK_LOCATION lowerIrpStack; ULONG paddingLength; ULONG pnLength; PIF_TX_FRAME_HEADER txFrameHeader; PPACKET_BUFFER buffer; PLOCK_LIST bulkOutList, contextList, packetList, bufferList; BOOLEAN sent; //buffer = packet->buffer; DBGTRACE( "====>IfSendFrame, adapter = %p\n", adapter ); bulkOutList = &adapter->pendingBulkOutList; contextList = &adapter->ifIoContextList; packetList = &adapter->txPacketList; bufferList = &adapter->txBufferList; sent = FALSE; buffer = packet->buffer; ioContext = NULL; do { // Check miniport state if( GetFlag(adapter->miniportState, fACMPS_HALTING | fACMPS_REMOVED) ) { DBGERROR( " Adapter is halting or removed, cancel sending\n" ); break; } // --------------------------------------------------------------------- // Initialize the packet for bulk out request // --------------------------------------------------------------------- ASSERT( packet ); txFrameHeader = (PIF_TX_FRAME_HEADER)packet->data; txFrameHeader->length = (USHORT)packet->dataLength; // // Add padding length // paddingLength = 0; if( txFrameHeader->length % adapter->usbBulkOutPipeInformation.MaximumPacketSize < 16 ) { paddingLength = 16; } packet->dataLength = txFrameHeader->length + paddingLength; ASSERT( packet->dataLength <= CFG_HW_MAX_BULK_TRANSFER_SIZE ); ioContext = (PIF_IO_CONTEXT)NdisInterlockedRemoveHeadList( &contextList->head, &contextList->lock ); if( NULL == ioContext ) { DBGERROR( " Not enough context descriptor, cancel sending\n" ); break; } // // Initialize I/O context // ioContext->buffer = buffer; // Initialize IRP and related stack // IoInitializeIrp( // ioContext->irp, // IoSizeOfIrp(adapter->usbLowerDevice->StackSize + 1), // adapter->usbLowerDevice->StackSize + 1 ); IoReuseIrp( ioContext->irp, 0 ); IoSetCompletionRoutine( ioContext->irp, IfSendComplete, packet, TRUE, TRUE, TRUE ); lowerIrpStack = IoGetNextIrpStackLocation( ioContext->irp ); ASSERT( lowerIrpStack != NULL ); packet->ioContext = ioContext; lowerIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; lowerIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; lowerIrpStack->Parameters.Others.Argument1 = ioContext->urb; // Initialize urb UsbBuildInterruptOrBulkTransferRequest( ioContext->urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), adapter->usbBulkOutPipeInformation.PipeHandle, packet->data, NULL, packet->dataLength, USBD_TRANSFER_DIRECTION_OUT, NULL ); if( AcquireAdapter(adapter) ) { NdisAcquireSpinLock( &bulkOutList->lock ); InsertTailList( &bulkOutList->head, &ioContext->link ); bulkOutList->count++; NdisReleaseSpinLock( &bulkOutList->lock ); //NdisAcquireSpinLock( &adapter->txLock ); status = IoCallDriver( adapter->usbLowerDevice, ioContext->irp ); sent = TRUE; if( !NT_SUCCESS(status) ) { DBGERROR( " Failed to submit irp to USBD[%X]!\n", status ); // TODO: // Reset pipe // Reset device if necessary break; } } } while( FALSE ); // // If the request is not sent, free related resources // if( !sent ) { NdisInterlockedInsertTailList( &bufferList->head, &buffer->link, &bufferList->lock ); NdisInterlockedInsertTailList( &packetList->head, &packet->link, &packetList->lock ); if( NULL != ioContext ) { NdisInterlockedInsertTailList( &contextList->head, &ioContext->link, &contextList->lock ); } } DBGTRACE( "<====IfSendFrame, pending send request = %d\n", bulkOutList->count ); } 完成函数如下: NTSTATUS IfSendComplete( IN PDEVICE_OBJECT device, IN PIRP irp, IN PVOID context) { NTSTATUS irpStatus, urbStatus; PADAPTER_CONTEXT adapter; PTX_PACKET packet; PPACKET_BUFFER buffer; PIF_IO_CONTEXT ioContext, completedContext; PLOCK_LIST bulkOutList, packetList, contextList, bufferList; DBGTRACE( "====>IfSendComplete\n" ); packet = (PTX_PACKET)context; ioContext = packet->ioContext; buffer = ioContext->buffer; adapter = ioContext->adapter; packetList = &adapter->txPacketList; bulkOutList = &adapter->pendingBulkOutList; contextList = &adapter->ifIoContextList; bufferList = &adapter->txBufferList; ASSERT( ioContext->irp == irp ); packet->ndisStatus = NDIS_STATUS_SUCCESS; NdisDprAcquireSpinLock( &bulkOutList->lock ); completedContext = (PIF_IO_CONTEXT)RemoveListEntry( &bulkOutList->head, &ioContext->link ); if( completedContext ) { bulkOutList->count--; } else { packet->ndisStatus = NDIS_STATUS_FAILURE; DBGTRACE( " Bulk out cancelled\n" ); } //USBD_STATUS_SUCCESS irpStatus = irp->IoStatus.Status; urbStatus = ioContext->urb->UrbHeader.Status; DBGTRACE( " Send status: [%X, %X]\n", irpStatus, urbStatus ); if( !USBD_SUCCESS(urbStatus) || !NT_SUCCESS(irpStatus) ) { //if( AcquireAdapter(adapter) && !GetFlag(adapter->miniportState, fACMPS_HALTING) ) { //NdisScheduleWorkItem( &adapter->ifPipeResetItem ); } //UsbDpcResetPipe( adapter, adapter->usbBulkOutPipeInformation.PipeHandle ); } NdisDprReleaseSpinLock( &bulkOutList->lock ); NdisInterlockedInsertTailList( &bufferList->head, &buffer->link, &bufferList->lock ); NdisInterlockedInsertTailList( &contextList->head, &ioContext->link, &contextList->lock ); NdisInterlockedInsertTailList( &packetList->head, &packet->link, &packetList->lock ); adapter->txOk++; ReleaseAdapter( adapter ); DBGTRACE( "<====IfSendComplete\n" ); return STATUS_MORE_PROCESSING_REQUIRED; } 在完成函数中,竟然发现断言语句ASSERT( ioContext->irp == irp )失败。也就是传入完成函数的context参数与设置该IRP的完成函数时制定的context参数不一样,莫名其妙。。。 请教... |
|