📄 usb.c
字号:
NULL);
ntStatus = USB_CallUSBD(DeviceObject, urb);
USB_KdPrintCond( DBGLVL_DEFAULT, !NT_SUCCESS(ntStatus), ("USB_StartDevice() FAILED USB_CallUSBD(DeviceObject, urb)\n"));
if (NT_SUCCESS(ntStatus)) {
USB_KdPrint( DBGLVL_DEFAULT,("Device Descriptor = %x, len %x\n",
deviceDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength));
//USB_KdPrint( DBGLVL_DEFAULT, ("exit USB_StartDevice (%x)\n", ntStatus));
USB_KdPrint( DBGLVL_DEFAULT,("I68001 Device Descriptor:\n"));
USB_KdPrint( DBGLVL_DEFAULT,("-------------------------\n"));
USB_KdPrint( DBGLVL_DEFAULT,("bLength %d\n", deviceDescriptor->bLength));
USB_KdPrint( DBGLVL_DEFAULT,("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
USB_KdPrint( DBGLVL_DEFAULT,("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
USB_KdPrint( DBGLVL_DEFAULT,("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
USB_KdPrint( DBGLVL_DEFAULT,("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
USB_KdPrint( DBGLVL_DEFAULT,("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
USB_KdPrint( DBGLVL_DEFAULT,("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
USB_KdPrint( DBGLVL_DEFAULT,("idVendor 0x%x\n", deviceDescriptor->idVendor));
USB_KdPrint( DBGLVL_DEFAULT,("idProduct 0x%x\n", deviceDescriptor->idProduct));
USB_KdPrint( DBGLVL_DEFAULT,("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
USB_KdPrint( DBGLVL_DEFAULT,("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
USB_KdPrint( DBGLVL_DEFAULT,("iProduct 0x%x\n", deviceDescriptor->iProduct));
USB_KdPrint( DBGLVL_DEFAULT,("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
USB_KdPrint( DBGLVL_DEFAULT,("bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations));
}
} else {
// if we got here we failed to allocate deviceDescriptor
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus)) {
deviceExtension->UsbDeviceDescriptor = deviceDescriptor;
} else if (deviceDescriptor) {
USB_ExFreePool(deviceDescriptor);
}
USB_ExFreePool(urb);
} else {
// if we got here we failed to allocate the urb
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus)) {
ntStatus = USB_ConfigureDevice(DeviceObject);
USB_KdPrintCond( DBGLVL_DEFAULT,!NT_SUCCESS(ntStatus),("USB_StartDevice USB_ConfigureDevice() FAILURE (%x)\n", ntStatus));
}
if (NT_SUCCESS(ntStatus)) {
deviceExtension->DeviceStarted = TRUE;
}
USB_KdPrint( DBGLVL_DEFAULT, ("exit USB_StartDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
USB_RemoveDevice(
IN PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING deviceLinkUnicodeString;
USB_KdPrint( DBGLVL_DEFAULT,("enter USB_RemoveDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
RtlInitUnicodeString (&deviceLinkUnicodeString,
deviceExtension->DeviceLinkNameBuffer);
// remove the GUID-based symbolic link
ntStatus = IoSetDeviceInterfaceState(&deviceLinkUnicodeString, FALSE);
USB_ASSERT( NT_SUCCESS( ntStatus ) );
//
// Free device descriptor structure
//
if (deviceExtension->UsbDeviceDescriptor) {
USB_ExFreePool(deviceExtension->UsbDeviceDescriptor);
deviceExtension->UsbDeviceDescriptor = NULL;
}
//
// Free pipe info structs
//
if( deviceExtension->PipeInfo ) {
USB_ExFreePool( deviceExtension->PipeInfo );
deviceExtension->PipeInfo = NULL;
}
//
// Free up the UsbInterface structure
//
if (deviceExtension->UsbInterface) {
USB_ExFreePool(deviceExtension->UsbInterface);
deviceExtension->UsbInterface = NULL;
}
// free up the USB config discriptor
if (deviceExtension->UsbConfigurationDescriptor) {
USB_ExFreePool(deviceExtension->UsbConfigurationDescriptor);
deviceExtension->UsbConfigurationDescriptor = NULL;
}
// free the pending irp list
if ( deviceExtension->PendingIoIrps ) {
USB_ExFreePool(deviceExtension->PendingIoIrps );
deviceExtension->PendingIoIrps = NULL;
}
USB_ASSERT( gExAllocCount == 0 );
USB_KdPrint( DBGLVL_HIGH,("exit USB_RemoveDevice() gExAllocCount = dec %d\n", gExAllocCount ));
USB_KdPrint( DBGLVL_DEFAULT,("exit USB_RemoveDevice() status = 0x%x\n", ntStatus ));
return ntStatus;
}
NTSTATUS
USB_StopDevice(
IN PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
ULONG siz;
USB_KdPrint( DBGLVL_DEFAULT,("enter USB_StopDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
//
// Send the select configuration urb with a NULL pointer for the configuration
// handle. This closes the configuration and puts the device in the 'unconfigured'
// state.
//
siz = sizeof(struct _URB_SELECT_CONFIGURATION);
urb = USB_ExAllocatePool(NonPagedPool,
siz);
if (urb) {
UsbBuildSelectConfigurationRequest(urb,
(USHORT) siz,
NULL);
ntStatus = USB_CallUSBD(DeviceObject, urb);
USB_KdPrintCond( DBGLVL_DEFAULT,!NT_SUCCESS(ntStatus),("USB_StopDevice() FAILURE Configuration Closed status = %x usb status = %x.\n", ntStatus, urb->UrbHeader.Status));
USB_ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus)) {
deviceExtension->DeviceStarted = FALSE;
}
deviceExtension->StopDeviceRequested = FALSE;
USB_KdPrint( DBGLVL_DEFAULT,("exit USB_StopDevice() (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
USB_IrpCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PKEVENT event = Context;
// Set the input event
KeSetEvent(event,
1, // Priority increment for waiting thread.
FALSE); // Flag this call is not immediately followed by wait.
return STATUS_MORE_PROCESSING_REQUIRED;
}
//////////////////////////////////////////////////
NTSTATUS
USB_ProcessPowerIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack;
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension;
BOOLEAN fGoingToD0 = FALSE;
POWER_STATE sysPowerState, desiredDevicePowerState;
KEVENT event;
USB_KdPrint( DBGLVL_MEDIUM,(" USB_ProcessPowerIrp() IRP_MJ_POWER\n"));
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation (Irp);
USB_IncrementIoCount(DeviceObject);
switch (irpStack->MinorFunction) {
case IRP_MN_WAIT_WAKE:
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Enter IRP_MN_WAIT_WAKE\n"));
deviceExtension->PowerDownLevel = deviceExtension->DeviceCapabilities.DeviceWake;
if ( ( PowerDeviceD0 == deviceExtension->CurrentDevicePowerState ) ||
( deviceExtension->DeviceCapabilities.DeviceWake > deviceExtension->CurrentDevicePowerState ) ) {
ntStatus = STATUS_INVALID_DEVICE_STATE;
Irp->IoStatus.Status = ntStatus;
IoCompleteRequest (Irp,IO_NO_INCREMENT );
USB_KdPrint( DBGLVL_HIGH, ( "Exit USB_ProcessPowerIrp(), ntStatus STATUS_INVALID_DEVICE_STATE\n" ) );
USB_DecrementIoCount(DeviceObject);
return ntStatus;
}
// flag we're enabled for wakeup
deviceExtension->EnabledForWakeup = TRUE;
// init an event for our completion routine to signal when PDO is done with this Irp
KeInitializeEvent(&event, NotificationEvent, FALSE);
// If not failing outright, pass this on to our PDO for further handling
IoCopyCurrentIrpStackLocationToNext(Irp);
// Set a completion routine so it can signal our event when
// the PDO is done with the Irp
IoSetCompletionRoutine(Irp,
USB_IrpCompletionRoutine,
&event, // pass the event to the completion routine as the Context
TRUE, // invoke on success
TRUE, // invoke on error
TRUE); // invoke on cancellation
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
// if PDO is not done yet, wait for the event to be set in our completion routine
if (ntStatus == STATUS_PENDING) {
// wait for irp to complete
NTSTATUS waitStatus = KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() done waiting for PDO to finish IRP_MN_WAIT_WAKE\n"));
}
// now tell the device to actually wake up
//=====USB_SelfSuspendOrActivate( DeviceObject, FALSE );
// flag we're done with wakeup irp
deviceExtension->EnabledForWakeup = FALSE;
USB_DecrementIoCount(DeviceObject);
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Exit IRP_MN_WAIT_WAKE\n"));
break;
case IRP_MN_SET_POWER:
{
// The system power policy manager sends this IRP to set the system power state.
// A device power policy manager sends this IRP to set the device power state for a device.
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Enter IRP_MN_SET_POWER\n"));
// Set Irp->IoStatus.Status to STATUS_SUCCESS to indicate that the device
// has entered the requested state. Drivers cannot fail this IRP.
switch (irpStack->Parameters.Power.Type) {
case SystemPowerState:
// Get input system power state
sysPowerState.SystemState = irpStack->Parameters.Power.State.SystemState;
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Set Power, type SystemPowerState = %s\n",
USB_StringForSysState( sysPowerState.SystemState ) ));
// If system is in working state always set our device to D0
// regardless of the wait state or system-to-device state power map
if ( sysPowerState.SystemState == PowerSystemWorking) {
desiredDevicePowerState.DeviceState = PowerDeviceD0;
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() PowerSystemWorking, will set D0, not use state map\n"));
} else {
// set to corresponding system state if IRP_MN_WAIT_WAKE pending
if ( deviceExtension->EnabledForWakeup ) { // got a WAIT_WAKE IRP pending?
// Find the device power state equivalent to the given system state.
// We get this info from the DEVICE_CAPABILITIES struct in our device
// extension (initialized in USB_PnPAddDevice() )
desiredDevicePowerState.DeviceState =
deviceExtension->DeviceCapabilities.DeviceState[ sysPowerState.SystemState ];
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() IRP_MN_WAIT_WAKE pending, will use state map\n"));
} else {
// if no wait pending and the system's not in working state, just turn off
desiredDevicePowerState.DeviceState = PowerDeviceD3;
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Not EnabledForWakeup and the system's not in working state,\n settting PowerDeviceD3 (off )\n"));
}
}
//
// We've determined the desired device state; are we already in this state?
//
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Set Power, desiredDevicePowerState = %s\n",
USB_StringForDevState( desiredDevicePowerState.DeviceState ) ));
if (desiredDevicePowerState.DeviceState !=
deviceExtension->CurrentDevicePowerState) {
// USB_IncrementIoCount(DeviceObject);
// No, request that we be put into this state
// by requesting a new Power Irp from the Pnp manager
deviceExtension->PowerIrp = Irp;
ntStatus = PoRequestPowerIrp(deviceExtension->PhysicalDeviceObject,
IRP_MN_SET_POWER,
desiredDevicePowerState,
// completion routine will pass the Irp down to the PDO
USB_PoRequestCompletion,
DeviceObject,
NULL);
} else {
// Yes, just pass it on to PDO (Physical Device Object)
IoCopyCurrentIrpStackLocationToNext(Irp);
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
USB_DecrementIoCount(DeviceObject);
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Exit IRP_MN_SET_POWER\n"));
}
break;
case DevicePowerState:
USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Set Power, type DevicePowerState = %s\n",
USB_StringForDevState( irpStack->Parameters.Power.State.DeviceState ) ));
fGoingToD0 = USB_SetDevicePowerState(DeviceObject,
irpStack->Parameters.Power.State.DeviceState
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -