📄 pnp.c
字号:
NTSTATUS
UsbCom_PnPAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
/*++
Routine Description:
This routine is called to create and initialize our Functional Device Object (FDO).
For monolithic drivers, this is done in DriverEntry(), but Plug and Play devices
wait for a PnP event
Arguments:
DriverObject - pointer to the driver object for this instance of UsbCom
PhysicalDeviceObject - pointer to a device object created by the bus
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
PDEVICE_EXTENSION deviceExtension;
PURB Urb;
PIRP Irp;
CHAR StackSize;
ULONG UrbSize;
//USBD_VERSION_INFORMATION versionInformation;
ULONG i;
DbgPrint("enter UsbCom_PnPAddDevice()\n");
GlobalPdaCount = 0;
if(GlobalPdaCount) {
DbgPrint("Can not support one more PDA!!\n");
return STATUS_NOT_SUPPORTED;
}
GlobalPdaCount = 1;
//
// create our funtional device object (FDO)
//
ntStatus =
UsbCom_CreateDeviceObject(DriverObject, PhysicalDeviceObject, &deviceObject);
if (NT_SUCCESS(ntStatus)) {
deviceExtension = deviceObject->DeviceExtension;
deviceExtension->DeviceObject = deviceObject;
//
// we support direct io for read/write
//
deviceObject->Flags |= DO_BUFFERED_IO;
//Set this flag causes the driver to not receive a IRP_MN_STOP_DEVICE
//during suspend and also not get an IRP_MN_START_DEVICE during resume.
//This is neccesary because during the start device call,
// the GetDescriptors() call will be failed by the USB stack.
deviceObject->Flags |= DO_POWER_PAGABLE;
// initialize our device extension
//
// remember the Physical device Object
//
deviceExtension->PhysicalDeviceObject=PhysicalDeviceObject;
//
// Attach to the PDO
//
deviceExtension->TopOfStackDeviceObject =
IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);
// Get a copy of the physical device's capabilities into a
// DEVICE_CAPABILITIES struct in our device extension;
// We are most interested in learning which system power states
// are to be mapped to which device power states for handling
// IRP_MJ_SET_POWER Irps.
UsbCom_QueryCapabilities(deviceExtension->TopOfStackDeviceObject,
&deviceExtension->DeviceCapabilities);
// We want to determine what level to auto-powerdown to; This is the lowest
// sleeping level that is LESS than D3;
// If all are set to D3, auto powerdown/powerup will be disabled.
deviceExtension->PowerDownLevel = PowerDeviceUnspecified; // init to disabled
for (i=PowerSystemSleeping1; i<= PowerSystemSleeping3; i++) {
if ( deviceExtension->DeviceCapabilities.DeviceState[i] < PowerDeviceD3 )
deviceExtension->PowerDownLevel = deviceExtension->DeviceCapabilities.DeviceState[i];
}
// We keep a pending IO count ( extension->PendingIoCount ) in the device extension.
// The first increment of this count is done on adding the device.
// Subsequently, the count is incremented for each new IRP received and
// decremented when each IRP is completed or passed on.
// Transition to 'one' therefore indicates no IO is pending and signals
// deviceExtension->NoPendingIoEvent. This is needed for processing
// IRP_MN_QUERY_REMOVE_DEVICE
// Transition to 'zero' signals an event ( deviceExtension->RemoveEvent )
// to enable device removal. This is used in processing for IRP_MN_REMOVE_DEVICE
//
UsbCom_IncrementIoCount(deviceObject);
// Allocate IRP for our I/O request
Irp = NULL;
StackSize = (CCHAR)(deviceExtension->TopOfStackDeviceObject->StackSize + 1);
Irp = IoAllocateIrp(StackSize, FALSE);
if (!Irp) {
DbgPrint("Failure due to memory error\n");
// Can't allocate IRP - complete request with error and return
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorProcess;
}
// Allocate URB. It will be reused for the data transfer, so insure
// it is large enough for both control and bulk transfers
UrbSize = max(sizeof (struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER) );
Urb = NULL;
Urb = ExAllocatePool(NonPagedPool, UrbSize);
if (!Urb) {
DbgPrint("Failure due to memory error\n");
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorProcess;
}
// Store all the transfer request info in our device extension
deviceExtension->ReadingUrb = Urb;
deviceExtension->ReadingIrp = Irp;
deviceExtension->readpending = FALSE;
// Allocate IRP for our I/O request
Irp = NULL;
StackSize = (CCHAR)(deviceExtension->TopOfStackDeviceObject->StackSize + 1);
Irp = IoAllocateIrp(StackSize, FALSE);
if (!Irp) {
DbgPrint("Failure due to memory error -- Allocate Irp for WRITE_REQUEST\n");
// Can't allocate IRP - complete request with error and return
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorProcess;
}
// Allocate URB. It will be reused for the data transfer, so insure
// it is large enough for both control and bulk transfers
UrbSize = max(sizeof (struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER) );
Urb = NULL;
Urb = ExAllocatePool(NonPagedPool, UrbSize);
if (!Urb) {
DbgPrint("Failure due to memory error -- Allocate Urb for WRITE_REQUEST\n");
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorProcess;
}
// Store all the transfer request info in our device extension
deviceExtension->WritingUrb = Urb;
deviceExtension->WritingIrp = Irp;
deviceExtension->writepending = FALSE;
// Henry-------------------------------------------------------------------//
// Allocate IRP for our I/O request
Irp = NULL;
StackSize = (CCHAR)(deviceExtension->TopOfStackDeviceObject->StackSize + 1);
Irp = IoAllocateIrp(StackSize, FALSE);
if (!Irp) {
DbgPrint("Failure due to memory error -- Allocate Irp for WRITE_REQUEST\n");
// Can't allocate IRP - complete request with error and return
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorProcess;
}
// Allocate URB. It will be reused for the data transfer, so insure
// it is large enough for both control and bulk transfers
UrbSize = sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER);
Urb = NULL;
Urb = ExAllocatePool(NonPagedPool, UrbSize);
if (!Urb) {
DbgPrint("Failure due to memory error -- Allocate Urb for WRITE_REQUEST\n");
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorProcess;
}
// Store all the transfer request info in our device extension
deviceExtension->PollingUrb = Urb;
deviceExtension->PollingIrp = Irp;
deviceExtension->pollpending = FALSE;
} else {
goto ErrorCreate;
}
//USBD_GetUSBDIVersion(&versionInformation);
ErrorProcess:
if( NT_SUCCESS( ntStatus ) )
{
NTSTATUS actStat;
// try to power down device until IO actually requested
actStat = UsbCom_SelfSuspendOrActivate( deviceObject, TRUE );
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
else {
// Error allocating memory.
if(deviceExtension->ReadingUrb)
ExFreePool(deviceExtension->ReadingUrb);
if(deviceExtension->ReadingIrp)
IoFreeIrp(deviceExtension->ReadingIrp);
if(deviceExtension->WritingUrb)
ExFreePool(deviceExtension->ReadingUrb);
if(deviceExtension->WritingIrp)
IoFreeIrp(deviceExtension->ReadingIrp);
if(deviceExtension->PollingUrb)
ExFreePool(deviceExtension->PollingUrb);
if(deviceExtension->PollingIrp)
IoFreeIrp(deviceExtension->PollingIrp);
}
ErrorCreate :
DbgPrint("exit UsbCom_PnPAddDevice() (%x)\n", ntStatus);
return ntStatus;
}
NTSTATUS
UsbCom_StartDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Called from UsbCom_ProcessPnPIrp(), the dispatch routine for IRP_MJ_PNP.
Initializes a given instance of the device on the USB.
USB client drivers such as us set up URBs (USB Request Packets) to send requests
to the host controller driver (HCD). The URB structure defines a format for all
possible commands that can be sent to a USB device.
Here, we request the device descriptor and store it, and configure the device.
Arguments:
DeviceObject - pointer to the FDO (Functional Device Object)
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus;
PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
PURB urb;
ULONG siz;
DbgPrint("enter UsbCom_StartDevice\n");
deviceExtension = DeviceObject->DeviceExtension;
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (urb) {
DbgPrint("UsbCom_StartDevice() SUCCESS ExAllocatePool() for URB_CONTROL_DESCRIPTOR_REQUEST");
siz = sizeof(USB_DEVICE_DESCRIPTOR);
deviceDescriptor = ExAllocatePool(NonPagedPool,
siz);
if (deviceDescriptor) {
DbgPrint("UsbCom_StartDevice() SUCESS ExAllocatePool() for deviceDescriptor\n");
UsbBuildGetDescriptorRequest(urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0,
deviceDescriptor,
NULL,
siz,
NULL);
ntStatus = UsbCom_CallUSBD(DeviceObject, urb);
if (NT_SUCCESS(ntStatus)) {
DbgPrint("Device Descriptor = %x, len 0x%x\n",
deviceDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength);
DbgPrint("I82930 Device Descriptor:\n");
DbgPrint("-------------------------\n");
DbgPrint("bLength %d\n", deviceDescriptor->bLength);
DbgPrint("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType);
DbgPrint("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB);
DbgPrint("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass);
DbgPrint("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass);
DbgPrint("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol);
DbgPrint("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0);
DbgPrint("idVendor 0x%x\n", deviceDescriptor->idVendor);
DbgPrint("idProduct 0x%x\n", deviceDescriptor->idProduct);
DbgPrint("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice);
DbgPrint("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer);
DbgPrint("iProduct 0x%x\n", deviceDescriptor->iProduct);
DbgPrint("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber);
DbgPrint("bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations);
}
} else {
// if we got here we failed to allocate deviceDescriptor
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -