📄 hpna_2k.c
字号:
}
pRcvBuf->dataLen = 0;
}
//
// Free the packet and buffer pool handles for this device.
//
if (Device->hPacketPool)
{
NdisFreePacketPool(Device->hPacketPool);
Device->hPacketPool = NULL;
}
if (Device->hBufferPool)
{
NdisFreeBufferPool(Device->hBufferPool);
Device->hBufferPool = NULL;
}
if ( Device->fDeviceStarted )
{
ntstatus = StopDevice( Device );
}
// InterlockedExchange( &Device->fMediaBusy, FALSE );
// InterlockedExchange( &Device->fIndicatedMediaBusy, FALSE );
FreeWdmStuff( Device );
return status;
}
/*****************************************************************************
*
* Function: MiniportHalt
*
* Synopsis: Deallocates resources when the NIC is removed and halts the
* device.
*
* Arguments: Context - pointer to the ir device object
*
* Returns:
*
* Algorithm: Mirror image of MiniportInitialize...undoes everything initialize
* did.
* Notes:
*
* This routine runs at IRQL PASSIVE_LEVEL.
*
* BUGBUG: Could MiniportReset fail and then MiniportHalt be called. If so, we need
* to chech validity of all the pointers, etc. before trying to
* deallocate.
*
*****************************************************************************/
VOID
MiniportHalt(
IN NDIS_HANDLE Context
)
{
PUSB_DEVICE device;
NTSTATUS ntstatus;
device = CONTEXT_TO_DEV(Context);
if ( TRUE == device->fPendingHalt ) {
goto done;
}
//
// Let the send completion and receive completion routine know that there
// is a pending reset.
//
device->fPendingHalt = TRUE;
UsbCommonShutdown( device ); //shutdown logic common to halt and reset; see below
// We had better not have left any pending read, write, or control IRPS hanging out there!
ASSERT( 0 == device->PendingIrpCount );
ASSERT( FALSE == device->fSetpending );
ASSERT( FALSE == device->fQuerypending );
//
// Free our own hpna device object.
//
MemFree(device, sizeof(USB_DEVICE));
done:
return;
}
/*****************************************************************************
*
* Function: UsbCommonShutdown
*
* Synopsis: Deallocates resources when the NIC is removed and halts the
* device. This is stuff common to USBHalt and USBReset and is called by both
*
* Arguments: device USB_DEVICE
*
* Returns:
*
* Algorithm: Mirror image of USBInitialize...undoes everything initialize
* did.
*
* Notes:
*
* This routine runs at IRQL PASSIVE_LEVEL.
*
*
*****************************************************************************/
VOID
UsbCommonShutdown(
IN PUSB_DEVICE Device
)
{
NTSTATUS ntStatus;
//
// Sleep 50 milliseconds so pending io might finish normally
//
NdisMSleep(50000); //
// We want to wait until all pending receives and sends to the
// device object. We cancel any
// irps. Wait until sends and receives have stopped.
//
CancelPendingIo( Device );
Device->fKillPassiveLevelThread = TRUE;
KeSetEvent(&Device->EventPassiveThread, 0, FALSE);
DbgPrint("halt!");
while (Device->hPassiveThread != NULL)
{
//
// Sleep 50 milliseconds.
//
NdisMSleep(50000);
}
Device->fKillPollingThread = TRUE;
//ASSERT( NT_SUCCESS( ntstatus ) );
while (Device->hPollingThread != NULL)
{
//
// Sleep 50 milliseconds.
//
NdisMSleep(50000);
}
//
// Deinitialize our own ir device object.
//
DeinitializeDevice(Device);
Device->fDeviceStarted= FALSE;
Device->NumDataErrors = 0; //reset data error count
return;
}
/*****************************************************************************
*
* Function: MiniportReset
*
* Synopsis: Resets the drivers software state.
*
* Arguments: AddressingReset - return arg. If set to TRUE, NDIS will call
* MiniportSetInformation to restore addressing
* information to the current values.
* Context - pointer to ir device object
*
* Returns: NDIS_STATUS_PENDING
*
*
* Notes:
*
*
*****************************************************************************/
NDIS_STATUS
MiniportReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
{
PUSB_DEVICE device;
NDIS_STATUS status = NDIS_STATUS_PENDING;
NDIS_PHYSICAL_ADDRESS noMaxAddr = NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
device = CONTEXT_TO_DEV(MiniportAdapterContext);
if ( TRUE == device->fPendingReset ) {
status = NDIS_STATUS_RESET_IN_PROGRESS ;
goto done;
}
//
// Let the send completion and receive completion routine know that there
// is a pending reset.
//
device->fPendingReset = TRUE;
*AddressingReset = TRUE;
if ( FALSE == ScheduleWorkItem( device,
ResetUsbDevice, NULL, 0)){
status = NDIS_STATUS_FAILURE;
}
done:
return status;
}
/*****************************************************************************
*
* Function: ResetUsbDevice
*
* Synopsis: Callback for MiniportReset
*
* Arguments:
*
* Returns:
*
*
* Notes:
*
* The following elements of the ir device object outlast the reset:
*
*
* pUsbDevObj
*
* hNdisAdapter
*
*****************************************************************************/
VOID
ResetUsbDevice(
IN PUSB_WORK_ITEM pWorkItem
)
{
NDIS_STATUS status = NDIS_STATUS_FAILURE;
PUSB_DEVICE device = (PUSB_DEVICE) pWorkItem->pDevice;
FreeWorkItem(pWorkItem);
UsbCommonShutdown( device ); //shutdown logic common to halt and reset; see above
status = InitializeDevice(device); //this MUST succeed
if (status != NDIS_STATUS_SUCCESS)
{
status = NDIS_STATUS_FAILURE;
goto done;
}
//
// Initialize receive loop.
//
status = InitializeReceive(device);
if (status != NDIS_STATUS_SUCCESS)
{
status = NDIS_STATUS_FAILURE;
goto done;
}
if (status != STATUS_SUCCESS)
{
NdisWriteErrorLogEntry(device->hNdisAdapter,
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
1,
status);
status = NDIS_STATUS_HARD_ERRORS;
goto done;
}
done:
NdisMResetComplete(
device->hNdisAdapter,
(NDIS_STATUS)status,
TRUE
);
device->fPendingReset = FALSE;
}
/*****************************************************************************
*
* Function: MiniportSend
*
* Synopsis: Send a packet to the USB driver and add the sent irp and io context to
* To the pending send queue; this que is really just needed for possible later error cancellation
*
*
* Arguments: MiniportAdapterContext - pointer to current ir device object
* pPacketToSend - pointer to packet to send
* Flags - any flags set by protocol
*
* Returns: NDIS_STATUS_PENDING - This is generally what we should
* return. We will call NdisMSendComplete
* when the USB driver completes the
* send.
* STATUS_UNSUCCESSFUL - The packet was invalid.
*
* Unsupported returns:
* NDIS_STATUS_SUCCESS - We should never return this since
* results will always be pending from
* the USB driver.
* NDIS_STATUS_RESOURCES-This indicates to the protocol that the
* device currently has no resources to complete
* the request. The protocol will resend
* the request when it receives either
* NdisMSendResourcesAvailable or
* NdisMSendComplete from the device.
*
* Notes: This routine delegates all the real work to SendPacket in rwir.c
*
*
*****************************************************************************/
NDIS_STATUS
MiniportSend(
IN NDIS_HANDLE MiniportAdapterContext,//就是初始化时用SetAttributEx的USB_DEVICE device
IN PNDIS_PACKET pPacketToSend,
IN UINT Flags
)
{
NDIS_STATUS status;
//PNDIS_USB_PACKET_INFO packetInfo;
PUSB_DEVICE device = ( PUSB_DEVICE ) MiniportAdapterContext;
if ( device->RcvBuffersInUse >= (NUM_RCV_BUFS -2) )
{
//
// fail the packet until we're caught up
status = NDIS_STATUS_FAILURE;
goto done;
}
//如果端点为Stall状态
if( TRUE == device->fPendingWriteClearStall ) {
status = NDIS_STATUS_FAILURE;
goto done;
}
//packetInfo = GetPacketInfo(pPacketToSend);
status = ( NDIS_STATUS ) SendPacket(
device,
pPacketToSend,
Flags,
CONTEXT_NDIS_PACKET
);
done:
return status;
}
/*
PNDIS_USB_PACKET_INFO oob
GetPacketInfo(
PNDIS_PACKET packet
)
{
MEDIA_SPECIFIC_INFORMATION *mediaInfo;
UINT size;
NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(packet, &mediaInfo, &size);
return (PNDIS_USB_PACKET_INFO)mediaInfo->ClassInformation;
}
*/
//indicate RcvBuffer is full
VOID
IndicateMediaBusy(
IN PUSB_DEVICE Device
)
{
NdisMIndicateStatus(
Device->hNdisAdapter,
NDIS_STATUS_MEDIA_BUSY,
NULL,
0
);
NdisMIndicateStatusComplete(
Device->hNdisAdapter,
);
}
/*****************************************************************************
*
* Function: MemAlloc
*
* Synopsis: allocates a block of memory using NdisAllocateMemory
*
* Arguments: size - size of the block to allocate
*
* Returns: a pointer to the allocated block of memory
*
*
*****************************************************************************/
PVOID MemAlloc(UINT size)
{
PVOID memptr;
NDIS_PHYSICAL_ADDRESS noMaxAddr = NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
NDIS_STATUS status;
status = NdisAllocateMemoryWithTag(&memptr, size, USB_TAG);
if (status != NDIS_STATUS_SUCCESS)
{
memptr = NULL;
}
return memptr;
}
/*****************************************************************************
*
* Function: MemFree
*
* Synopsis: frees a block of memory allocated by MemAlloc
*
* Arguments: memptr - memory to free
* size - size of the block to free
*
*
*****************************************************************************/
VOID
MemFree(
PVOID memptr,
UINT size
)
{
NdisFreeMemory(memptr, size, 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -