?? liubo2004666_ezusbsys.c
字號:
} // if ntStatus is PENDING
goto Ezusb_Dispatch_Done;
Ezusb_Dispatch_Done:
Ezusb_KdPrint (("Exit Ezusb_DispatchPower %x\n", ntStatus));
return ntStatus;
}//Ezusb_DispatchPower
VOID
Ezusb_Unload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
TODO: This is a placeholder for driver writer to add code on unload
Arguments:
DriverObject - pointer to a driver object
Return Value:
None
--*/
{
Ezusb_KdPrint (("enter Ezusb_Unload\n"));
/*
// TODO: Free any global resources allocated in DriverEntry
*/
Ezusb_KdPrint (("exit Ezusb_Unload\n"));
}
NTSTATUS
Ezusb_HandleRemoveDevice(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp
)
{
NTSTATUS ntStatus;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
ULONG i;
// set the removing flag to prevent any new I/O's
pdx->removing = TRUE;
// brute force - send an abort pipe message to all pipes to cancel any
// pending transfers. this should solve the problem of the driver blocking
// on a REMOVE message because there is a pending transfer.
for (i = 0; i < pdx->Interface->NumberOfPipes; i++)
{
Ezusb_AbortPipe(fdo,(USBD_PIPE_HANDLE) pdx->Interface->Pipes[i].PipeHandle);
}
UnlockDevice(fdo); // once for LockDevice at start of dispatch
UnlockDevice(fdo); // once for initialization during AddDevice
KeWaitForSingleObject(&pdx->evRemove, Executive, KernelMode, FALSE, NULL);
Ezusb_RemoveDevice(fdo);
ntStatus = Ezusb_DefaultPnpHandler(fdo, Irp);
return ntStatus; // lower-level completed IoStatus already
}
NTSTATUS
Ezusb_HandleStartDevice(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp
)
{
NTSTATUS ntStatus;
//
// First let all lower-level drivers handle this request.
//
ntStatus = ForwardAndWait(fdo, Irp);
if (!NT_SUCCESS(ntStatus))
return CompleteRequest(Irp, ntStatus, Irp->IoStatus.Information);
//
// now do whatever we need to do to start the device
//
ntStatus = Ezusb_StartDevice(fdo);
return CompleteRequest(Irp, ntStatus, 0);
}
NTSTATUS
Ezusb_StartDevice(
IN PDEVICE_OBJECT fdo
)
/*++
Routine Description:
Initializes a given instance of the Ezusb Device on the USB.
Arguments:
fdo - pointer to the device object for this instance of a
Ezusb Device
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION pdx;
NTSTATUS ntStatus;
PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
PURB urb;
ULONG siz;
Ezusb_KdPrint (("enter Ezusb_StartDevice\n"));
pdx = fdo->DeviceExtension;
pdx->NeedCleanup = TRUE;
/*
// Get some memory from then non paged pool (fixed, locked system memory)
// for use by the USB Request Block (urb) for the specific USB Request we
// will be performing below (a USB device request).
*/
urb = ExAllocatePool( NonPagedPool,
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (urb) {
siz = sizeof(USB_DEVICE_DESCRIPTOR);
// Get some non paged memory for the device descriptor contents
deviceDescriptor = ExAllocatePool(NonPagedPool,
siz);
if (deviceDescriptor) {
// Use a macro in the standard USB header files to build the URB
UsbBuildGetDescriptorRequest(urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0,
deviceDescriptor,
NULL,
siz,
NULL);
// Get the device descriptor
ntStatus = Ezusb_CallUSBD(fdo, urb);
// Dump out the descriptor info to the debugger
if (NT_SUCCESS(ntStatus)) {
Ezusb_KdPrint (("Device Descriptor = %x, len %x\n",
deviceDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength));
Ezusb_KdPrint (("Ezusb Device Descriptor:\n"));
Ezusb_KdPrint (("-------------------------\n"));
Ezusb_KdPrint (("bLength %d\n", deviceDescriptor->bLength));
Ezusb_KdPrint (("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
Ezusb_KdPrint (("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
Ezusb_KdPrint (("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
Ezusb_KdPrint (("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
Ezusb_KdPrint (("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
Ezusb_KdPrint (("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
Ezusb_KdPrint (("idVendor 0x%x\n", deviceDescriptor->idVendor));
Ezusb_KdPrint (("idProduct 0x%x\n", deviceDescriptor->idProduct));
Ezusb_KdPrint (("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
Ezusb_KdPrint (("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
Ezusb_KdPrint (("iProduct 0x%x\n", deviceDescriptor->iProduct));
Ezusb_KdPrint (("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
Ezusb_KdPrint (("bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations));
}
} else {
ntStatus = STATUS_NO_MEMORY;
}
if (NT_SUCCESS(ntStatus)) {
/*
// Put a ptr to the device descriptor in the device extension for easy
// access (like a "cached" copy). We will free this memory when the
// device is removed. See the "Ezusb_RemoveDevice" code.
*/
pdx->DeviceDescriptor = deviceDescriptor;
pdx->Stopped = FALSE;
} else if (deviceDescriptor) {
/*
// If the bus transaction failed, then free up the memory created to hold
// the device descriptor, since the device is probably non-functional
*/
ExFreePool(deviceDescriptor);
pdx->DeviceDescriptor = NULL;
}
ExFreePool(urb);
} else {
// Failed getting memory for the Urb
ntStatus = STATUS_NO_MEMORY;
}
// If the Get_Descriptor call was successful, then configure the device.
if (NT_SUCCESS(ntStatus)) {
ntStatus = Ezusb_ConfigureDevice(fdo);
}
#ifdef DOWNLOAD_KEIL_MONITOR
//
// download the Keil monitor
//
//
// First download loader firmware. The loader firmware implements a vendor
// specific command that will allow us to anchor load to external ram
//
Ezusb_8051Reset(fdo,1);
Ezusb_DownloadIntelHex(fdo,loader);
Ezusb_8051Reset(fdo,0);
//
// Now download the Keil Monitor
//
if (IsFx2(fdo))
{
Ezusb_KdPrint (("**** Downloading FX2 monitor\n"));
Ezusb_DownloadIntelHex(fdo,mon_ext_sio1_fx2);
}
else
{
Ezusb_KdPrint (("**** Downloading EZ-USB monitor\n"));
Ezusb_DownloadIntelHex(fdo,mon_ext_sio1_ezusb);
}
Ezusb_8051Reset(fdo,1);
Ezusb_8051Reset(fdo,0);
#endif // if DOWNLOAD_KEIL_MONITOR
Ezusb_KdPrint (("exit Ezusb_StartDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
Ezusb_RemoveDevice(
IN PDEVICE_OBJECT fdo
)
/*++
Routine Description:
Removes a given instance of a Ezusb Device device on the USB.
Arguments:
fdo - pointer to the device object for this instance of a Ezusb Device
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION pdx;
NTSTATUS ntStatus = STATUS_SUCCESS;
Ezusb_KdPrint (("enter Ezusb_RemoveDevice\n"));
pdx = fdo->DeviceExtension;
if (pdx->DeviceDescriptor)
{
ExFreePool(pdx->DeviceDescriptor);
}
//
// Free up any interface structures in our device extension
//
if (pdx->Interface != NULL)
{
ExFreePool(pdx->Interface);
}
//
// remove the device object's symbolic link
//
if (pdx->NeedCleanup)
{
UNICODE_STRING deviceLinkUnicodeString;
pdx->NeedCleanup = FALSE;
RtlInitUnicodeString (&deviceLinkUnicodeString,
pdx->DeviceLinkNameBuffer);
IoDeleteSymbolicLink(&deviceLinkUnicodeString);
}
IoDetachDevice(pdx->StackDeviceObject);
IoDeleteDevice (fdo);
Ezusb_KdPrint (("exit Ezusb_RemoveDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
Ezusb_StopDevice(
IN PDEVICE_OBJECT fdo
)
/*++
Routine Description:
Stops a given instance of a Ezusb Device device on USB.
Arguments:
fdo - pointer to the device object for this instance of a Ezusb Device
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION pdx;
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
ULONG siz;
Ezusb_KdPrint (("enter Ezusb_StopDevice\n"));
pdx = fdo->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 = ExAllocatePool(NonPagedPool,
siz);
if (urb)
{
NTSTATUS status;
UsbBuildSelectConfigurationRequest(urb,
(USHORT) siz,
NULL);
status = Ezusb_CallUSBD(fdo, urb);
Ezusb_KdPrint (("Device Configuration Closed status = %x usb status = %x.\n",
status, urb->UrbHeader.Status));
ExFreePool(urb);
}
else
{
ntStatus = STATUS_NO_MEMORY;
}
Ezusb_KdPrint (("exit Ezusb_StopDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
Ezusb_PnPAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
/*++
Routine Description:
This routine is called to create a new instance of the device
Arguments:
DriverObject - pointer to the driver object for this instance of Ezusb
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 pdx;
int instance;
Ezusb_KdPrint(("enter Ezusb_PnPAddDevice\n"));
#define MAX_EZUSB_DEVICES 8
//
// create our functional device object (FDO). This driver supports multiple ezusb devices.
// This loop will look for an available instance number. Keep incrementing the instance
// until a call to Ezusb_CreateDeviceObject succeeds.
//
instance = 0;
do
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -