windows-nt/Source/XPSP1/NT/drivers/net/irda/sigmatel/sys/openclos.c
2020-09-26 16:20:57 +08:00

418 lines
11 KiB
C

/**************************************************************************************************************************
* OPENCLOS.C SigmaTel STIR4200 init/shutdown module
**************************************************************************************************************************
* (C) Unpublished Copyright of Sigmatel, Inc. All Rights Reserved.
*
*
* Created: 04/06/2000
* Version 0.9
* Edited: 04/24/2000
* Version 0.91
* Edited: 04/27/2000
* Version 0.92
* Edited: 05/12/2000
* Version 0.94
* Edited: 05/19/2000
* Version 0.95
*
*
**************************************************************************************************************************/
#define DOBREAKS // enable debug breaks
#include <ndis.h>
#include <ntddndis.h> // defines OID's
#include <usbdi.h>
#include <usbdlib.h>
#include "debug.h"
#include "ircommon.h"
#include "irndis.h"
/*****************************************************************************
*
* Function: InitializeDevice
*
* Synopsis: initialize resources for a single IR device object
*
* Arguments: pThisDev - IR device object to initialize
*
* Returns: NDIS_STATUS_SUCCESS - if device is successfully opened
* NDIS_STATUS_RESOURCES - could not claim sufficient
* resources
*
*
* Notes:
* we do a lot of stuff in this open device function
* - allocate packet pool
* - allocate buffer pool
* - allocate packets/buffers/memory and chain together
* (only one buffer per packet)
* - initialize send queue
*
* This function should be called with device lock held.
*
* We don't initialize the following ir device object entries, since
* these values will outlast an reset.
* pUsbDevObj
* hNdisAdapter
* dongleCaps
* fGotFilterIndication
*
*****************************************************************************/
NDIS_STATUS
InitializeDevice(
IN OUT PIR_DEVICE pThisDev
)
{
int i;
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
DEBUGMSG(DBG_FUNC|DBG_PNP, ("+InitializeDevice\n"));
IRUSB_ASSERT( pThisDev != NULL );
//
// Current speed is the default (9600).
//
pThisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];
pThisDev->currentSpeed = DEFAULT_BAUD_RATE;
//
// Init statistical info.
// We need to do this cause reset won't free and realloc pThisDev!
//
pThisDev->packetsReceived = 0;
pThisDev->packetsReceivedDropped = 0;
pThisDev->packetsReceivedOverflow = 0;
pThisDev->packetsReceivedChecksum = 0;
pThisDev->packetsReceivedRunt = 0;
pThisDev->packetsReceivedNoBuffer = 0;
pThisDev->packetsSent = 0;
pThisDev->packetsSentDropped = 0;
pThisDev->packetsSentRejected = 0;
pThisDev->packetsSentInvalid = 0;
pThisDev->NumDataErrors = 0;
pThisDev->NumReadWriteErrors = 0;
pThisDev->NumReads = 0;
pThisDev->NumWrites = 0;
pThisDev->NumReadWrites = 0;
#if DBG
pThisDev->TotalBytesReceived = 0;
pThisDev->TotalBytesSent = 0;
pThisDev->NumYesQueryMediaBusyOids = 0;
pThisDev->NumNoQueryMediaBusyOids = 0;
pThisDev->NumSetMediaBusyOids = 0;
pThisDev->NumMediaBusyIndications = 0;
pThisDev->packetsHeldByProtocol = 0;
pThisDev->MaxPacketsHeldByProtocol = 0;
pThisDev->NumPacketsSentRequiringTurnaroundTime = 0;
pThisDev->NumPacketsSentNotRequiringTurnaroundTime = 0;
#endif
//
// Variables about the state of the device
//
pThisDev->fDeviceStarted = FALSE;
pThisDev->fGotFilterIndication = FALSE;
pThisDev->fPendingHalt = FALSE;
pThisDev->fPendingReadClearStall = FALSE;
pThisDev->fPendingWriteClearStall = FALSE;
pThisDev->fPendingReset = FALSE;
pThisDev->fPendingClearTotalStall = FALSE;
pThisDev->fKillPollingThread = FALSE;
pThisDev->fKillPassiveLevelThread = FALSE;
pThisDev->LastQueryTime.QuadPart = 0;
pThisDev->LastSetTime.QuadPart = 0;
pThisDev->PendingIrpCount = 0;
//
// OID Set/Query pending
//
pThisDev->fQuerypending = FALSE;
pThisDev->fSetpending = FALSE;
//
// Diags are off
//
#if defined(DIAGS)
pThisDev->DiagsActive = FALSE;
pThisDev->DiagsPendingActivation = FALSE;
#endif
//
// Some more state variables
//
InterlockedExchange( &pThisDev->fMediaBusy, FALSE );
InterlockedExchange( &pThisDev->fIndicatedMediaBusy, FALSE );
pThisDev->pCurrentRecBuf = NULL;
pThisDev->fProcessing = FALSE;
pThisDev->fCurrentlyReceiving = FALSE;
pThisDev->fReadHoldingReg = FALSE;
pThisDev->BaudRateMask = 0xffff; // as per Class Descriptor; may be reset in registry
//
// Initialize the queues.
//
if( TRUE != IrUsb_InitSendStructures( pThisDev ) )
{
DEBUGMSG(DBG_ERR, (" Failed to init WDM objects\n"));
goto done;
}
//
// Allocate the NDIS packet and NDIS buffer pools
// for this device's RECEIVE buffer queue.
// Our receive packets must only contain one buffer a piece,
// so #buffers == #packets.
//
NdisAllocatePacketPool(
&status, // return status
&pThisDev->hPacketPool, // handle to the packet pool
NUM_RCV_BUFS, // number of packet descriptors
16 // number of bytes reserved for ProtocolReserved field
);
if( status != NDIS_STATUS_SUCCESS )
{
DEBUGMSG(DBG_ERR, (" NdisAllocatePacketPool failed. Returned 0x%.8x\n", status));
goto done;
}
NdisAllocateBufferPool(
&status, // return status
&pThisDev->hBufferPool,// handle to the buffer pool
NUM_RCV_BUFS // number of buffer descriptors
);
if( status != NDIS_STATUS_SUCCESS )
{
DEBUGMSG(DBG_ERR, (" NdisAllocateBufferPool failed. Returned 0x%.8x\n", status));
pThisDev->BufferPoolAllocated = FALSE;
goto done;
}
pThisDev->BufferPoolAllocated = TRUE;
//
// Prepare the work items
//
for( i = 0; i < NUM_WORK_ITEMS; i++ )
{
PIR_WORK_ITEM pWorkItem;
pWorkItem = &(pThisDev->WorkItems[i]);
pWorkItem->pIrDevice = pThisDev;
pWorkItem->pInfoBuf = NULL;
pWorkItem->InfoBufLen = 0;
pWorkItem->fInUse = FALSE;
pWorkItem->Callback = NULL;
}
//
// Initialize each of the RECEIVE objects for this device.
//
for( i = 0; i < NUM_RCV_BUFS; i++ )
{
PNDIS_BUFFER pBuffer = NULL;
PRCV_BUFFER pReceivBuffer = &pThisDev->rcvBufs[i];
//
// Allocate a data buffer
//
pReceivBuffer->pDataBuf = MyMemAlloc( MAX_RCV_DATA_SIZE );
if( pReceivBuffer->pDataBuf == NULL )
{
status = NDIS_STATUS_RESOURCES;
goto done;
}
NdisZeroMemory(
pReceivBuffer->pDataBuf,
MAX_RCV_DATA_SIZE
);
pReceivBuffer->pThisDev = pThisDev;
pReceivBuffer->DataLen = 0;
pReceivBuffer->BufferState = RCV_STATE_FREE;
#if defined(WORKAROUND_MISSING_C1)
pReceivBuffer->MissingC1Detected = FALSE;
#endif
//
// Allocate the NDIS_PACKET.
//
NdisAllocatePacket(
&status, // return status
&((PNDIS_PACKET)pReceivBuffer->pPacket), // return pointer to allocated descriptor
pThisDev->hPacketPool // handle to packet pool
);
if( status != NDIS_STATUS_SUCCESS )
{
DEBUGMSG(DBG_ERR, (" NdisAllocatePacket failed. Returned 0x%.8x\n", status));
goto done;
}
}
//
// These are the receive objects for the USB
//
pThisDev->PreReadBuffer.pDataBuf = MyMemAlloc( STIR4200_FIFO_SIZE );
if( pThisDev->PreReadBuffer.pDataBuf == NULL )
{
status = NDIS_STATUS_RESOURCES;
goto done;
}
NdisZeroMemory(
pThisDev->PreReadBuffer.pDataBuf,
STIR4200_FIFO_SIZE
);
pThisDev->PreReadBuffer.pThisDev = pThisDev;
pThisDev->PreReadBuffer.DataLen = 0;
pThisDev->PreReadBuffer.BufferState = RCV_STATE_FREE;
//
// Synchronization events
//
KeInitializeEvent(
&pThisDev->EventSyncUrb,
NotificationEvent, // non-auto-clearing event
FALSE // event initially non-signalled
);
KeInitializeEvent(
&pThisDev->EventAsyncUrb,
NotificationEvent, // non-auto-clearing event
FALSE // event initially non-signalled
);
done:
//
// If we didn't complete the init successfully, then we should clean
// up what we did allocate.
//
if( status != NDIS_STATUS_SUCCESS )
{
DEBUGMSG(DBG_ERR, (" InitializeDevice() FAILED\n"));
DeinitializeDevice(pThisDev);
}
else
{
DEBUGMSG(DBG_OUT, (" InitializeDevice() SUCCEEDED\n"));
}
DEBUGMSG(DBG_FUNC|DBG_PNP, ("-InitializeDevice()\n"));
return status;
}
/*****************************************************************************
*
* Function: DeinitializeDevice
*
* Synopsis: deallocate the resources of the IR device object
*
* Arguments: pThisDev - the IR device object to close
*
* Returns: none
*
*
* Notes:
*
* Called for shutdown and reset.
* Don't clear hNdisAdapter, since we might just be resetting.
* This function should be called with device lock held.
*
*****************************************************************************/
VOID
DeinitializeDevice(
IN OUT PIR_DEVICE pThisDev
)
{
UINT i;
DEBUGMSG( DBG_FUNC|DBG_PNP, ("+DeinitializeDevice\n"));
pThisDev->linkSpeedInfo = NULL;
//
// Free all resources for the RECEIVE buffer queue.
//
for( i = 0; i < NUM_RCV_BUFS; i++ )
{
PNDIS_BUFFER pBuffer = NULL;
PRCV_BUFFER pRcvBuf = &pThisDev->rcvBufs[i];
if( pRcvBuf->pPacket != NULL )
{
NdisFreePacket( (PNDIS_PACKET)pRcvBuf->pPacket );
pRcvBuf->pPacket = NULL;
}
if( pRcvBuf->pDataBuf != NULL )
{
MyMemFree( pRcvBuf->pDataBuf, MAX_RCV_DATA_SIZE );
pRcvBuf->pDataBuf = NULL;
}
pRcvBuf->DataLen = 0;
}
//
// Deallocate the USB receive buffers
//
if( pThisDev->PreReadBuffer.pDataBuf != NULL )
MyMemFree( pThisDev->PreReadBuffer.pDataBuf, STIR4200_FIFO_SIZE );
//
// Free the packet and buffer pool handles for this device.
//
if( pThisDev->hPacketPool )
{
NdisFreePacketPool( pThisDev->hPacketPool );
pThisDev->hPacketPool = NULL;
}
if( pThisDev->BufferPoolAllocated )
{
NdisFreeBufferPool( pThisDev->hBufferPool );
pThisDev->BufferPoolAllocated = FALSE;
}
if( pThisDev->fDeviceStarted )
{
NTSTATUS ntstatus;
ntstatus = IrUsb_StopDevice( pThisDev );
DEBUGMSG(DBG_FUNC, (" DeinitializeDevice IrUsb_StopDevice() status = 0x%x\n",ntstatus));
}
InterlockedExchange( &pThisDev->fMediaBusy, FALSE );
InterlockedExchange( &pThisDev->fIndicatedMediaBusy, FALSE );
IrUsb_FreeSendStructures( pThisDev );
DEBUGMSG(DBG_FUNC|DBG_PNP, ("-DeinitializeDevice\n"));
}