?? rwusb.c
字號:
DEBUGMSG(DBG_ERR, (" +ResetPipe()\n"));
// Allocate URB for RESET_PIPE request
//
urb = MemAlloc( sizeof(struct _URB_PIPE_REQUEST));
if (urb != NULL)
{
#if 0
NdisZeroMemory( urb, sizeof (struct _URB_PIPE_REQUEST) );
DEBUGMSG(DBG_ERR, (" ResetPipe before ABORT PIPE \n"));
// Initialize ABORT_PIPE request URB
//
urb->UrbHeader.Length = sizeof (struct _URB_PIPE_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
urb->UrbPipeRequest.PipeHandle = Pipe;
ntStatus = CallUSBD(Device, urb);
DEBUGCOND(DBG_ERR, !NT_SUCCESS(ntStatus), (" ResetPipe ABORT PIPE FAILED \n"));
DEBUGMSG(DBG_ERR, (" ResetPipe before RESET_PIPE \n"));
#endif
NdisZeroMemory( urb, sizeof (struct _URB_PIPE_REQUEST) );
// Initialize RESET_PIPE request URB
//
urb->UrbHeader.Length = sizeof (struct _URB_PIPE_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
urb->UrbPipeRequest.PipeHandle = (USBD_PIPE_HANDLE) Pipe;
// Submit RESET_PIPE request URB
//
ntStatus = CallUSBD(Device, urb);
DEBUGCOND(DBG_ERR, !NT_SUCCESS(ntStatus), (" ResetPipe RESET PIPE FAILED \n"));
DEBUGCOND(DBG_ERR, NT_SUCCESS(ntStatus), (" ResetPipe RESET PIPE SUCCEEDED \n"));
// Done with URB for RESET_PIPE request, free urb
//
ExFreePool(urb);
}
else
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
DEBUGMSG(DBG_ERR, (" -ResetPipe %08X\n", ntStatus));
return ntStatus;
}
NTSTATUS MyKeWaitForSingleObject(
IN PUSB_DEVICE Device,
IN PVOID EventWaitingFor,
IN OUT PIRP IrpWaitingFor,
LONGLONG timeout100ns
)
/*++
Routine Description:
Wait with a timeout in a loop
so we will never hang if we are asked to halt/reset the driver while
pollingthread is waiting for something.
If input IRP is not null, also cancel it on timeout.
NOTE: THIS FUNCTION MUST BE RE-ENTERABLE!
Return Value:
NT status code
--*/
{
NTSTATUS status = STATUS_SUCCESS;
LARGE_INTEGER Timeout;
BOOLEAN cancelResult;
if ( timeout100ns )
{ //if a non-zero timeout was passed in, use it
Timeout.QuadPart = - ( timeout100ns );
}
else
{
Timeout.QuadPart = -10000 * 1000 * 3; // default to 3 second relative delay
}
DEBUGMSG( DBG_FUNC,(" +MyKeWaitForSingleObject\n "));
status = KeWaitForSingleObject( //keep this as standard wait
EventWaitingFor,
Executive,//Suspended?Executive
KernelMode,
FALSE,
&Timeout);
if ( IrpWaitingFor && (status != STATUS_SUCCESS))
{
// if we get here we timed out and we were passed a PIRP to cancel
cancelResult = IoCancelIrp( IrpWaitingFor );
DEBUGCOND( DBG_FUNC, cancelResult,(" MyKeWaitForSingleObject successfully cancelled IRP (%x),cancelResult = %x\n",IrpWaitingFor, cancelResult));
DEBUGCOND( DBG_ERR, !cancelResult,(" MyKeWaitForSingleObject FAILED to cancel IRP (%x),cancelResult = %x\n",IrpWaitingFor, cancelResult));
}
DEBUGCOND( DBG_OUT,( STATUS_TIMEOUT == status ),(" MyKeWaitForSingleObject TIMED OUT\n"));
DEBUGCOND( DBG_OUT,( STATUS_ALERTED == status ),(" MyKeWaitForSingleObject ALERTED\n"));
DEBUGCOND( DBG_OUT,( STATUS_USER_APC == status ),(" MyKeWaitForSingleObject USER APC\n"));
DEBUGMSG( DBG_FUNC,(" -MyKeWaitForSingleObject (%x)\n", status));
return status;
}
/*****************************************************************************
*
* Function: PassiveLevelThread
*
* Synopsis: Thread running at IRQL PASSIVE_LEVEL.
*
* Arguments:
*
* Returns:
*
*
*
* Any work item that can be called must be serialized.
* i.e. when USBReset is called, NDIS will not make any other
* requests of the miniport until NdisMResetComplete is called.
*
*****************************************************************************/
VOID
PassiveLevelThread(
IN OUT PVOID Context
)
{
NTSTATUS ntStatus;
LARGE_INTEGER Timeout;
int i;
PUSB_WORK_ITEM pWorkItem;
// every parameter used here is passed via Device.
PUSB_DEVICE Device = (PUSB_DEVICE) Context;
DEBUGMSG(DBG_WARN, ("+PassiveLevelThread\n")); // change to FUNC later?
KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
Timeout.QuadPart = -10000 * 1000 * 3; // 3 second relative delay
//notify this assert
ASSERT(KeGetCurrentIrql()==PASSIVE_LEVEL);
while ( !Device->fKillPassiveLevelThread )
{
//
// The eventPassiveThread is an auto-clearing event, so
// we don't need to reset the event.
//
ntStatus = KeWaitForSingleObject( //keep this as standard wait
&Device->EventPassiveThread,
Suspended,
KernelMode,
FALSE,
&Timeout);
for (i = 0; i < NUM_WORK_ITEMS; i++ )
{
if ( Device->WorkItems[i].fInUse ) {
Device->WorkItems[i].Callback(&(Device->WorkItems[i]));
}
}
} // while !fKill
DEBUGMSG(DBG_ERR, (" PassiveLevelThread: HALT\n"));
Device->hPassiveThread = NULL;
DEBUGMSG(DBG_WARN, (" -PassiveLevelThread\n")); // change to FUNC later?
PsTerminateSystemThread(STATUS_SUCCESS);
}
void DumpStatsEverySec( PUSB_DEVICE Device, UINT NumSeconds )
{
#if DBG //disable unless really need it
static LARGE_INTEGER LastStatTime = { 0 };
LARGE_INTEGER Now;
LARGE_INTEGER Elapsed;
if ( 0 == LastStatTime.QuadPart ) {
NdisGetCurrentSystemTime( &LastStatTime ); // init
}
NdisGetCurrentSystemTime( &Now );
Elapsed = RtlLargeIntegerSubtract( Now, LastStatTime );
if ( Elapsed.QuadPart >= ( NumSeconds * USB_100ns_PER_SEC ) ) {
NdisGetCurrentSystemTime( &LastStatTime );
DEBUGMSG( DBG_WARN,("\n ****Dumping statistics every %d seconds\n",NumSeconds));
DEBUGMSG( DBG_WARN,(" Total packetsReceived = decimal %d\n",Device->packetsReceived));
DEBUGMSG( DBG_WARN,(" packetsReceivedDropped = decimal %d\n",Device->packetsReceivedDropped));
DEBUGMSG( DBG_WARN,(" packetsReceivedOverflow = decimal %d\n",Device->packetsReceivedOverflow));
DEBUGMSG( DBG_WARN,(" packetsSent = decimal %d\n",Device->packetsSent));
DEBUGMSG( DBG_WARN,(" packetsSentDropped = decimal %d\n",Device->packetsSentDropped));
//DEBUGMSG( DBG_WARN,(" packetsHeldByProtocol = decimal %d\n",Device->packetsHeldByProtocol));
// DEBUGMSG( DBG_WARN,(" MaxPacketsHeldByProtocol = decimal %d\n",Device->MaxPacketsHeldByProtocol));
// DEBUGMSG( DBG_WARN,(" MaxLenSendList ever attained = decimal %d\n",Device->MaxLenSendList));
// DEBUGMSG( DBG_WARN,(" NumTimesRcvListMaxedOut = decimal %d\n",Device->NumTimesRcvListMaxedOut));
// DEBUGMSG( DBG_WARN,(" NumSendPacketsRejected = decimal %d\n",Device->NumSendPacketsRejected));
// DEBUGMSG( DBG_WARN,(" #Times SendList que > 1 = decimal %d\n",Device->NumTimesLongerThan1));
// DEBUGMSG( DBG_WARN,(" Total packet data errors = decimal %d\n",Device->NumDataErrors));
// DEBUGMSG( DBG_WARN,(" Total bytes sent = decimal %d\n",Device->TotalBytesSent ));
// DEBUGMSG( DBG_WARN,(" Total bytes received = decimal %d\n",Device->TotalBytesReceived ));
// DEBUGMSG( DBG_WARN,(" NumYesQueryMediaBusyOids = decimal %d\n",Device->NumYesQueryMediaBusyOids));
// DEBUGMSG( DBG_WARN,(" NumNoQueryMediaBusyOids = decimal %d\n",Device->NumNoQueryMediaBusyOids));
// DEBUGMSG( DBG_WARN,(" NumSetMediaBusyOids = decimal %d\n",Device->NumSetMediaBusyOids));
// DEBUGMSG( DBG_WARN,(" NumMediaBusyUsbHeaders = decimal %d\n",Device->NumMediaBusyUsbHeaders));
// DEBUGMSG( DBG_WARN,(" NumMediaNotBusyUsbHeaders = decimal %d\n",Device->NumMediaNotBusyUsbHeaders));
// DEBUGMSG( DBG_WARN,(" NumMediaBusyIndications = decimal %d\n",Device->NumMediaBusyIndications));
// DEBUGMSG( DBG_WARN,(" NumPacketsSentRequiringTurnaroundTime = decimal %d\n",Device->NumPacketsSentRequiringTurnaroundTime));
// DEBUGMSG( DBG_WARN,(" NumPacketsSentNotRequiringTurnaroundTime = decimal %d\n",Device->NumPacketsSentNotRequiringTurnaroundTime));
}
#endif // DBG
}
/*****************************************************************************
*
* Function: PollingThread
*
* Synopsis: Thread running at IRQL PASSIVE_LEVEL.
*
* Arguments: Device Extension
*
* Returns:
*
* Algorithm: Call USBD for input data;
*
* History: dd-mm-yyyy Author Comment
* *
* Notes:
*
* USB reads are by nature 'Blocking', and when in a read, the device looks like it's
* in a 'stall' condition, so we deliberately time out every second if we've gotten no data
*
*****************************************************************************/
VOID
PollingThread(
IN PVOID Context
)
{
// every parameter used here is passed via device.
PUSB_DEVICE device = (PUSB_DEVICE) Context;
NTSTATUS Status;
DEBUGMSG(DBG_WARN, (" +PollingThread\n")); // change to FUNC later?
while(!device->fKillPollingThread )
{
if ( device->fReceiving )//Receivebuffer has been initialized
{
NTSTATUS ntStatus;
//在UsbCompleteRead中將device->pCurrentRcvBuf=pRcvBuf
ntStatus = StartUsbRead(device);
if ( NULL != device->pCurrentRcvBuf)
{ // flag we were successful
ProcessData(
device,
device->pCurrentRcvBuf
); // BUGBUG EXPERIMENT?
device->pCurrentRcvBuf = NULL;
}
} // end if
} // end while
DEBUGMSG(DBG_WARN, (" -PollingThread\n")); // change to FUNC later?
device->hPollingThread = NULL;
// this thread will finish here
// if the terminate flag is TRUE
PsTerminateSystemThread(0);
}
BOOLEAN
InitWdmStuff(
IN OUT PUSB_DEVICE Device
)
{
BOOLEAN fRes = TRUE;
ULONGLONG thisContext; //make ptr arithmetic 64-bit compatible
PUSB_CONTEXT pCont;
int i;
DEBUGMSG(DBG_FUNC, (" +InitWdmStuff\n"));
ASSERT(KeGetCurrentIrql()==PASSIVE_LEVEL);
//
// Initialize a notification event for signalling PassiveLevelThread.
//
KeInitializeEvent(
&Device->EventPassiveThread,
SynchronizationEvent, // auto-clearing event
FALSE // event initially non-signalled
);
KeInitializeEvent(
&Device->EventUrb,
NotificationEvent, // non-auto-clearing event
FALSE // event initially non-signalled
);
KeInitializeEvent(
&Device->EventIoCtl,
NotificationEvent, // non-auto-clearing event
FALSE // event initially non-signalled
);
((PUSB_INFO) Device->pUsbInfo)->IrpSubmitUrb = NULL;
// set urblen to max possible urb size
Device->UrbLen = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
//Device->UrbLen = MAX( Device->UrbLen, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
Device->UrbLen = MAX( Device->UrbLen, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST ));
Device->UrbLen = MAX( Device->UrbLen, sizeof(struct _URB_SELECT_CONFIGURATION));
// allocate our send context structs
Device->pSendContexts = MemAlloc( NUM_SEND_CONTEXTS * sizeof( USB_CONTEXT ) );
if ( NULL == Device->pSendContexts ) {
fRes = FALSE;
goto done;
}
NdisZeroMemory( Device->pSendContexts, NUM_SEND_CONTEXTS * sizeof( USB_CONTEXT ) );
thisContext = (ULONGLONG) Device->pSendContexts;
for ( i= 0; i < NUM_SEND_CONTEXTS; i++ ) //
{
pCont = (PUSB_CONTEXT) thisContext;
pCont->DeviceObject = Device;
pCont->Urb = MemAlloc(Device->UrbLen );
if ( NULL == pCont->Urb )
{
DEBUGMSG(DBG_ERR, ("InitWdmStuff failed to alloc urb\n"));
fRes = FALSE;
goto done;
}
NdisZeroMemory( pCont->Urb, Device->UrbLen );
pCont->fInUse = FALSE;
pCont->Buffer = MemAlloc(MAX_PACKET_SIZE);
if ( NULL == pCont->Buffer )
{
DEBUGMSG(DBG_ERR, ("InitWdmStuff failed to alloc info buf\n"));
fRes = FALSE;
goto done;
}
thisContext += sizeof(USB_CONTEXT );
} // for
done:
DEBUGMSG(DBG_FUNC, (" -InitWdmStuff\n"));
return fRes;
}
VOID
FreeWdmStuff(
IN OUT PUSB_DEVICE Device
)
{
ULONGLONG thisContext; //make ptr arithmetic 64-bit compatible
PUSB_CONTEXT pCont;
int i;
DEBUGMSG(DBG_FUNC, (" +
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -