Ejemplo n.º 1
0
/*++
Routine Description:

The framework calls a driver's EvtDeviceFileCreate callback
when the framework receives an IRP_MJ_CREATE request.
The system sends this request when a user application opens the
device to perform an I/O operation, such as reading or writing a file.
This callback is called synchronously, in the context of the thread
that created the IRP_MJ_CREATE request.

Arguments:

Device - Handle to a framework device object.
FileObject - Pointer to fileobject that represents the open handle.
CreateParams - copy of the create IO_STACK_LOCATION

Return Value:

NT status code
--*/
VOID PSDrv_EvtDeviceFileCreate(IN WDFDEVICE Device, IN WDFREQUEST Request, IN WDFFILEOBJECT FileObject)
{
    NTSTATUS                    status = STATUS_UNSUCCESSFUL;
    PUNICODE_STRING             fileName;
    PFILE_CONTEXT               pFileContext;
    PDEVICE_CONTEXT             pDevContext;
    WDFUSBPIPE                  pipe;

    PSDrv_DbgPrint(3, ("PSDrv_EvtDeviceFileCreate - begins\n"));

    PAGED_CODE();

    // initialize variables
    pDevContext = GetDeviceContext(Device);
    pFileContext = GetFileContext(FileObject);
    fileName = WdfFileObjectGetFileName(FileObject);

    if (0 == fileName->Length)
	{
        // opening a device as opposed to pipe.
        status = STATUS_SUCCESS;
    }
    else {
        pipe = GetPipeFromName(pDevContext, fileName);

		// Does the pipe exists?
        if (pipe != NULL)
		{
            pFileContext->Pipe = pipe;

            WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

			// Set the default timeout
			pFileContext->nTimeOut = PSUSBDRV_DEFAULT_TIMEOUT;

            status = STATUS_SUCCESS;
        }
		else
		{
            status = STATUS_INVALID_DEVICE_REQUEST;
        }
    }

    WdfRequestComplete(Request, status);

    PSDrv_DbgPrint(3, ("PSDrv_EvtDeviceFileCreate - ends\n"));

    return;
}
Ejemplo n.º 2
0
static VOID UsbChief_EvtDeviceFileCreate(IN WDFDEVICE Device, IN WDFREQUEST Request,
				  IN WDFFILEOBJECT FileObject)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	PUNICODE_STRING fileName;
	PFILE_CONTEXT pFileContext;
	PDEVICE_CONTEXT pDevContext;
	WDFUSBPIPE  pipe;

	PAGED_CODE();

	UsbChief_DbgPrint(DEBUG_RW|DEBUG_IOCTL, ("called\n"));

	pDevContext = GetDeviceContext(Device);
	pFileContext = GetFileContext(FileObject);

	fileName = WdfFileObjectGetFileName(FileObject);

	if (!fileName->Length) {
		status = STATUS_SUCCESS;
	} else {
		pipe = UsbChief_GetPipeFromName(pDevContext, fileName);

		if (pipe != NULL) {
			pFileContext->Pipe = pipe;

			WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

			status = STATUS_SUCCESS;
		} else {
			status = STATUS_INVALID_DEVICE_REQUEST;
		}
	}

	WdfRequestComplete(Request, status);
}
NTSTATUS AndroidUsbPipeFileObject::InitializePipe(
    const WDF_USB_PIPE_INFORMATION* pipe_info) {
  ASSERT_IRQL_LOW();
  ASSERT(IsPipeAttached());
  if (!IsPipeAttached())
    return STATUS_INTERNAL_ERROR;

  // Initialize base class
  NTSTATUS status = AndroidUsbFileObject::Initialize();
  ASSERT(NT_SUCCESS(status));
  if (!NT_SUCCESS(status))
    return status;

  // Save pipe information
  pipe_information_ = *pipe_info;

  // We will provide size check ourselves (less surprizes always better)
  WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(wdf_pipe());

  GoogleDbgPrint("\n===== File %p for %s pipe. max_transfer_size = %X, max_packet_size = %X",
                 this, is_input_pipe() ? "read" : "write",
                 max_transfer_size(), max_packet_size());
  return STATUS_SUCCESS;
}
Ejemplo n.º 4
0
NTSTATUS
SelectInterfaces(
    _In_ WDFDEVICE Device
    )
/*++

Routine Description:

    This helper routine selects the configuration, interface and
    creates a context for every pipe (end point) in that interface.

Arguments:

    Device - Handle to a framework device

Return Value:

    NT status value

--*/
{
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    NTSTATUS                            status = STATUS_SUCCESS;
    PDEVICE_CONTEXT                     pDeviceContext;
    WDFUSBPIPE                          pipe;
    WDF_USB_PIPE_INFORMATION            pipeInfo;
    UCHAR                               index;
    UCHAR                               numberConfiguredPipes;
    WDFUSBINTERFACE                     usbInterface;

    PAGED_CODE();

    pDeviceContext = GetDeviceContext(Device);

    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

    usbInterface =
        WdfUsbTargetDeviceGetInterface(pDeviceContext->UsbDevice, 0);

    if (NULL == usbInterface) {
       status = STATUS_UNSUCCESSFUL;
       TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                   "WdfUsbTargetDeviceGetInterface 0 failed %!STATUS! \n",
                   status);
       return status;
    }

    configParams.Types.SingleInterface.ConfiguredUsbInterface =
        usbInterface;
    
    configParams.Types.SingleInterface.NumberConfiguredPipes =
        WdfUsbInterfaceGetNumConfiguredPipes(usbInterface);

    pDeviceContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    numberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;

    //
    // Get pipe handles
    //
    for(index=0; index < numberConfiguredPipes; index++) {

        WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);

        pipe = WdfUsbInterfaceGetConfiguredPipe(
            pDeviceContext->UsbInterface,
            index, //PipeIndex,
            &pipeInfo
            );
        //
        // Tell the framework that it's okay to read less than
        // MaximumPacketSize
        //
        WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

        if(WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "Interrupt Pipe is 0x%p\n", pipe);
            pDeviceContext->InterruptPipe = pipe;
        }

        if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
                WdfUsbTargetPipeIsInEndpoint(pipe)) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "BulkInput Pipe is 0x%p\n", pipe);
            pDeviceContext->BulkReadPipe = pipe;
        }

        if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
                WdfUsbTargetPipeIsOutEndpoint(pipe)) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "BulkOutput Pipe is 0x%p\n", pipe);
            pDeviceContext->BulkWritePipe = pipe;
        }

    }

    //
    // If we didn't find all the 3 pipes, fail the start.
    //
    if(!(pDeviceContext->BulkWritePipe
            && pDeviceContext->BulkReadPipe && pDeviceContext->InterruptPipe)) {
        status = STATUS_INVALID_DEVICE_STATE;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                            "Device is not configured properly %!STATUS!\n",
                            status);

        return status;
    }

    return status;
}
Ejemplo n.º 5
0
Archivo: usb.c Proyecto: uri247/wdk80
NTSTATUS
HidFx2EvtDevicePrepareHardware(
    IN WDFDEVICE    Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    )
/*++

Routine Description:

    In this callback, the driver does whatever is necessary to make the
    hardware ready to use.  In the case of a USB device, this involves
    reading and selecting descriptors.

Arguments:

    Device - handle to a device

    ResourceList - A handle to a framework resource-list object that
    identifies the raw hardware resourcest

    ResourceListTranslated - A handle to a framework resource-list object
    that identifies the translated hardware resources

Return Value:

    NT status value

--*/
{
    NTSTATUS                            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION                   devContext = NULL;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    WDF_OBJECT_ATTRIBUTES               attributes;
    PUSB_DEVICE_DESCRIPTOR              usbDeviceDescriptor = NULL;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

    PAGED_CODE ();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,
        "HidFx2EvtDevicePrepareHardware Enter\n");

    devContext = GetDeviceContext(Device);

    //
    // Create a WDFUSBDEVICE object. WdfUsbTargetDeviceCreate obtains the
    // USB device descriptor and the first USB configuration descriptor from
    // the device and stores them. It also creates a framework USB interface
    // object for each interface in the device's first configuration.
    //
    // The parent of each USB device object is the driver's framework driver
    // object. The driver cannot change this parent, and the ParentObject
    // member or the WDF_OBJECT_ATTRIBUTES structure must be NULL.
    //
    // We only create device the first time PrepareHardware is called. If 
    // the device is restarted by pnp manager for resource rebalance, we 
    // will use the same device handle but then select the interfaces again
    // because the USB stack could reconfigure the device on restart.
    //
    if (devContext->UsbDevice == NULL) {
        status = WdfUsbTargetDeviceCreate(Device,
                                          WDF_NO_OBJECT_ATTRIBUTES,
                                          &devContext->UsbDevice);
  
        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                "WdfUsbTargetDeviceCreate failed 0x%x\n", status);
            return status;
        }
    }

    //
    // Select a device configuration by using a
    // WDF_USB_DEVICE_SELECT_CONFIG_PARAMS structure to specify USB
    // descriptors, a URB, or handles to framework USB interface objects.
    //
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

    status = WdfUsbTargetDeviceSelectConfig(devContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n",
            status);
        return status;
    }

    devContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    //
    // Get the device descriptor and store it in device context
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = Device;
    status = WdfMemoryCreate(
                             &attributes,
                             NonPagedPool,
                             0,
                             sizeof(USB_DEVICE_DESCRIPTOR),
                             &devContext->DeviceDescriptor,
                             &usbDeviceDescriptor
                             );

    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfMemoryCreate for Device Descriptor failed %!STATUS!\n",
            status);
        return status;
    }

    WdfUsbTargetDeviceGetDeviceDescriptor(
          devContext->UsbDevice,
          usbDeviceDescriptor
          );

    //
    // Get the Interrupt pipe. There are other endpoints but we are only
    // interested in interrupt endpoint since our HID data comes from that
    // endpoint. Another way to get the interrupt endpoint is by enumerating
    // through all the pipes in a loop and looking for pipe of Interrupt type.
    //
    devContext->InterruptPipe = WdfUsbInterfaceGetConfiguredPipe(
                                                  devContext->UsbInterface,
                                                  INTERRUPT_ENDPOINT_INDEX,
                                                  NULL);// pipeInfo

    if (NULL == devContext->InterruptPipe) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                    "Failed to get interrupt pipe info\n");
        status = STATUS_INVALID_DEVICE_STATE;
        return status;
    }

    //
    // Tell the framework that it's okay to read less than
    // MaximumPacketSize
    //
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(devContext->InterruptPipe);

    //
    //configure continuous reader
    //
    status = HidFx2ConfigContReaderForInterruptEndPoint(devContext);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,
        "HidFx2EvtDevicePrepareHardware Exit, Status:0x%x\n", status);

    return status;
}
Ejemplo n.º 6
0
///////////////////////////////////////////////////////////////////////////////
//
//  BasicUsbEvtDevicePrepareHardware
//
//    This routine is called by the framework when a device of
//    the type we support is coming online. Our job will be to
//    create our WDFUSBDEVICE and configure it.
//
//  INPUTS:
//
//      Device       - One of our WDFDEVICE objects
//
//      ResourceList - We're a USB device, so not used
//
//      ResourceListTranslated - We're a USB device, so not
//                               used
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_SUCCESS, otherwise an error indicating why the driver could not
//                      load.
//
//  IRQL:
//
//      This routine is called at IRQL == PASSIVE_LEVEL.
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
BasicUsbEvtDevicePrepareHardware(
    IN WDFDEVICE Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    ) {

    NTSTATUS                            status;
    PBASICUSB_DEVICE_CONTEXT            devContext;   
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS selectConfigParams;
    WDFUSBINTERFACE                     configuredInterface;
    WDF_USB_PIPE_INFORMATION            pipeInfo;
    UCHAR                               numPipes;
    UCHAR                               pipeIndex;
    WDFUSBPIPE                          configuredPipe;
    WDF_USB_CONTINUOUS_READER_CONFIG    contReaderConfig;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

#if DBG
    DbgPrint("BasicUsbEvtDevicePrepareHardware\n");
#endif

    devContext = BasicUsbGetContextFromDevice(Device);

    //
    // First thing to do is create our WDFUSBDEVICE. This is the
    // special USB I/O target that we'll be using to configure our
    // device and to send control requests.
    //
    // Under very rare cirumstances (i.e. resource rebalance of the
    // host controller) it's possible to come through here multiple
    // times. We could handle this by having an
    // EvtDeviceReleaseHardware and cleaning up the USB device
    // target, but we'll just leave it around and avoid creating it
    // multiple times with this check. No race condition as our
    // Prepare and Release can't run in parallel for the same device
    // 
    if (devContext->BasicUsbUsbDevice == NULL) {

        status = WdfUsbTargetDeviceCreate(Device, 
                                          WDF_NO_OBJECT_ATTRIBUTES,
                                          &devContext->BasicUsbUsbDevice);
        if (!NT_SUCCESS(status)) {
    #if DBG
            DbgPrint("WdfUsbTargetDeviceCreate failed 0x%0x\n", status);
    #endif
            return status;
        }

    }

    //
    // Now that our WDFUSBDEVICE is created, it's time to select
    // our configuration and enable our interface.
    //

    //
    // The OSRFX2 device only has a single interface, so we'll
    // initialize our select configuration parameters structure
    // using the specially provided macro
    //
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(
                                                &selectConfigParams);

    //
    // And actually select our configuration.
    //
    status = WdfUsbTargetDeviceSelectConfig(devContext->BasicUsbUsbDevice,
                                            WDF_NO_OBJECT_ATTRIBUTES,
                                            &selectConfigParams);
    if (!NT_SUCCESS(status)) {
#if DBG
        DbgPrint("WdfUsbTargetDeviceSelectConfig failed 0x%0x\n", status);
#endif
        return status;

    }

    //
    // Our single interface has been configured. Let's grab the
    // WDFUSBINTERFACE object so that we can get our pipes.
    //
    configuredInterface 
            = selectConfigParams.Types.SingleInterface.ConfiguredUsbInterface;

    //
    // How many pipes were configure?
    //
    numPipes = selectConfigParams.Types.SingleInterface.NumberConfiguredPipes;

    //
    // For all the pipes that were configured....
    //
    for(pipeIndex = 0; pipeIndex < numPipes; pipeIndex++) {

        //
        // We'll need to find out the type the pipe, which we'll do
        // by supplying a pipe information structure when calling
        // WdfUsbInterfaceGetConfiguredPipe
        //
        WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);

        //
        // Get the configured pipe.
        //
        configuredPipe = WdfUsbInterfaceGetConfiguredPipe(configuredInterface,
                                                          pipeIndex,
                                                          &pipeInfo);

        //
        // For this device, we're looking for three pipes:
        //
        // 1) A Bulk IN pipe
        // 2) A Bulk OUT pipe
        // 3) An Interrupt IN pipe
        //

        //
        // First, let's see what type of pipe it is...
        //
        switch (pipeInfo.PipeType) {
            case WdfUsbPipeTypeBulk: {

                //
                // Bulk pipe. Determine if it's an IN pipe or not.
                //
                if (WdfUsbTargetPipeIsInEndpoint(configuredPipe)) {

                    //
                    // Bulk IN pipe. Should only ever get one of these...
                    //
                    ASSERT(devContext->BulkInPipe == NULL);

                    devContext->BulkInPipe = configuredPipe;

                } else {

                    //
                    // HAS to be an OUT...
                    //
                    ASSERT(WdfUsbTargetPipeIsOutEndpoint(configuredPipe));

                    //
                    // Bulk OUT pipe. Should only ever get one of these...
                    //
                    ASSERT(devContext->BulkOutPipe == NULL);

                    devContext->BulkOutPipe = configuredPipe;
                }
                break;
            }
            case WdfUsbPipeTypeInterrupt: {
                //
                // We're only expecting an IN interrupt pipe
                //
                ASSERT(WdfUsbTargetPipeIsInEndpoint(configuredPipe));

                //
                // And we're only expected one of them
                //
                ASSERT(devContext->InterruptInPipe == NULL);

                devContext->InterruptInPipe = configuredPipe;
                break;
            }
            default: {
                //
                // Don't know what it is, don't care what it is...
                //
#if DBG
                DbgPrint("Unexpected pipe type? 0x%x\n", pipeInfo.PipeType);
#endif                
                break;
            }

        }

    }

    //
    // We hopefully have found everything we need...
    //
    if (devContext->BulkInPipe == NULL  ||
        devContext->BulkOutPipe == NULL ||
        devContext->InterruptInPipe == NULL) {
#if DBG
        DbgPrint("Didn't find expected pipes. BIN=0x%p, BOUT=0x%p, IIN=0x%p\n",
                    devContext->BulkInPipe,
                    devContext->BulkOutPipe,
                    devContext->InterruptInPipe);

#endif
        return STATUS_DEVICE_CONFIGURATION_ERROR;
    }

    //
    // By default, KMDF will not allow any non-MaxPacketSize
    // aligned I/O to be done against IN pipes. This is to avoid
    // hitting "babble" conditions, which occur when the device
    // sends more data than what you've asked it for.
    //
    // Our device doesn't babble, so we don't need this check on
    // our IN pipes.
    //
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(devContext->BulkInPipe);
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(devContext->InterruptInPipe);


    //
    // For fun, we're going to hang a continuous reader out on the
    // interrupt endpoint. By doing so, we'll get called at
    // BasicUsbInterruptPipeReadComplete every time someone toggles
    // the switches on the switch pack.
    //


    //
    // Initialize the continuous reader config structure, specifying
    // our callback, our context, and the size of the transfers.
    //
    WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&contReaderConfig,
                                          BasicUsbInterruptPipeReadComplete,
                                          devContext,
                                          sizeof(UCHAR));

    //
    // And create the continuous reader.
    //
    // Note that the continuous reader is not started by default, so
    // we'll need to manually start it when we are called at
    // EvtD0Entry.
    //
    status = WdfUsbTargetPipeConfigContinuousReader(devContext->InterruptInPipe,
                                                    &contReaderConfig);

    if (!NT_SUCCESS(status)) {
#if DBG
        DbgPrint("WdfUsbTargetPipeConfigContinuousReader failed 0x%0x\n", 
                 status);
#endif
        return status;
    }
        
    return STATUS_SUCCESS;

}
Ejemplo n.º 7
0
NTSTATUS
EvtDevicePrepareHardware(
    IN WDFDEVICE    Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    )
{
    NTSTATUS                            status;
    PDEVICE_CONTEXT                     pDeviceContext;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

    pDeviceContext = GetDeviceContext(Device);
    
    //
    // Create the USB device if it is not already created.
    //
    if (pDeviceContext->UsbDevice == NULL) {
        WDF_USB_DEVICE_CREATE_CONFIG config;

        WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config,
                                   USBD_CLIENT_CONTRACT_VERSION_602);

        status = WdfUsbTargetDeviceCreateWithParameters(Device,
                                               &config,
                                               WDF_NO_OBJECT_ATTRIBUTES,
                                               &pDeviceContext->UsbDevice);

        if (!NT_SUCCESS(status)) {
            KdPrint(("WdfUsbTargetDeviceCreateWithParameters failed 0x%x\n", status));        
            return status;
        }
    }

    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);

    status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {
        KdPrint(("WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n", status));
        return status;
    }

    pDeviceContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;


    pDeviceContext->BulkReadPipe = WdfUsbInterfaceGetConfiguredPipe(
                                                  pDeviceContext->UsbInterface,
                                                  BULK_IN_ENDPOINT_INDEX,
                                                  NULL);// pipeInfo

    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkReadPipe);

    pDeviceContext->BulkWritePipe = WdfUsbInterfaceGetConfiguredPipe(
                                                  pDeviceContext->UsbInterface,
                                                  BULK_OUT_ENDPOINT_INDEX,
                                                  NULL);// pipeInfo

    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkWritePipe);

    return status;
}
Ejemplo n.º 8
0
// In this callback, the driver does whatever is necessary to make the hardware ready to use.
// In the case of a USB device, this involves reading and selecting descriptors.
NTSTATUS
HidFx2EvtDevicePrepareHardware(
    _In_ WDFDEVICE    hDevice,
    _In_ WDFCMRESLIST hResourceList,
    _In_ WDFCMRESLIST hResourceListTranslated
   )
{
    NTSTATUS                            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION                   pDevContext = NULL;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    WDF_OBJECT_ATTRIBUTES               attributes;
    PUSB_DEVICE_DESCRIPTOR              pUsbDeviceDescriptor = NULL;

    UNREFERENCED_PARAMETER(hResourceList);
    UNREFERENCED_PARAMETER(hResourceListTranslated);

    PAGED_CODE ();

    TraceVerbose(DBG_INIT, "(%!FUNC!) Enter\n");

    pDevContext = GetDeviceContext(hDevice);

    // Create a WDFUSBDEVICE object. WdfUsbTargetDeviceCreate obtains the USB device descriptor and the first USB configuration
    //descriptor from the device and stores them. It also creates a framework USB interface object for each interface in the device's first configuration.
    //
    // The parent of each USB device object is the driver's framework driver object. The driver cannot change this parent, and the ParentObject
    // member or the WDF_OBJECT_ATTRIBUTES structure must be NULL.
    //
    // We only create device the first time PrepareHardware is called. If the device is restarted by pnp manager for resource rebalance, we 
    // will use the same device handle but then select the interfaces again because the USB stack could reconfigure the device on restart.
    if (pDevContext->hUsbDevice == NULL)
    {
        status = WdfUsbTargetDeviceCreate(hDevice, WDF_NO_OBJECT_ATTRIBUTES, &pDevContext->hUsbDevice);
        if (!NT_SUCCESS(status))
        {
            TraceErr(DBG_PNP, "(%!FUNC!) WdfUsbTargetDeviceCreate failed %!STATUS!\n", status);
            return status;
        }
    }

    // Select a device configuration by using a WDF_USB_DEVICE_SELECT_CONFIG_PARAMS
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);
    status = WdfUsbTargetDeviceSelectConfig(pDevContext->hUsbDevice, WDF_NO_OBJECT_ATTRIBUTES, &configParams);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n", status);
        return status;
    }

    pDevContext->hUsbInterface = configParams.Types.SingleInterface.ConfiguredUsbInterface;

    // Get the device descriptor and store it in device context
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = hDevice;
    status = WdfMemoryCreate(&attributes,
                             NonPagedPool,
                             0,
                             sizeof(USB_DEVICE_DESCRIPTOR),
                             &pDevContext->hDeviceDescriptor,
                             &pUsbDeviceDescriptor);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfMemoryCreate for Device Descriptor failed %!STATUS!\n", status);
        return status;
    }

    WdfUsbTargetDeviceGetDeviceDescriptor(pDevContext->hUsbDevice, pUsbDeviceDescriptor);

    // Get the Interrupt pipe. There are other endpoints but we are only interested in interrupt endpoint since our HID data comes from this
    pDevContext->hInterruptPipe = WdfUsbInterfaceGetConfiguredPipe(pDevContext->hUsbInterface, INTERRUPT_ENDPOINT_INDEX, NULL);
    if (NULL == pDevContext->hInterruptPipe)
    {
        TraceErr(DBG_PNP, "(%!FUNC!) Failed to get interrupt pipe info\n");
        status = STATUS_INVALID_DEVICE_STATE;
        return status;
    }

    // Tell the framework that it's okay to read less than MaximumPacketSize
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDevContext->hInterruptPipe);

    //configure continuous reader
    status = HidFx2ConfigContReaderForInterruptEndPoint(pDevContext);

    TraceVerbose(DBG_INIT, "(%!FUNC!) Exit, Status: %!STATUS!\n", status);

    return status;
}
Ejemplo n.º 9
0
NTSTATUS ConfigureUsbPipes(PDEVICE_CONTEXT DeviceContext)
{
  NTSTATUS status = STATUS_SUCCESS;
  BYTE index = 0;
  WDF_USB_PIPE_INFORMATION pipeConfig;
  WDFUSBPIPE pipe = NULL;
  BYTE  numEndpoints;

  // For debug
  numEndpoints = WdfUsbInterfaceGetNumEndpoints(
                                              DeviceContext->UsbInterface,
                                              0
                                              );

  KdPrint((__DRIVER_NAME " Found %i EndPoints\n", numEndpoints)); 
  // For debug

  DeviceContext->UsbInterruptPipe = NULL;
  DeviceContext->UsbBulkInPipe = NULL;
  DeviceContext->UsbBulkOutPipe = NULL;
  WDF_USB_PIPE_INFORMATION_INIT(&pipeConfig);	// Init pipe config
  
  //
  // Scan all pipe from USB Interface
  //
  do
  {
    pipe = WdfUsbInterfaceGetConfiguredPipe(DeviceContext->UsbInterface,
                                          index,
                                          &pipeConfig);
											
    if (NULL == pipe)
      break;

    // For debug
    KdPrint((__DRIVER_NAME " Pipe[%i].PacketSize = %i\n", index, pipeConfig.MaximumPacketSize));    
    // For debug

    /*None of our data transfers will have a guarantee that the requested
      data size is a multiple of the packet size.*/
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

    if(WdfUsbPipeTypeInterrupt == pipeConfig.PipeType)	// Interrupt pipe
    { 
	  KdPrint((__DRIVER_NAME " Found Interrupt Pipe at index %i\n", index));
      DeviceContext->UsbInterruptPipe = pipe;
    }
    else if(WdfUsbPipeTypeBulk == pipeConfig.PipeType)	// Bulk pipe
    {
      if(TRUE == WdfUsbTargetPipeIsInEndpoint(pipe))	// In EndPoint of Bulk
      {
	    KdPrint((__DRIVER_NAME " Found In Endpoint Pipe at index %i\n", index));
        DeviceContext->UsbBulkInPipe = pipe;
      }
      else if(TRUE == WdfUsbTargetPipeIsOutEndpoint(pipe))
      {
        KdPrint((__DRIVER_NAME " Found Out Endpoint Pipe at index %i\n", index));
        DeviceContext->UsbBulkOutPipe = pipe;			// Out EndPoint of Bulk
      }
    }
	
	index++;	// Encreate index of Pipe
	
  } while (NULL != pipe);

  // Check for all 3 pipe: interrupt, Bulk In, Bulk Out for our device
  if((NULL == DeviceContext->UsbInterruptPipe) ||
	  (NULL == DeviceContext->UsbBulkInPipe) ||
	  (NULL == DeviceContext->UsbBulkOutPipe))
  {
    KdPrint((__DRIVER_NAME
      "Not all expected USB pipes were found.\n"));
    return STATUS_INVALID_PARAMETER;
  }
  
  return status;
}
Ejemplo n.º 10
0
NTSTATUS
SelectInterfaces(
    __in WDFDEVICE Device
    )
