?? usbfx2lk_usb.cpp
字號:
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2005 OSR Open Systems Resources, Inc.
// All Rights Reserved
//
// This sofware is supplied for instructional purposes only.
//
// OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
// for this software. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
// THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
// PURPOSE. THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
// WITH YOU. OSR's entire liability and your exclusive remedy shall not
// exceed the price paid for this material. In no event shall OSR or its
// suppliers be liable for any damages whatsoever (including, without
// limitation, damages for loss of business profit, business interruption,
// loss of business information, or any other pecuniary loss) arising out
// of the use or inability to use this software, even if OSR has been
// advised of the possibility of such damages. Because some states/
// jurisdictions do not allow the exclusion or limitation of liability for
// consequential or incidental damages, the above limitation may not apply
// to you.
//
// OSR Open Systems Resources, Inc.
// 105 Route 101A Suite 19
// Amherst, NH 03031 (603) 595-6500 FAX: (603) 595-6503
// email bugs to: bugs@osr.com
//
//
// MODULE:
//
// USBFx2LK_PnP.cpp
//
// ABSTRACT:
//
// This file contains the routines that handle Plug and Play processing for the
// OSR USB FX2 Learning Kit Device
//
// AUTHOR(S):
//
// OSR Open Systems Resources, Inc.
//
///////////////////////////////////////////////////////////////////////////////
#include "usbfx2lk.h"
#ifdef WPP_TRACING
//
// Include the necessary tmh file - this is
// just a matter of course if you're using WPP tracing.
//
extern "C" {
#include "usbfx2lk_usb.tmh"
}
#endif
//
// Forward Definitions
//
NTSTATUS SubmitUrb(PUSBFX2LK_EXT DevExt,PURB Urb);
NTSTATUS ConfigureUsbDevice(PUSBFX2LK_EXT DevExt);
NTSTATUS SelectUsbInterfaces(PUSBFX2LK_EXT DevExt,
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);
VOID DetermineDeviceSpeed(PUSBFX2LK_EXT DevExt);
#ifndef IoForwardIrpSynchronously
NTSTATUS DetermineDeviceSpeedCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
#endif //IoForwardIrpSynchronously
NTSTATUS AsynchronousUrbRequestCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp, IN PVOID Context);
///////////////////////////////////////////////////////////////////////////////
//
// ReadandSelectUsbDescriptors
//
// This routine is called by OsrStartDevice to Read and Select the USB
// descriptors that will be used to talk to the usb device.
//
//
// INPUTS:
//
// DevExt - Address of the Devices Device Extension.
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// None
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL
//
// CONTEXT:
//
// Arbitrary Context
//
// NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS ReadandSelectUsbDescriptors(PUSBFX2LK_EXT DevExt)
{
PURB urb = NULL;
NTSTATUS status;
PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ReadandSelectUsbDescriptors: Enter\n"));
//
// Allocate a URB.
//
urb = (PURB) ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),'bruO');
if(urb) {
//
// Allocate a USB_DEVICE_DESCRIPTOR to receive the device descriptor from our device.
//
deviceDescriptor = (PUSB_DEVICE_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool,
sizeof(USB_DEVICE_DESCRIPTOR), 'dduO');
if(deviceDescriptor) {
//
// Format the Urb for the request to get the USB_DEVICE_DESCRIPTOR
//
UsbBuildGetDescriptorRequest(
urb,
(USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0,
deviceDescriptor,
NULL,
sizeof(USB_DEVICE_DESCRIPTOR),
NULL);
//
// Submit the URB to the Device
//
status = SubmitUrb(DevExt,urb);
//
// If the request is successful, then configure the device
//
if(NT_SUCCESS(status)) {
ASSERT(deviceDescriptor->bNumConfigurations);
//
// Save away the device descriptor
//
DevExt->UsbDeviceDescriptor = deviceDescriptor;
status = ConfigureUsbDevice(DevExt);
} else {
//
// No descriptor info? Clean up.
//
ExFreePool(deviceDescriptor);
}
//
// Free the URB
//
ExFreePool(urb);
} else {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("ReadandSelectUsbDescriptors: Failed to allocate memory for deviceDescriptor\n"));
ExFreePool(urb);
status = STATUS_INSUFFICIENT_RESOURCES;
}
} else {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("ReadandSelectUsbDescriptors: Failed to allocate memory for urb\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
}
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ReadandSelectUsbDescriptors: Exit\n"));
return status;
}
///////////////////////////////////////////////////////////////////////////////
//
// ConfigureUsbDevice
//
// This routine is called by ReadandSelectUsbDescriptors to read the USB
// configuration descriptor that will be used to talk to the usb device.
//
//
// INPUTS:
//
// DevExt - Address of the Devices Device Extension.
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// None
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL
//
// CONTEXT:
//
// Arbitrary Context
//
// NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS ConfigureUsbDevice(PUSBFX2LK_EXT DevExt)
{
PURB urb = NULL;
ULONG size = sizeof(USB_CONFIGURATION_DESCRIPTOR);
NTSTATUS status;
PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ConfigureUsbDevice: Enter\n"));
//
// Allocate memory for a URB.
//
urb = (PURB) ExAllocatePoolWithTag(NonPagedPool,sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),'bruO');
if(urb) {
//
// Allocate memory for the default sized configuration descriptor.
//
configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size,'dcuO');
if(configurationDescriptor) {
//
// Format the URB for the request.
//
UsbBuildGetDescriptorRequest(
urb,
(USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
configurationDescriptor,
NULL,
sizeof(USB_CONFIGURATION_DESCRIPTOR),
NULL);
//
// Submit the request to the USB Device.
//
status = SubmitUrb(DevExt,urb);
//
// If the request is not successful, go and cleanup from the error.
//
if(!NT_SUCCESS(status)) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("ConfigureUsbDevice: UsbBuildGetDescriptorRequest failed\n"));
goto ConfigureDevice_Exit;
}
} else {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,("ConfigureUsbDevice: Failed to allocate mem for config Descriptor\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
goto ConfigureDevice_Exit;
}
//
// Okay, the request was successful. Look at the returned length in the configuration
// descriptor and use it to allocate a configuration descriptor that is big enough
// to receive the full configuration from the device.
//
size = configurationDescriptor->wTotalLength;
//
// Free the existing configuration descriptor.
//
ExFreePool(configurationDescriptor);
//
// Allocate the correct sized descriptor.
//
configurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size,'dcuO');
if(configurationDescriptor) {
//
// Format the urb to get the full configuration descriptor.
//
UsbBuildGetDescriptorRequest(
urb,
(USHORT)sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
configurationDescriptor,
NULL,
size,
NULL);
//
// Submit the request to the device.
//
status = SubmitUrb(DevExt,urb);
//
// If the request is not successful, clean up after the error.
//
if(!NT_SUCCESS(status)) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("ConfigureUsbDevice: Failed to read configuration descriptor\n"));
goto ConfigureDevice_Exit;
}
} else {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("ConfigureUsbDevice: Failed to alloc mem for config Descriptor\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
goto ConfigureDevice_Exit;
}
} else {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("ConfigureUsbDevice: Failed to allocate memory for urb\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
goto ConfigureDevice_Exit;
}
//
// Check to make sure that a configuration descriptor was allocated.
//
if(configurationDescriptor) {
//
// Save a copy of configurationDescriptor in deviceExtension
// remember to free it later.
//
DevExt->UsbConfigurationDescriptor = configurationDescriptor;
//
// Determine if the USB configuration is cabable of supporting
// remote wake.
//
if(configurationDescriptor->bmAttributes & USB_CONFIG_REMOTE_WAKEUP) {
//
// This configuration supports remote wakeup
//
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO,
("ConfigureUsbDevice: Remote Wakeup Enabled.\n"));
DevExt->WaitWakeEnable = TRUE;
} else {
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO,
("ConfigureUsbDevice: Remote Wakeup Disabled.\n"));
DevExt->WaitWakeEnable = FALSE;
}
//
// Select the interface(s) that we are going to use to communicate with the device.
//
status = SelectUsbInterfaces(DevExt, configurationDescriptor);
//
// And also determine the speed at which the device is running
//
DetermineDeviceSpeed(DevExt);
} else {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
("ConfigureUsbDevice: Failed to allocate configuration descriptor.\n"));
DevExt->UsbConfigurationDescriptor = NULL;
}
//
// Cleanup memory and exit.
//
ConfigureDevice_Exit:
if(urb) {
ExFreePool(urb);
}
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ConfigureUsbDevice: Exit\n"));
return status;
}
///////////////////////////////////////////////////////////////////////////////
//
// SelectUsbInterfaces
//
// This routine is called by ConfigureUsbDevice to read the USB
// select the interfaces that will be used to talk to the usb device.
//
//
// INPUTS:
//
// DevExt - Address of the Devices Device Extension.
// ConfigurationDescriptor - Address of the Configuration Descriptor
// selected.
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// None
//
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -