/************************************************************************************************************************** * 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 #include // defines OID's #include #include #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")); }