/*++

Routine Description:

    This helper routine selects the configuration, interface and
    creates a context for every pipe (end point) in that interface.

Arguments:

    Device - Handle to a framework device

Return Value:

    NT status value

--*/
{
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    NTSTATUS                            status;
    PDEVICE_CONTEXT                     pDeviceContext;
    WDFUSBPIPE                          pipe;
    WDF_USB_PIPE_INFORMATION            pipeInfo;
    UCHAR                               index;
    UCHAR                               numberConfiguredPipes;

    PAGED_CODE();

    pDeviceContext = GetDeviceContext(Device);

    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

    status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {

        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                        "WdfUsbTargetDeviceSelectConfig failed %!STATUS! \n",
                        status);

        //
        // Since the Osr USB fx2 device is capable of working at high speed, the only reason 
        // the device would not be working at high speed is if the port doesn't 
        // support it. If the port doesn't support high speed it is a 1.1 port
        //
        if ((pDeviceContext->UsbDeviceTraits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) == 0) {
            GUID activity = DeviceToActivityId(Device);

            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                            " On a 1.1 USB port on Windows Vista" 
                            " this is expected as the OSR USB Fx2 board's Interrupt EndPoint descriptor" 
                            " doesn't conform to the USB specification. Windows Vista detects this and"
                            " returns an error. \n"
                            );
            EventWriteSelectConfigFailure(
                &activity,
                pDeviceContext->DeviceName,
                pDeviceContext->Location,
                status
                );
        }
        
        return status;
    }


    pDeviceContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    numberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;

    //
    // Get pipe handles
    //
    for(index=0; index < numberConfiguredPipes; index++) {

        WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);

        pipe = WdfUsbInterfaceGetConfiguredPipe(
            pDeviceContext->UsbInterface,
            index, //PipeIndex,
            &pipeInfo
            );
        //
        // Tell the framework that it's okay to read less than
        // MaximumPacketSize
        //
        WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

        if(WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "Interrupt Pipe is 0x%p\n", pipe);
            pDeviceContext->InterruptPipe = pipe;
        }

        if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
                WdfUsbTargetPipeIsInEndpoint(pipe)) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "BulkInput Pipe is 0x%p\n", pipe);
            pDeviceContext->BulkReadPipe = pipe;
        }

        if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
                WdfUsbTargetPipeIsOutEndpoint(pipe)) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "BulkOutput Pipe is 0x%p\n", pipe);
            pDeviceContext->BulkWritePipe = pipe;
        }

    }

    //
    // If we didn't find all the 3 pipes, fail the start.
    //
    if(!(pDeviceContext->BulkWritePipe
            && pDeviceContext->BulkReadPipe && pDeviceContext->InterruptPipe)) {
        status = STATUS_INVALID_DEVICE_STATE;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                            "Device is not configured properly %!STATUS!\n",
                            status);

        return status;
    }

    return status;
}
Ejemplo n.º 11
0
VOID CyGetActiveAltInterfaceConfig(__in PDEVICE_CONTEXT pDevContext)
{
	WDFUSBPIPE                          UsbPipe;
    WDF_USB_PIPE_INFORMATION            UsbPipeInfo;
    UCHAR                               ucIndex;
    UCHAR                               ucNumberConfiguredPipes;
	
	ucNumberConfiguredPipes = WdfUsbInterfaceGetNumConfiguredPipes(pDevContext->UsbInterfaceConfig.Types.SingleInterface.ConfiguredUsbInterface);	
	pDevContext->ucActiveNumOfPipe = ucNumberConfiguredPipes; /* Update the number of cofigured pipe */
	CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"Number of configured pipe 0x%x\n", pDevContext->ucActiveNumOfPipe); 

	pDevContext->ucActiveInterruptInPipe = 0; // Initialize
	for(ucIndex=0; ucIndex < ucNumberConfiguredPipes; ucIndex++) 
	{
		WDF_USB_PIPE_INFORMATION_INIT(&UsbPipeInfo);

		UsbPipe = WdfUsbInterfaceGetConfiguredPipe(
			pDevContext->UsbInterfaceConfig.Types.SingleInterface.ConfiguredUsbInterface,
			ucIndex,
			&UsbPipeInfo
			);        
		WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(UsbPipe); /* disable check for the multiple of maximum packet size for read/write buffer */
		pDevContext->WdfUsbPipeArray[ucIndex] = UsbPipe; /* Store pipe handle */
		/* display information */		
		if(WdfUsbPipeTypeInterrupt == UsbPipeInfo.PipeType && (WdfUsbTargetPipeIsInEndpoint(UsbPipe)))
		{
			//Update the interrupt IN endpoint information
			pDevContext->WdfUsbInterruptInPipeArray[pDevContext->ucActiveInterruptInPipe]=UsbPipe;
			pDevContext->ucActiveInterruptInPipe++;

			CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
					"Interrupt Pipe is 0x%p\n", UsbPipe);  
			CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
					"Interrupt Pipe\n"); 					
		}
		if(WdfUsbPipeTypeBulk == UsbPipeInfo.PipeType) {
			CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
					"Bulk Pipe is 0x%p\n", UsbPipe);            // && WdfUsbTargetPipeIsInEndpoint(pipe
			CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
					"Bulk Pipe\n");			
		}        

		if(WdfUsbPipeTypeIsochronous == UsbPipeInfo.PipeType &&
				WdfUsbTargetPipeIsOutEndpoint(UsbPipe)) 
		{
			CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
					"Isochronous Pipe is 0x%p\n", UsbPipe);            
			CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
					"Isochronous Pipe\n");			
		}
		CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
				" MaximumPacketSize :%x\n", UsbPipeInfo.MaximumPacketSize);
		CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
				" EndpointAddress  :%x\n", UsbPipeInfo.EndpointAddress);
		CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
				" Interval   :%x\n", UsbPipeInfo.Interval);
		CyTraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
				" SettingIndex    :%x\n", UsbPipeInfo.SettingIndex);  
	}

}