?? usblspnp.c
字號:
}
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// All PNP_POWER messages get passed to the TopOfStackDeviceObject
// we were given in PnPAddDevice
//
USBLS120_KdPrint( DBGLVL_MAXIMUM,("USBLS120_ProcessPnPIrp() Passing PnP Irp down, status = %x\n", ntStatus));
ntStatus = IoCallDriver(stackDeviceObject, Irp);
USBLS120_DecrementIoCount(DeviceObject);
USBLS120_KdPrint( DBGLVL_MAXIMUM,("USBLS120_ProcessPnPIrp() Exit USBLS120_ProcessPnPIrp %x\n", ntStatus));
return ntStatus;
}
NTSTATUS
USBLS120_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 BulkUsb
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;
USBD_VERSION_INFORMATION versionInformation;
ULONG i;
USBLS120_KdPrint( DBGLVL_DEFAULT,("enter USBLS120_PnPAddDevice()\n"));
//
// create our funtional device object (FDO)
//
ntStatus =
USBLS120_CreateDeviceObject(DriverObject, PhysicalDeviceObject, &deviceObject);
if (NT_SUCCESS(ntStatus)) {
deviceExtension = deviceObject->DeviceExtension;
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//
// we do not support direct io for read/write
//
// deviceObject->Flags |= DO_DIRECT_IO;
// Storage devices are flushed by VPOWERED shortly after resuming
// from a standby. This means we can get I/O requests after resume
// even if the device was removed while we were suspended. To avoid
// this we will *not* set the DO_POWER_PAGABLE flag. This is
// interpreted by Win98 as meaning we only support D0, and will
// cause our driver to be removed during suspend, and reloaded
// after resume.
// 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);
// Initialize the DPC we use to schedule data transfers to/from the device
deviceExtension->TransferDataDpc = (PRKDPC)USBLS120_ExAllocatePool(
NonPagedPool,
sizeof(KDPC)
);
KeInitializeDpc(
deviceExtension->TransferDataDpc,
USBLS120_TransferDataDPC,
NULL
);
// 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.
USBLS120_QueryCapabilities(PhysicalDeviceObject,
&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];
}
#if DBG
// May want override auto power-down level from registry;
// ( CurrentControlSet\Services\BulkUsb\Parameters )
// Setting to 0 or 1 in registry disables auto power-down
USBLS120_GetRegistryDword( USBLS120_REGISTRY_PARAMETERS_PATH,
L"PowerDownLevel",
&(deviceExtension->PowerDownLevel)
);
//
// display the device caps
//
USBLS120_KdPrint( DBGLVL_MEDIUM,(" >>>>>> DeviceCaps\n"));
USBLS120_KdPrint( DBGLVL_MEDIUM,(" SystemWake = %s\n",
USBLS120_StringForSysState( deviceExtension->DeviceCapabilities.SystemWake ) ));
USBLS120_KdPrint( DBGLVL_MEDIUM,(" DeviceWake = %s\n",
USBLS120_StringForDevState( deviceExtension->DeviceCapabilities.DeviceWake) ));
for (i=PowerSystemUnspecified; i< PowerSystemMaximum; i++) {
USBLS120_KdPrint( DBGLVL_MEDIUM,(" Device State Map: sysstate %s = devstate %s\n",
USBLS120_StringForSysState( i ),
USBLS120_StringForDevState( deviceExtension->DeviceCapabilities.DeviceState[i] ) ));
}
USBLS120_KdPrint( DBGLVL_MEDIUM,(" <<<<<<<<DeviceCaps\n"));
#endif
// 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
//
USBLS120_IncrementIoCount(deviceObject);
}
USBD_GetUSBDIVersion(&versionInformation);
if( NT_SUCCESS( ntStatus ) )
{
NTSTATUS actStat;
// try to power down device until IO actually requested
actStat = USBLS120_SelfSuspendOrActivate( deviceObject, TRUE );
}
USBLS120_KdPrint( DBGLVL_DEFAULT,("exit USBLS120_PnPAddDevice() (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
USBLS120_StartDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Called from USBLS120_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;
USBLS120_KdPrint( DBGLVL_DEFAULT,("enter USBLS120_StartDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
urb = USBLS120_ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
USBLS120_KdPrintCond( DBGLVL_HIGH,!urb, ("USBLS120_StartDevice() FAILED USBLS120_ExAllocatePool() for URB\n"));
if (urb) {
siz = sizeof(USB_DEVICE_DESCRIPTOR);
deviceDescriptor = USBLS120_ExAllocatePool(NonPagedPool, siz);
USBLS120_KdPrintCond( DBGLVL_HIGH, !deviceDescriptor, ("USBLS120_StartDevice() FAILED USBLS120_ExAllocatePool() for deviceDescriptor\n"));
if (deviceDescriptor) {
UsbBuildGetDescriptorRequest(urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0,
deviceDescriptor,
NULL,
siz,
NULL
);
ntStatus = USBLS120_CallUSBD(DeviceObject, urb);
USBLS120_KdPrintCond( DBGLVL_DEFAULT, !NT_SUCCESS(ntStatus), ("USBLS120_StartDevice() FAILED USBLS120_CallUSBD(DeviceObject, urb)\n"));
if (NT_SUCCESS(ntStatus)) {
USBLS120_KdPrint( DBGLVL_MEDIUM,("Device Descriptor = %x, len %x\n",
deviceDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength)
);
USBLS120_KdPrint( DBGLVL_MEDIUM,("USB Mass Storage Device Descriptor:\n"));
USBLS120_KdPrint( DBGLVL_MEDIUM,("-----------------------------------\n"));
USBLS120_KdPrint( DBGLVL_MEDIUM,("bLength %d\n", deviceDescriptor->bLength));
USBLS120_KdPrint( DBGLVL_MEDIUM,("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
USBLS120_KdPrint( DBGLVL_MEDIUM,("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
USBLS120_KdPrint( DBGLVL_MEDIUM,("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
USBLS120_KdPrint( DBGLVL_MEDIUM,("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
USBLS120_KdPrint( DBGLVL_MEDIUM,("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
USBLS120_KdPrint( DBGLVL_MEDIUM,("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
USBLS120_KdPrint( DBGLVL_MEDIUM,("idVendor 0x%x\n", deviceDescriptor->idVendor));
USBLS120_KdPrint( DBGLVL_MEDIUM,("idProduct 0x%x\n", deviceDescriptor->idProduct));
USBLS120_KdPrint( DBGLVL_MEDIUM,("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
USBLS120_KdPrint( DBGLVL_MEDIUM,("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
USBLS120_KdPrint( DBGLVL_MEDIUM,("iProduct 0x%x\n", deviceDescriptor->iProduct));
USBLS120_KdPrint( DBGLVL_MEDIUM,("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
USBLS120_KdPrint( DBGLVL_MEDIUM,("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) {
USBLS120_ExFreePool(deviceDescriptor);
}
USBLS120_ExFreePool(urb);
}
else {
// if we got here we failed to allocate the urb
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus)) {
ntStatus = USBLS120_ConfigureDevice(DeviceObject);
USBLS120_KdPrintCond( DBGLVL_MEDIUM,!NT_SUCCESS(ntStatus),("USBLS120_StartDevice USBLS120_ConfigureDevice() FAILURE (%x)\n", ntStatus));
}
//USBLS120_StartInterruptPipe(DeviceObject);
if (NT_SUCCESS(ntStatus)) {
deviceExtension->DeviceStarted = TRUE;
}
USBLS120_KdPrint( DBGLVL_DEFAULT, ("exit USBLS120_StartDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
USBLS120_RemoveDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Called from USBLS120_ProcessPnPIrp() to
clean up our device instance's allocated buffers; free symbolic links
Arguments:
DeviceObject - pointer to the FDO
Return Value:
NT status code from free symbolic link operation
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING deviceLinkUnicodeString;
USBLS120_KdPrint( DBGLVL_DEFAULT,("enter USBLS120_RemoveDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
//
// Free device descriptor structure
//
if (deviceExtension->UsbDeviceDescriptor) {
USBLS120_ExFreePool(deviceExtension->UsbDeviceDescriptor);
}
//
// Free up the UsbInterface structure
//
if (deviceExtension->UsbInterface) {
USBLS120_ExFreePool(deviceExtension->UsbInterface);
}
// free up the USB config discriptor
if (deviceExtension->UsbConfigurationDescriptor) {
USBLS120_ExFreePool(deviceExtension->UsbConfigurationDescriptor);
}
// free the data transfer DPC
if (deviceExtension->TransferDataDpc) {
USBLS120_ExFreePool(deviceExtension->TransferDataDpc);
}
USBLS120_ASSERT( gExAllocCount == 0 );
USBLS120_KdPrint( DBGLVL_HIGH,("exit USBLS120_RemoveDevice() gExAllocCount = dec %d\n", gExAllocCount ));
USBLS120_KdPrint( DBGLVL_DEFAULT,("exit USBLS120_RemoveDevice() status = 0x%x\n", ntStatus ));
return ntStatus;
}
NTSTATUS
USBLS120_StopDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Stops a given instance of a USB LS-120 device on the USB.
We basically just tell USB this device is now 'unconfigured'
Arguments:
DeviceObject - pointer to the device object for this instance of a USB LS-120
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
ULONG siz;
USBLS120_KdPrint( DBGLVL_DEFAULT,("enter USBLS120_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 = USBLS120_ExAllocatePool(NonPagedPool, siz);
if (urb) {
UsbBuildSelectConfigurationRequest(
urb,
(USHORT) siz,
NULL
);
ntStatus = USBLS120_CallUSBD(DeviceObject, urb);
USBLS120_KdPrintCond( DBGLVL_DEFAULT,!NT_SUCCESS(ntStatus),("USBLS120_StopDevice() FAILURE Configuration Closed status = %x usb status = %x.\n", ntStatus, urb->UrbHeader.Status));
USBLS120_ExFreePool(urb);
}
else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus)) {
deviceExtension->DeviceStarted = FALSE;
}
deviceExtension->StopDeviceRequested = FALSE;
USBLS120_KdPrint( DBGLVL_DEFAULT,("exit USBLS120_StopDevice() (%x)\n", ntStatus));
return ntStatus;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -