usb驱动问题,大家看看为什么在KeWaitForSingleObject处死等不回!!!!

DontKissBossAss 2012-01-30 04:33:51
我在一个IRP的取消例程中,给USB设备发送通知。 出现了上述问题。

VOID IrpCancelRoutine(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;

IoAcquireRemoveLock(&pdx->RemoveLock, Irp);

// Release the global cancel spin lock.
// Do this while not holding any other spin locks so that we exit at the right IRQL.
IoReleaseCancelSpinLock(Irp->CancelIrql);

if( Irp == pdx->pBufIrp)
{
KeInitializeEvent(&event, NotificationEvent, FALSE);

//pdx->LowerDeviceObject, 已经初始化完成
irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
pdx->LowerDeviceObject,
NULL,
0,
NULL,
0,
TRUE,
&event,
&ioStatus);

ntStatus = IoCallDriver(pdx->LowerDeviceObject, irp);
if(ntStatus == STATUS_PENDING)
{
//在此处死等,在其他线程上先文中不存在这个问题,取消历程中,存在此问题。为啥
status = KeWaitForSingleObject(pdx->phExitEvent,Executive,ernelMode,FALSE,NULL);
}
//...其他处理
}

//取消IRP
}
...全文
416 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
cqupt_chen 2012-09-26
  • 打赏
  • 举报
回复
应该是死锁的问题
windbg调一下吧 这种同步的问题 比较好搞 看看内核对象的格式就好办了
wait_list_entry入手 线程里也有等待列表的
wjcapple 2012-02-04
  • 打赏
  • 举报
回复
我来顶楼主一下,顺便做个记号
jzxsasch 2012-02-04
  • 打赏
  • 举报
回复
不明白 肯定是个很小的地方错了
曹大夯 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dontkissbossass 的回复:]
2:当上层应用程序异常结束时,为了消除挂起的资源而引起蓝屏,我要为步骤1中的irp设置取消例程,,由于异常结束时,驱动再清理线程时,会主动调用我这个取消例程。
[/Quote]

为什么上层应用程序异常结束时会蓝屏?蓝屏信息是什么?

这类问题建议通过修改应用程序来解决。也就是说,在应用程序里面加足够的保护并加入异常处理。确保应用程序以外退出的时候,会去Cancel自己的取数IRP。
而不是在驱动的Cancel例程里面做处理。驱动的Cancel例程只能做Cancel本身对应IRP相关的动作。
jzxsasch 2012-02-02
  • 打赏
  • 举报
回复
那就要看下层驱动什么时候完成 你自己创建的这个请求了 调试下城驱动吧
DontKissBossAss 2012-02-02
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jzxsasch 的回复:]

为什么不是
status = KeWaitForSingleObject(&event,Executive,ernelMode,FALSE,NULL);
而是
status = KeWaitForSingleObject(event,Executive,ernelMode,FALSE,NULL);
[/Quote]

是我在帖子里面写错了,不存在event不一致问题。 抱歉。
Luisfan 2012-02-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 huntercao 的回复:]

是什么IRP的Cancel例证?

另外,在Cancel例程里面发送IRP/URB不太合适。
[/Quote]

我估计是他那里的参数有误!
DontKissBossAss 2012-02-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jzxsasch 的回复:]

那就要看下层驱动什么时候完成 你自己创建的这个请求了 调试下城驱动吧
[/Quote]

很奇怪,同样一个函数,在其他地方,基本上立马返回,但是当程序调用cancel例程,cancel例程下边的标准调用时, 就死等

我cancel例程是当上层应用程序强制结束进程时,执行的。难道是这有关系?

NTSTATUS
BulkUsb_CallUSBD(
IN PDEVICE_OBJECT DeviceObject,
IN PURB Urb
)
/*++

Routine Description:

Passes a URB to the USBD class driver
The client device driver passes USB request block (URB) structures
to the class driver as a parameter in an IRP with Irp->MajorFunction
set to IRP_MJ_INTERNAL_DEVICE_CONTROL and the next IRP stack location
Parameters.DeviceIoControl.IoControlCode field set to
IOCTL_INTERNAL_USB_SUBMIT_URB.

Arguments:

DeviceObject - pointer to the physical device object (PDO)

Urb - pointer to an already-formatted Urb request block

Return Value:

STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise

--*/
{
NTSTATUS ntStatus, status = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension;
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION nextStack;

BULKUSB_KdPrint( DBGLVL_MAXIMUM,("enter BulkUsb_CallUSBD\n"));

deviceExtension = DeviceObject->DeviceExtension;

//
// issue a synchronous request
//

KeInitializeEvent(&event, NotificationEvent, FALSE);

irp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_USB_SUBMIT_URB,
deviceExtension->TopOfStackDeviceObject, //Points to the next-lower driver's device object
NULL, // optional input bufer; none needed here
0, // input buffer len if used
NULL, // optional output bufer; none needed here
0, // output buffer len if used
TRUE, // If InternalDeviceControl is TRUE the target driver's Dispatch
// outine for IRP_MJ_INTERNAL_DEVICE_CONTROL or IRP_MJ_SCSI
// is called; otherwise, the Dispatch routine for
// IRP_MJ_DEVICE_CONTROL is called.
&event, // event to be signalled on completion
&ioStatus); // Specifies an I/O status block to be set when the request is completed the lower driver.

//
// As an alternative, we could call KeDelayExecutionThread, wait for some
// period of time, and try again....but we keep it simple for right now
//
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}

//
// Call the class driver to perform the operation. If the returned status
// is PENDING, wait for the request to complete.
//

nextStack = IoGetNextIrpStackLocation(irp);
BULKUSB_ASSERT(nextStack != NULL);

//
// pass the URB to the USB driver stack
//
nextStack->Parameters.Others.Argument1 = Urb;

ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);

BULKUSB_KdPrint( DBGLVL_MAXIMUM,("BulkUsb_CallUSBD() return from IoCallDriver USBD %x\n", ntStatus));

if (ntStatus == STATUS_PENDING) {

status = KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);

} else {
ioStatus.Status = ntStatus;
}

BULKUSB_KdPrint( DBGLVL_MAXIMUM,("BulkUsb_CallUSBD() URB status = %x status = %x irp status %x\n",
Urb->UrbHeader.Status, status, ioStatus.Status));

//
// USBD maps the error code for us
//
ntStatus = ioStatus.Status;

BULKUSB_KdPrintCond( DBGLVL_MAXIMUM, !NT_SUCCESS( ntStatus ), ("exit BulkUsb_CallUSBD FAILED (%x)\n", ntStatus));

return ntStatus;
}
jzxsasch 2012-02-01
  • 打赏
  • 举报
回复
为什么不是
status = KeWaitForSingleObject(&event,Executive,ernelMode,FALSE,NULL);
而是
status = KeWaitForSingleObject(pdx->phExitEvent,Executive,ernelMode,FALSE,NULL);
jzxsasch 2012-02-01
  • 打赏
  • 举报
回复
设备扩展的事件是不是以下函数的事件对象啊??
IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
pdx->LowerDeviceObject,
NULL,
0,
NULL,
0,
TRUE,
&event,
&ioStatus);
DontKissBossAss 2012-01-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 huntercao 的回复:]

是什么IRP的Cancel例证?

另外,在Cancel例程里面发送IRP/URB不太合适。
[/Quote]

终于等到一个牛人, 是这个样子的,

1:我这么应用的前提是: 应用层传递了buffer,给驱动层使用,传递buffer的这个irp上层不会主动cancel,
只有在上层主动发起停止的请求时,驱动去完成这个irp,再停止设备。

2:当上层应用程序异常结束时,为了消除挂起的资源而引起蓝屏,我要为步骤1中的irp设置取消例程,,由于异常结束时,驱动再清理线程时,会主动调用我这个取消例程。

3: 在取消例程中,我要停止底层驱动对步骤1buffer的占用,因此要发送URB/Irp时设备停止工作,现在问题是, IoBuildDeviceIoControlRequest注册的event在iocalldriver后,不能正常受信, 我就一直等待。造成了异常退出时,进程驻留的问题。

针对3:我的解决办法是,为urb产生的irp设置完成例程,此完成例程中设置事件,此时能正确工作。但是某个时刻,底层的驱动程序又要主动完成步骤3的irp。又来了新问题。

唉,都是资源惹得祸。牛人给个办法吧。
曹大夯 2012-01-31
  • 打赏
  • 举报
回复
是什么IRP的Cancel例证?

另外,在Cancel例程里面发送IRP/URB不太合适。

21,616

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