百分求救:wdm USB驱动,两个device总是会互相影响
[复制链接]
我的电脑上连了两个USB serial class的device,现在一个拔线之后,另一个的write urb传输也会fail掉,请问各位高手是什么原因?
我看到在OnWriteInterrupt里面两个device object都返回fail,但是我只拔出了一个USB device啊。
NTSTATUS
StartWriteUrb(
PDEVICE_EXTENSION Extension
)
{
// If the interrupt polling IRP is currently running, don't try to start
// it again.
USBD_PIPE_HANDLE PipeHandle;
BOOLEAN startirp;
KIRQL oldirql;
PIRP Irp;
PURB urb;
PIO_STACK_LOCATION stack;
TRACE("Enter StartWriteUrb() size=%d pipehandle=%X\n",Extension->WriteSize,Extension->UsbInterface->Pipes[Extension->DataOutPipe].PipeHandle);
// KeAcquireSpinLock(&Extension->polllock, &oldirql);
if (Extension->writepending)
startirp = FALSE;
else
startirp = TRUE, Extension->writepending = TRUE;
// KeReleaseSpinLock(&Extension->polllock, oldirql);
if (!startirp)
return STATUS_DEVICE_BUSY; // already pending
Irp = Extension->WritingIrp;
urb = Extension->WritingUrb;
PipeHandle = Extension->UsbInterface->Pipes[Extension->DataOutPipe].PipeHandle;
ASSERT(Irp && urb);
// Acquire the remove lock so we can't remove the device while the IRP
// is still active.
// Initialize the URB we use for reading the interrupt pipe
UsbBuildInterruptOrBulkTransferRequest(
urb,
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
PipeHandle,
Extension->WriteCurrentChar,
NULL,
Extension->WriteSize,
USBD_TRANSFER_DIRECTION_OUT,
NULL);
// Install "OnInterrupt" as the completion routine for the polling IRP.
IoSetCompletionRoutine(
Irp,
(PIO_COMPLETION_ROUTINE) OnWriteInterrupt,
Extension,
TRUE,
TRUE,
TRUE);
// Initialize the IRP for an internal control request
stack = IoGetNextIrpStackLocation(Irp);
stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
stack->Parameters.Others.Argument1 = urb;
// This IRP might have been cancelled the last time it was used, in which case
// the cancel flag will still be on. Clear it to prevent USBD from thinking that it's
// been cancelled again! A better way to do this would be to call IoReuseIrp,
// but that function is not declared in WDM.H.
Irp->Cancel = FALSE;
TRACE("Exit StartWriteUrb()\n");
return IoCallDriver(Extension->TopOfStackDeviceObject, Irp);
}