Leonsoft
驱动小牛
驱动小牛
  • 注册日期2003-05-08
  • 最后登录2012-08-11
  • 粉丝1
  • 关注0
  • 积分21分
  • 威望281点
  • 贡献值1点
  • 好评度103点
  • 原创分0分
  • 专家分0分
阅读:3642回复:15

怎样在USB driver里面Reset Control Pipe??

楼主#
更多 发布于:2007-08-06 10:09
最近发现有一个问题,我们公司的USB 产品在某些VIA芯片组的主板机器上,BULK传输起来后,再发Veder Request后,就没有response了,一直都是Pending。但是这个时候用BusHound,发Control的Reset Pipe后,就可以Work了。
但我发现在USB driver里面,看不到端点0,拿不到Control Pipe的Handle,没法做reset Control Pipe操作,只有USB host driver可以做到的。
请问高手,在USB driver里面,有什么办法可以做到Reset Control Pipe。
谢谢。。。
I will do the best with what the God gave me.
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-08-06 11:02
这个管道复位的方法倒有,只是NTSTATUS
D12_ResetPipe(
    IN PDEVICE_OBJECT DeviceObject,
    IN PD12_PIPE Pipe,
    IN BOOLEAN IsoClearStall
    )
/*++

Routine Description:

    Reset a given USB pipe.
    
    NOTES:

    This will reset the host to Data0 and should also reset the device
    to Data0 for Bulk and Interrupt pipes.

    For Iso pipes this will set the virgin state of pipe so that ASAP
    transfers begin with the current bus frame instead of the next frame
    after the last transfer occurred.

Arguments:

Return Value:


--*/
{
    NTSTATUS ntStatus;
    PURB urb;

    D12_KdPrint (("D12TEST.SYS: Reset Pipe %x\n", Pipe));

    urb = ExAllocatePool(NonPagedPool,
                         sizeof(struct _URB_PIPE_REQUEST));

    if (urb) {

        urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
        urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
        urb->UrbPipeRequest.PipeHandle =
            Pipe->PipeInfo->PipeHandle;

        ntStatus = D12_CallUSBD(DeviceObject, urb);

        ExFreePool(urb);

    } else {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Memphis RESET_PIPE will send a Clear-Feature Endpoint Stall to
    // reset the data toggle of non-Iso pipes as part of a RESET_PIPE
    // request.  It does not do this for Iso pipes as Iso pipes do not use
    // the data toggle (all Iso packets are Data0).  However, we also use
    // the Clear-Feature Endpoint Stall request in our device firmware to
    // reset data buffer points inside the device so we explicitly send
    // this request to the device for Iso pipes if desired.
    //
    if (NT_SUCCESS(ntStatus) && IsoClearStall &&
        (Pipe->PipeInfo->PipeType == UsbdPipeTypeIsochronous)) {
        
        urb = ExAllocatePool(NonPagedPool,
                             sizeof(struct _URB_CONTROL_FEATURE_REQUEST));

        if (urb) {

            UsbBuildFeatureRequest(urb,
                                   URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,
                                   USB_FEATURE_ENDPOINT_STALL,
                                   Pipe->PipeInfo->EndpointAddress,
                                   NULL);

            ntStatus = D12_CallUSBD(DeviceObject, urb);

            ExFreePool(urb);
        } else {
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    return ntStatus;
}
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-08-06 11:18
我只想知道,在驱动,什么时候用这个复位.
Leonsoft
驱动小牛
驱动小牛
  • 注册日期2003-05-08
  • 最后登录2012-08-11
  • 粉丝1
  • 关注0
  • 积分21分
  • 威望281点
  • 贡献值1点
  • 好评度103点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-08-07 11:13
楼上的,这个Reset Pipe早试过了,这样做,只能Reset Bulk or ISO pipe,不能做到reset Control Pipe,因为Client端看不到端点0,也就是拿不到Control Pipe的Handle。
I will do the best with what the God gave me.
gutian98
禁止发言
禁止发言
  • 注册日期2003-01-12
  • 最后登录2016-12-11
  • 粉丝4
  • 关注2
  • 积分760分
  • 威望8026点
  • 贡献值1点
  • 好评度364点
  • 原创分0分
  • 专家分21分
  • 金点子奖
  • 社区居民
地下室#
发布于:2007-08-07 11:55
用户被禁言,该主题自动屏蔽!
lejianz
驱动中牛
驱动中牛
  • 注册日期2003-03-05
  • 最后登录2023-11-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望145点
  • 贡献值0点
  • 好评度116点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2007-08-07 12:00
不行的话,就复位设备
一起交流,共同提高!
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-08-07 14:01
NTSTATUS
Ezusb_ResetParentPort(
    IN IN PDEVICE_OBJECT fdo
    )
/*++

Routine Description:

    Reset the our parent port

Arguments:

Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise

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

    Ezusb_KdPrint (("EZUSB.SYS: enter Ezusb_ResetPort\n"));

    pdx = fdo->DeviceExtension;

    //
    // issue a synchronous request
    //

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = IoBuildDeviceIoControlRequest(
                IOCTL_INTERNAL_USB_RESET_PORT,
                pdx->StackDeviceObject,
//                pdx->TopOfStackDeviceObject,
                NULL,
                0,
                NULL,
                0,
                TRUE, /* INTERNAL */
                &event,
                &ioStatus);

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

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

    Ezusb_KdPrint (("EZUSB.SYS: calling USBD enable port api\n"));

    ntStatus = IoCallDriver(pdx->StackDeviceObject,
                            irp);
                            
    Ezusb_KdPrint (("EZUSB.SYS: return from IoCallDriver USBD %x\n", ntStatus));

    if (ntStatus == STATUS_PENDING) {

        Ezusb_KdPrint (("EZUSB.SYS: Wait for single object\n"));

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

        Ezusb_KdPrint (("EZUSB.SYS: Wait for single object, returned %x\n", status));
        
    } else {
        ioStatus.Status = ntStatus;
    }

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

    Ezusb_KdPrint (("EZUSB.SYS: Ezusb_ResetPort (%x)\n", ntStatus));

    return ntStatus;
}


复位端口这样做,当是我不知道什么情况下该复位端口,不能读不到正常数据就复位吧,再说,只要有通信,也不能复位吧,楼主知道吗?
vale
驱动牛犊
驱动牛犊
  • 注册日期2005-12-24
  • 最后登录2010-04-22
  • 粉丝0
  • 关注0
  • 积分440分
  • 威望45点
  • 贡献值0点
  • 好评度44点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-08-07 15:50
我不是说了么?用_URB_CONTROL_TRANSFER发送CLEAR_FEATURE request
setup packect 的layout你不会不知道吧?
引用第3楼Leonsoft于2007-08-07 11:13发表的  :
楼上的,这个Reset Pipe早试过了,这样做,只能Reset Bulk or ISO pipe,不能做到reset Control Pipe,因为Client端看不到端点0,也就是拿不到Control Pipe的Handle。
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-08-07 16:12
哎,算了,楼主水平高,在下不知道,行吧
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-08-07 16:13
我前面是指复位设备,不是复位管道.
Leonsoft
驱动小牛
驱动小牛
  • 注册日期2003-05-08
  • 最后登录2012-08-11
  • 粉丝1
  • 关注0
  • 积分21分
  • 威望281点
  • 贡献值1点
  • 好评度103点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-08-07 16:14
vale,我以前都是做PCI,PCMCIA方面的开发,刚接触USB driver开发,对USB协议不熟悉,实在不好意思。你能否告知应该怎么配置SetupPacket.
谢谢。
I will do the best with what the God gave me.
vale
驱动牛犊
驱动牛犊
  • 注册日期2005-12-24
  • 最后登录2010-04-22
  • 粉丝0
  • 关注0
  • 积分440分
  • 威望45点
  • 贡献值0点
  • 好评度44点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-08-07 17:56
引用第10楼Leonsoft于2007-08-07 16:14发表的  :
vale,我以前都是做PCI,PCMCIA方面的开发,刚接触USB driver开发,对USB协议不熟悉,实在不好意思。你能否告知应该怎么配置SetupPacket.
谢谢。

sorry,我看你一些感念挺清楚的以为你比较熟。ddk经常把底层封装的让人摸不着头脑,比如defualt pipe的handle问题。我说仔细点。
1. reset pipe就是给目标发送clear feature(至少在windows里面是这样的),usb 2.0 spec里面的标准请求,格式见9.4,
bmRequestType bRequest wValue wIndex wLength
按照表中给上述内容负值就行了,上面这6个变量总共8个字节,就是setup packet。
2. 给control pipe发请求
ddk中只提供了几个标准请求的封装,而且是没法直接发给control pipe,得自己手动。下面是我封装好的函数。把那6个变量打包到一个char[8]里面调用就行了。
3. 这个函数只提供向control pipe发请求。至于你的问题是否就能解决,得看你的硬件和固件是否是clear feature就能恢复正常。



#ifndef USBD_DEFAULT_PIPE_TRANSFER
#define USBD_DEFAULT_PIPE_TRANSFER            0x00000008
#endif

NTSTATUS
Usb_ControlTransfer(
    IN PDEVICE_OBJECT DeviceObject,
    IN PCHAR  SetupPacket
)
{
    PURB                          urb;
    NTSTATUS                      ntStatus;
    PDEVICE_EXTENSION             deviceExtension;


    urb = NULL;
    deviceExtension = DeviceObject->DeviceExtension;

    urb = ExAllocatePool(NonPagedPool,
                         sizeof(struct _URB_CONTROL_TRANSFER));

    if(urb) {

    urb->UrbControlTransfer.Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;
    urb->UrbControlTransfer.Hdr.Length = sizeof(struct _URB_CONTROL_TRANSFER);
    urb->UrbControlTransfer.PipeHandle = NULL; //deviceExtension->UsbInterface->Pipes[0].PipeHandle;
    urb->UrbControlTransfer.TransferBuffer = NULL;
    urb->UrbControlTransfer.TransferBufferMDL = NULL;
    urb->UrbControlTransfer.TransferBufferLength = 0;
    urb->UrbControlTransfer.TransferFlags =  USBD_DEFAULT_PIPE_TRANSFER ;
    urb->UrbControlTransfer.UrbLink = NULL;
    RtlCopyMemory(urb->UrbControlTransfer.SetupPacket, SetupPacket, 8);

        ntStatus = CallUSBD(DeviceObject, urb);

        if(!NT_SUCCESS(ntStatus)) {
            Usb_DbgPrint(1, ("Usb_ControlTransfer failed. Status = %X08\n", ntStatus));
        }

    }
    else {

        Usb_DbgPrint(1, ("Failed to allocate memory for urb\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    if(urb) {

        ExFreePool(urb);
    }

    return ntStatus;
}
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-08-08 11:21
没关系,我也是刚学USB的,我以前是纯搞软件,对这个一点都不懂,看来楼主水平确实不错,以后多向你学习.
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2007-08-08 11:23
我现在也遇到这种情况,复位管道根本不起作用,我没有使用控制台,我一般拔掉USB,重新插入就可以了.呵呵,这是问题所在,也必须解决,只是不知道,这应该是由固件去解决还是驱动去解决,我个人认为应该由固件去解决,不知正确与否.
Leonsoft
驱动小牛
驱动小牛
  • 注册日期2003-05-08
  • 最后登录2012-08-11
  • 粉丝1
  • 关注0
  • 积分21分
  • 威望281点
  • 贡献值1点
  • 好评度103点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2007-08-23 10:14
Vale,我试过,发CLEAR FEATURE,不行的。各位有什么高招可以做到Reset Control Pipe。
I will do the best with what the God gave me.
lejianz
驱动中牛
驱动中牛
  • 注册日期2003-03-05
  • 最后登录2023-11-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望145点
  • 贡献值0点
  • 好评度116点
  • 原创分0分
  • 专家分0分
  • 社区居民
15楼#
发布于:2007-08-23 14:58
还是按照我前面的说法复位设备吧,其实,CLEAR FEATURE也只能对INT EP或BULK EP的.如果你的控制传输都不行的话,你能做的也就是复位设备让它重新枚举了,当然,你的复位可以设置一些条件,比如说,几次都不能有效传输.
一起交流,共同提高!
游客

返回顶部