?? d12.c
字號:
// We have the configuration descriptor for the configuration
// we want.
//
// Now we issue the select configuration command to get
// the pipes associated with this configuration.
//
ntStatus = D12_SelectInterface(DeviceObject,
configurationDescriptor, NULL);
ExFreePool(configurationDescriptor);
}
D12_KdPrint (("D12TEST.SYS: exit D12_ConfigureDevice (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
D12_SelectInterface(
IN PDEVICE_OBJECT DeviceObject,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
PUSBD_INTERFACE_INFORMATION Interface
)
/*++
Routine Description:
Initializes an 82930 with multiple interfaces
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
devcice.
ConfigurationDescriptor - pointer to the USB configuration
descriptor containing the interface and endpoint
descriptors.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus;
PURB urb = NULL;
ULONG i;
UCHAR alternateSetting, interfaceNumber;
PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL;
USHORT siz;
D12_KdPrint (("D12TEST.SYS: enter D12_SelectInterface\n"));
deviceExtension = DeviceObject->DeviceExtension;
if (Interface == NULL) {
//
// D12 driver only supports one interface, we must search
// the configuration descriptor for the interface we want
// and remember the pipes.
//
urb = USBD_CreateConfigurationRequest(ConfigurationDescriptor, &siz);
if (urb) {
//
// search thru all the interfaces
// and find any we are interested in
//
interfaceNumber = 0;
alternateSetting = 0;
// alternateSetting = 3;
interfaceDescriptor =
USBD_ParseConfigurationDescriptor(ConfigurationDescriptor,
interfaceNumber,
alternateSetting);
Interface = &urb->UrbSelectConfiguration.Interface;
for (i=0; i< Interface->NumberOfPipes; i++) {
//
// perform any pipe initialization here
//
Interface->Pipes[i].MaximumTransferSize = 64*1024-1;
}
UsbBuildSelectConfigurationRequest(urb,
(USHORT) siz,
ConfigurationDescriptor);
// Interface->AlternateSetting = 3;
ntStatus = D12_CallUSBD(DeviceObject, urb);
deviceExtension->ConfigurationHandle =
urb->UrbSelectConfiguration.ConfigurationHandle;
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
} else {
//
// we were give an interface already set up
//
// do a selectinterface here if we want to change any of the
// pipe parameters.
//
TRAP();
}
ASSERT(Interface != NULL);
if (NT_SUCCESS(ntStatus)) {
//
// Save the configuration handle for this device
//
deviceExtension->ConfigurationHandle =
urb->UrbSelectConfiguration.ConfigurationHandle;
deviceExtension->Interface = ExAllocatePool(NonPagedPool,
Interface->Length);
if (deviceExtension->Interface) {
ULONG j;
//
// save a copy of the interface information returned
//
RtlCopyMemory(deviceExtension->Interface, Interface, Interface->Length);
//
// Dump the interface to the debugger
//
D12_KdPrint (("D12TEST.SYS: ---------\n"));
D12_KdPrint (("D12TEST.SYS: NumberOfPipes 0x%x\n", deviceExtension->Interface->NumberOfPipes));
D12_KdPrint (("D12TEST.SYS: Length 0x%x\n", deviceExtension->Interface->Length));
D12_KdPrint (("D12TEST.SYS: Alt Setting 0x%x\n", deviceExtension->Interface->AlternateSetting));
D12_KdPrint (("D12TEST.SYS: Interface Number 0x%x\n", deviceExtension->Interface->InterfaceNumber));
D12_KdPrint (("D12TEST.SYS: Class, subclass, protocol 0x%x 0x%x 0x%x\n",
deviceExtension->Interface->Class,
deviceExtension->Interface->SubClass,
deviceExtension->Interface->Protocol));
// Dump the pipe info
for (j=0; j<Interface->NumberOfPipes; j++) {
PUSBD_PIPE_INFORMATION pipeInformation;
pipeInformation = &deviceExtension->Interface->Pipes[j];
D12_KdPrint (("D12TEST.SYS: ---------\n"));
D12_KdPrint (("D12TEST.SYS: PipeType 0x%x\n", pipeInformation->PipeType));
D12_KdPrint (("D12TEST.SYS: EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
D12_KdPrint (("D12TEST.SYS: MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
D12_KdPrint (("D12TEST.SYS: Interval 0x%x\n", pipeInformation->Interval));
D12_KdPrint (("D12TEST.SYS: Handle 0x%x\n", pipeInformation->PipeHandle));
D12_KdPrint (("D12TEST.SYS: MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
}
D12_KdPrint (("D12TEST.SYS: ---------\n"));
}
}
if (urb) {
ExFreePool(urb);
urb = NULL;
}
// Retrieve the selected Configuration and Interface setting from the
// device. (The only purpose of doing this here is to exercise the
// URB_FUNCTION_GET_CONFIGURATION and URB_FUNCTION_GET_INTERFACE
// requests).
//
if (NT_SUCCESS(ntStatus)) {
urb = ExAllocatePool(
NonPagedPool,
sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST) + 1);
if (urb)
{
PUCHAR configuration;
configuration = (PUCHAR)urb + sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST);
*configuration = 0xFF;
urb->UrbHeader.Function = URB_FUNCTION_GET_CONFIGURATION;
urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_GET_CONFIGURATION_REQUEST);
urb->UrbControlGetConfigurationRequest.TransferBufferLength = 1;
urb->UrbControlGetConfigurationRequest.TransferBuffer = configuration;
urb->UrbControlGetConfigurationRequest.TransferBufferMDL = NULL;
urb->UrbControlGetConfigurationRequest.UrbLink = NULL;
ntStatus = D12_CallUSBD(DeviceObject, urb);
D12_KdPrint (("D12TEST.SYS: Configuration %d (%x)\n",
*configuration, ntStatus));
ExFreePool(urb);
urb = NULL;
}
urb = ExAllocatePool(
NonPagedPool,
sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST) + 1);
if (urb)
{
PUCHAR interface;
interface = (PUCHAR)urb + sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST);
*interface = 0xFF;
urb->UrbHeader.Function = URB_FUNCTION_GET_INTERFACE;
urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_GET_INTERFACE_REQUEST);
urb->UrbControlGetInterfaceRequest.TransferBufferLength = 1;
urb->UrbControlGetInterfaceRequest.TransferBuffer = interface;
urb->UrbControlGetInterfaceRequest.TransferBufferMDL = NULL;
urb->UrbControlGetInterfaceRequest.UrbLink = NULL;
urb->UrbControlGetInterfaceRequest.Interface =
deviceExtension->Interface->InterfaceNumber;
ntStatus = D12_CallUSBD(DeviceObject, urb);
D12_KdPrint (("D12TEST.SYS: Interface %d (%x)\n",
*interface, ntStatus));
ExFreePool(urb);
urb = NULL;
}
}
D12_KdPrint (("D12TEST.SYS: exit D12_SelectInterface (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
D12_BuildPipeList(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
devcice.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
ULONG i;
WCHAR Name[] = L"\\PIPE00";
PUSBD_INTERFACE_INFORMATION interface;
deviceExtension = DeviceObject->DeviceExtension;
interface = deviceExtension->Interface;
D12_KdPrint (("D12TEST.SYS: enter D12_BuildPipeList\n"));
deviceExtension = DeviceObject->DeviceExtension;
for (i=0; i<D12_MAX_PIPES; i++) {
Name[6] = 'X';
RtlCopyMemory(deviceExtension->PipeList[i].Name,
Name,
sizeof(Name));
}
//
// build a list of pipe names based on the interface
//
for (i=0; i<interface->NumberOfPipes; i++) {
Name[6] = '0' + (USHORT) i;
RtlCopyMemory(deviceExtension->PipeList[i].Name,
Name,
sizeof(Name));
deviceExtension->PipeList[i].PipeInfo =
&interface->Pipes[i];
deviceExtension->PipeList[i].Opened = FALSE;
}
return STATUS_SUCCESS;
}
NTSTATUS
D12_ResetPipe(
IN PDEVICE_OBJECT DeviceObject,
IN PD12_PIPE Pipe,
IN BOOLEAN IsoClearStall
)
/*++
Routine Description:
Reset a given USB pipe.
NOTES:
This will reset the host to Data0 and should also reset the device
to Data0 for Bulk and Interrupt pipes.
For Iso pipes this will set the virgin state of pipe so that ASAP
transfers begin with the current bus frame instead of the next frame
after the last transfer occurred.
Arguments:
Return Value:
--*/
{
NTSTATUS ntStatus;
PURB urb;
D12_KdPrint (("D12TEST.SYS: Reset Pipe %x\n", Pipe));
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_PIPE_REQUEST));
if (urb) {
urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
urb->UrbPipeRequest.PipeHandle =
Pipe->PipeInfo->PipeHandle;
ntStatus = D12_CallUSBD(DeviceObject, urb);
ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
//
// Memphis RESET_PIPE will send a Clear-Feature Endpoint Stall to
// reset the data toggle of non-Iso pipes as part of a RESET_PIPE
// request. It does not do this for Iso pipes as Iso pipes do not use
// the data toggle (all Iso packets are Data0). However, we also use
// the Clear-Feature Endpoint Stall request in our device firmware to
// reset data buffer points inside the device so we explicitly send
// this request to the device for Iso pipes if desired.
//
if (NT_SUCCESS(ntStatus) && IsoClearStall &&
(Pipe->PipeInfo->PipeType == UsbdPipeTypeIsochronous)) {
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_FEATURE_REQUEST));
if (urb) {
UsbBuildFeatureRequest(urb,
URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,
USB_FEATURE_ENDPOINT_STALL,
Pipe->PipeInfo->EndpointAddress,
NULL);
ntStatus = D12_CallUSBD(DeviceObject, urb);
ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
return ntStatus;
}
LONG
D12_DecrementIoCount(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PDEVICE_EXTENSION deviceExtension;
LONG ioCount;
deviceExtension = DeviceObject->DeviceExtension;
ioCount = InterlockedDecrement(&deviceExtension->PendingIoCount);
D12_KdPrint (("D12TEST.SYS: Pending io count = %x\n", ioCount));
if (ioCount==0) {
KeSetEvent(&deviceExtension->RemoveEvent,
1,
FALSE);
}
return ioCount;
}
VOID
D12_IncrementIoCount(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PDEVICE_EXTENSION deviceExtension;
deviceExtension = DeviceObject->DeviceExtension;
InterlockedIncrement(&deviceExtension->PendingIoCount);
}
NTSTATUS
D12_ReconfigureDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Initializes a given instance of the device on the USB and selects the
configuration.
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
devcice.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
PUSBD_INTERFACE_INFORMATION interface;
ULONG i;
D12_KdPrint (("D12TEST.SYS: enter D12_ReconfigureDevice\n"));
deviceExtension = DeviceObject->DeviceExtension;
if (NT_SUCCESS(ntStatus)) {
ntStatus = D12_ConfigureDevice(DeviceObject);
}
//
// new interface structure is now set up
//
interface = deviceExtension->Interface;
//
// set up the pipe handles again
//
for (i=0; i<interface->NumberOfPipes; i++) {
D12_KdPrint (("D12TEST.SYS: pipe list = %x\n", &deviceExtension->PipeList[i]));
deviceExtension->PipeList[i].PipeInfo =
&interface->Pipes[i];
//deviceExtension->PipeList[i].Opened = FALSE;
}
return ntStatus;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -