📄 card.c
字号:
//++
//
//Copyright (c) 1998-2001 ASIX Electronics Corporation
//
//Module Name:
// card.c
//
//Abstract:
// Card-specific functions for the NDIS3/NDIS5 ASIX AX88172 driver.
//
//Author:
// William Lee ,August 2000, July 2002,
//
//Environment:
// Kernel mode, FSD
//
//Revision History:
// May-20-2000, Add IRQL change for Wait Mode IoCallDriver
// Jun-13-2000, Dynamic Interrupt Endpoint Assertion for DUAL PHY Support.
//
//--
NTSTATUS
BulkUsb_CallUSBD_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PBULKUSB_RW_CONTEXT context
)
{
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
BulkUsb_WaitIoCall(
IN PAX_ADAPTER Adapter,
IN PVOID Argument1,
IN ULONG IoControlCode
)
{
PIRP irp;
NTSTATUS ntStatus;
PIO_STACK_LOCATION nextStack;
irp = IoAllocateIrp(
(CCHAR)(Adapter->PhysicalDeviceObject->StackSize + 1),
FALSE
);
if (irp == NULL)
return STATUS_UNSUCCESSFUL;
IoSetCompletionRoutine(
irp,
BulkUsb_CallUSBD_Complete,
NULL, // the context array element to completion routine
TRUE, // invoke on success
TRUE, // invoke on error
FALSE // invoke on cancellation of the Irp
);
nextStack = IoGetNextIrpStackLocation(irp);
nextStack->Parameters.Others.Argument1 = Argument1;
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
//
// Call the class driver to perform the operation.
ntStatus = IoCallDriver( Adapter->PhysicalDeviceObject,irp );
// If the returned status is PENDING, wait for the request to complete.
if (ntStatus == STATUS_PENDING)
{
KIRQL OriginalIRQL;
KeRaiseIrql( PASSIVE_LEVEL,&OriginalIRQL );
while( irp->IoStatus.Status == STATUS_PENDING )
NdisStallExecution(100);
KeLowerIrql( OriginalIRQL );
ntStatus = irp->IoStatus.Status;
}
IoFreeIrp(irp);
return ntStatus;
}
NTSTATUS
BulkUsb_CallUSBD(
IN PAX_ADAPTER Adapter,
IN PURB pUrb
)
//++
//
//Routine Description:
// Passes a URB to the USBD class driver
// The client device driver passes USB request block (URB) structures
// to the class driver as a parameter in an IRP with Irp->MajorFunction
// set to IRP_MJ_INTERNAL_DEVICE_CONTROL and the next IRP stack location
// Parameters.DeviceIoControl.IoControlCode field set to
// IOCTL_INTERNAL_USB_SUBMIT_URB.
//
//Arguments:
// Adapter - pointer to the physical device object (PDO)
// pUrb - pointer to an already-formatted Urb request block
//
//Return Value:
// STATUS_SUCCESS if successful,
// STATUS_UNSUCCESSFUL otherwise
//
//--
{
return BulkUsb_WaitIoCall( Adapter,pUrb,IOCTL_INTERNAL_USB_SUBMIT_URB );
}
NTSTATUS
BulkUsb_AsyncTransmit_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PBULKUSB_RW_CONTEXT context
)
//*++
//Routine Description:
// Completion routine for our staged read/write Irps
//
//Arguments:
// DeviceObject - Pointer to the device object for next lower device
// in the driver stack;
//
// Irp - Irp completed.
//
// Adapter - Driver defined context.
//
//Return Value:
// The function value is the final status from the operation.
//
//--*
{
PAX_ADAPTER Adapter = context->Adapter;
PURB pUrb = context->pUrb;
if ( USBD_CANCEL(pUrb->UrbHeader.Status) )
return STATUS_MORE_PROCESSING_REQUIRED;
if ( USBD_HALTED(pUrb->UrbHeader.Status) )
Adapter->HaltEvents |= HaltTransmit;
else
{
ULONG IoCount;
if ( USBD_SUCCESS(pUrb->UrbHeader.Status) )
Adapter->FramesXmitGood++;
else
Adapter->FramesXmitBad++;
NdisAcquireSpinLock( &Adapter->TransmitIoCountSpinLock );
IoCount = NdisInterlockedDecrement(&Adapter->TransmitIoCount);
NdisReleaseSpinLock( &Adapter->TransmitIoCountSpinLock );
if ( IoCount )
BulkUsb_PacketTransmit( Adapter );
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
VOID
BulkUsb_PacketTransmit(
IN PAX_ADAPTER Adapter
)
//*++
//
//Routine Description:
// Breaks up a write in to specified sized chunks,
// as specified by deviceExtension->MaximumTransferSize
//
//Arguments:
//
// Adapter - pointer to our FDO ( Functional Device Object )
//
//--*
{
PBULKUSB_RW_CONTEXT context;
PIO_STACK_LOCATION nextStack;
context = &Adapter->PendingTransmit;
UsbBuildInterruptOrBulkTransferRequest(
context->pUrb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
Adapter->TransmitPipe,
(PUCHAR)Adapter->TransmitBuffer[Adapter->LastTransmit],
NULL,
Adapter->TransmitLength[Adapter->LastTransmit],
USBD_TRANSFER_DIRECTION_OUT, // Write
NULL
);
IoSetCompletionRoutine(
context->irp,
BulkUsb_AsyncTransmit_Complete,
context,
TRUE,TRUE,FALSE
);
nextStack = IoGetNextIrpStackLocation(context->irp);
nextStack->Parameters.Others.Argument1 = context->pUrb;
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
//
// Call the class driver to perform the operation.
if ( NT_SUCCESS(IoCallDriver(Adapter->PhysicalDeviceObject,context->irp)) )
{
if ( Adapter->LastTransmit<(numTransmitQ-1) )
Adapter->LastTransmit++;
else
Adapter->LastTransmit = 0; //turn around
}
else
{
NdisMSetTimer( &Adapter->TransmitTimer,1 );
}
}
NTSTATUS
BulkUsb_AsyncReceive_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PBULKUSB_RW_CONTEXT context
)
//*++
//Routine Description:
// Completion routine for our staged read/write Irps
//
//Arguments:
// DeviceObject - Pointer to the device object for next lower device
// in the driver stack;
//
// Irp - Irp completed.
//
// Context - Driver defined context.
//
//Return Value:
// The function value is the final status from the operation.
//
//--*
{
PURB pUrb = context->pUrb;
PAX_ADAPTER Adapter;
if ( USBD_CANCEL(pUrb->UrbHeader.Status) )
return STATUS_MORE_PROCESSING_REQUIRED;
Adapter = context->Adapter;
if ( USBD_HALTED(pUrb->UrbHeader.Status) )
Adapter->HaltEvents |= HaltReceive;
else
{
if ( USBD_SUCCESS(pUrb->UrbHeader.Status) &&
(pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength>ETH_HEADER_SIZE) )
{
ULONG IoCount;
Adapter->ReceiveLength[Adapter->FirstReceive] =
pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
if ( Adapter->FirstReceive<(numReceiveQ-1) )
Adapter->FirstReceive++;
else
Adapter->FirstReceive = 0;
NdisAcquireSpinLock( &Adapter->ReceiveIoCountSpinLock );
IoCount = NdisInterlockedIncrement(&Adapter->ReceiveIoCount);
NdisReleaseSpinLock( &Adapter->ReceiveIoCountSpinLock );
if ( IoCount<numReceiveQ )
{
BulkUsb_PacketReceive( Adapter );
if ( !Adapter->StartReceive )
{
Adapter->StartReceive = TRUE;
NdisMSetTimer( &Adapter->ReceiveHandleTimer,0 );
}
}
else
{
Adapter->fgBusy =
Adapter->StopReceive = TRUE;
}
}
else
{
Adapter->MissedPackets++;
BulkUsb_PacketReceive( Adapter );
}
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
VOID
BulkUsb_PacketReceive(
IN PAX_ADAPTER Adapter
)
{
PBULKUSB_RW_CONTEXT context;
PIO_STACK_LOCATION nextStack;
context = &Adapter->PendingReceive;
UsbBuildInterruptOrBulkTransferRequest(
context->pUrb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
Adapter->ReceivePipe,
(PUCHAR)Adapter->ReceiveBuffer[Adapter->FirstReceive],
NULL,
1514,
(USBD_TRANSFER_DIRECTION_IN |USBD_SHORT_TRANSFER_OK),
NULL
);
IoSetCompletionRoutine(
context->irp,
BulkUsb_AsyncReceive_Complete,
context,
TRUE,TRUE,FALSE
);
nextStack = IoGetNextIrpStackLocation(context->irp);
nextStack->Parameters.Others.Argument1 = context->pUrb;
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
//
// Call the class driver to perform the operation.
if ( !NT_SUCCESS(IoCallDriver(Adapter->PhysicalDeviceObject,context->irp)) )
{
NdisMSetTimer( &Adapter->ReceiveTimer,1 );
}
}
NTSTATUS
BulkUsb_Interrupt_Complete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PBULKUSB_RW_CONTEXT context
)
//*++
//Routine Description:
// Completion routine for our staged read/write Irps
//
//Arguments:
// DeviceObject - Pointer to the device object for next lower device
// in the driver stack;
//
// Irp - Irp completed.
//
// Adapter - Driver defined context.
//
//Return Value:
// The function value is the final status from the operation.
//
//--*
{
PURB pUrb = context->pUrb;
PAX_ADAPTER Adapter;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -