/************************************************************************************************************************** * IRMISC.C SigmaTel STIR4200 misc module ************************************************************************************************************************** * (C) Unpublished Copyright of Sigmatel, Inc. All Rights Reserved. * * * Created: 04/06/2000 * Version 0.9 * Edited: 09/16/2000 * Version 1.03 * Edited: 09/25/2000 * Version 1.10 * Edited: 12/07/2000 * Version 1.12 * Edited: 01/09/2001 * Version 1.13 * Edited: 01/16/2001 * Version 1.14 * * **************************************************************************************************************************/ #define DOBREAKS // enable debug breaks #include #include // defines OID's #include #include #include "debug.h" #include "ircommon.h" #include "irndis.h" /***************************************************************************** * * Function: IrUsb_CreateDeviceExt * * Synopsis: Creates a IR device extension * * Arguments: DeviceExt - pointer to DeviceExt pointer to return created device extension. * * Returns: STATUS_SUCCESS if successful * STATUS_UNSUCCESSFUL otherwise * * Notes: * *****************************************************************************/ NTSTATUS IrUsb_CreateDeviceExt( IN OUT PIR_DEVICE *DeviceExt ) { NTSTATUS ntStatus = STATUS_SUCCESS; PIR_DEVICE pThisDev = NULL; DEBUGMSG(DBG_FUNC,("+IrUsb_CreateDeviceExt() \n")); pThisDev = NewDevice(); if( !pThisDev ) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto done; } *DeviceExt = pThisDev; done: DEBUGMSG(DBG_FUNC,("-IrUsb_CreateDeviceExt() \n")); return ntStatus; } /***************************************************************************** * * Function: IrUsb_AddDevice * * Synopsis: This routine is called to create and initialize our Functional Device Object (FDO). * For monolithic drivers, this is done in DriverEntry(), but Plug and Play devices * wait for a PnP event * * Arguments: DeviceExt - receives ptr to new dev obj * * Returns: STATUS_SUCCESS if successful, * STATUS_UNSUCCESSFUL otherwise * * Notes: * *****************************************************************************/ NTSTATUS IrUsb_AddDevice( IN OUT PIR_DEVICE *DeviceExt ) { NTSTATUS ntStatus; DEBUGMSG( DBG_FUNC,("+IrUsb_AddDevice()\n")); *DeviceExt = NULL; ntStatus = IrUsb_CreateDeviceExt( DeviceExt ); DEBUGMSG( DBG_FUNC,("-IrUsb_AddDevice() (%x)\n", ntStatus)); return ntStatus; } /***************************************************************************** * * Function: IrUsb_GetDongleCaps * * Synopsis: We need to manually set the data in the class specific descriptor, since * our device does not support the automatic-read feature * * Arguments: pThisDev - pointer to IR device * * Returns: STATUS_SUCCESS if successful * STATUS_UNSUCCESSFUL otherwise * * Notes: * *****************************************************************************/ NTSTATUS IrUsb_GetDongleCaps( IN OUT PIR_DEVICE pThisDev ) { IRUSB_CLASS_SPECIFIC_DESCRIPTOR *pDesc = &(pThisDev->ClassDesc); NTSTATUS ntStatus = STATUS_SUCCESS; NDIS_HANDLE ConfigurationHandle; // MS Security bug #539291 IRUSB_ASSERT(pThisDev != NULL); IRUSB_ASSERT(pDesc != NULL); // // MS Security bug #539314 // Note: this code is called at init time when it will set ClassConfigured=TRUE. // It may later be called by the polling thread, but at no time could multiple // threads be in here. Therefore, access to ClassConfigured does not need to be locked. // // // Make sure the code is only executed at init time // if( pDesc->ClassConfigured ) { return STATUS_SUCCESS; } pDesc->ClassConfigured = TRUE; // // Some is hardwired, some are read from the registry // NdisOpenConfiguration( &ntStatus, &ConfigurationHandle, pThisDev->WrapperConfigurationContext ); // // Turnaroud time (read from the registry) // if( NT_SUCCESS(ntStatus) ) { NDIS_STRING MinTurnAroundKeyWord = NDIS_STRING_CONST("MinTurnTime"); PNDIS_CONFIGURATION_PARAMETER pParameterValue; NdisReadConfiguration( &ntStatus, &pParameterValue, ConfigurationHandle, &MinTurnAroundKeyWord, NdisParameterInteger ); if( NT_SUCCESS(ntStatus) ) { switch( pParameterValue->ParameterData.IntegerData ) { case 500: pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_0p5ms; break; case 1000: pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_1ms; break; case 5000: pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_5ms; break; case 10000: pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_10ms; break; default: pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_0ms; break; } } // // Speed mask (read from the registry) // if( NT_SUCCESS(ntStatus) ) { NDIS_STRING SpeedEnable = NDIS_STRING_CONST("SpeedEnable"); NdisReadConfiguration( &ntStatus, &pParameterValue, ConfigurationHandle, &SpeedEnable, NdisParameterInteger ); if( NT_SUCCESS(ntStatus) ) { switch( pParameterValue->ParameterData.IntegerData ) { case SPEED_2400: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_2400; break; case SPEED_9600: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_9600; break; case SPEED_19200: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_19200; break; case SPEED_38400: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_38400; break; case SPEED_57600: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_57600; break; case SPEED_115200: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_115200; break; case SPEED_576000: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_576K; break; case SPEED_1152000: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_1152K; break; case SPEED_4000000: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_4M; break; default: pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_4M; break; } } } // // Read the receive mode // if( NT_SUCCESS(ntStatus) ) { NDIS_STRING Keyword = NDIS_STRING_CONST("ReceiveMode"); NdisReadConfiguration( &ntStatus, &pParameterValue, ConfigurationHandle, &Keyword, NdisParameterInteger ); if( NT_SUCCESS(ntStatus) ) { switch( pParameterValue->ParameterData.IntegerData ) { case RXMODE_SLOW: pThisDev->ReceiveMode = RXMODE_SLOW; break; case RXMODE_SLOWFAST: pThisDev->ReceiveMode = RXMODE_SLOWFAST; break; case RXMODE_FAST: default: pThisDev->ReceiveMode = RXMODE_FAST; break; } } else { // // Force a default anyway // pThisDev->ReceiveMode = RXMODE_FAST; ntStatus = STATUS_SUCCESS; } } // // Read the tranceiver type // if( NT_SUCCESS(ntStatus) ) { NDIS_STRING Keyword = NDIS_STRING_CONST("TransceiverType"); NdisReadConfiguration( &ntStatus, &pParameterValue, ConfigurationHandle, &Keyword, NdisParameterInteger ); if( NT_SUCCESS(ntStatus) ) { switch( pParameterValue->ParameterData.IntegerData ) { case TRANSCEIVER_HP: pThisDev->TransceiverType = TRANSCEIVER_HP; break; case TRANSCEIVER_INFINEON: pThisDev->TransceiverType = TRANSCEIVER_INFINEON; break; case TRANSCEIVER_VISHAY: pThisDev->TransceiverType = TRANSCEIVER_VISHAY; break; case TRANSCEIVER_VISHAY_6102F: pThisDev->TransceiverType = TRANSCEIVER_VISHAY_6102F; break; case TRANSCEIVER_4000: pThisDev->TransceiverType = TRANSCEIVER_4000; break; case TRANSCEIVER_4012: pThisDev->TransceiverType = TRANSCEIVER_4012; break; case TRANSCEIVER_CUSTOM: default: pThisDev->TransceiverType = TRANSCEIVER_CUSTOM; break; } } else { // // Force a default anyway // pThisDev->TransceiverType = TRANSCEIVER_4012; ntStatus = STATUS_SUCCESS; } } // // And the receive window // if( NT_SUCCESS(ntStatus) ) { if( pThisDev->ChipRevision == CHIP_REVISION_7 ) { NDIS_STRING Keyword = NDIS_STRING_CONST("ReceiveWindow"); NdisReadConfiguration( &ntStatus, &pParameterValue, ConfigurationHandle, &Keyword, NdisParameterInteger ); if( NT_SUCCESS(ntStatus) ) { switch( pParameterValue->ParameterData.IntegerData ) { case 2: pDesc->bmWindowSize = BM_WINDOW_SIZE_2; break; case 1: default: pDesc->bmWindowSize = BM_WINDOW_SIZE_1; break; } } else { // // Force a default anyway // pDesc->bmWindowSize = BM_WINDOW_SIZE_1; ntStatus = STATUS_SUCCESS; } } #if defined(SUPPORT_LA8) && !defined(LEGACY_NDIS5) else if( pThisDev->ChipRevision == CHIP_REVISION_8 ) { #ifdef LOW_PRIORITY_POLL pDesc->bmWindowSize = BM_WINDOW_SIZE_2; #else pDesc->bmWindowSize = BM_WINDOW_SIZE_4; #endif } #endif else { pDesc->bmWindowSize = BM_WINDOW_SIZE_1; } } // // MS Security bug #539329 (added comment). // Used in Diagnostic version. // #if defined(VARIABLE_SETTINGS) if( NT_SUCCESS(ntStatus) ) { NDIS_STRING Keyword = NDIS_STRING_CONST("Dpll"); NTSTATUS DumStatus; NdisReadConfiguration( &DumStatus, &pParameterValue, ConfigurationHandle, &Keyword, NdisParameterHexInteger ); // // Since the Sir and Fir Dpll must be identical, they have // been combined into a single registry value. // if( NT_SUCCESS(DumStatus) ) { pThisDev->SirDpll = pParameterValue->ParameterData.IntegerData; pThisDev->FirDpll = pParameterValue->ParameterData.IntegerData; } } if( NT_SUCCESS(ntStatus) ) { NDIS_STRING Keyword = NDIS_STRING_CONST("SirSensitivity"); NTSTATUS DumStatus; NdisReadConfiguration( &DumStatus, &pParameterValue, ConfigurationHandle, &Keyword, NdisParameterHexInteger ); if( NT_SUCCESS(DumStatus) ) { pThisDev->SirSensitivity = pParameterValue->ParameterData.IntegerData; } } if( NT_SUCCESS(ntStatus) ) { NDIS_STRING Keyword = NDIS_STRING_CONST("FirSensitivity"); NTSTATUS DumStatus; NdisReadConfiguration( &DumStatus, &pParameterValue, ConfigurationHandle, &Keyword, NdisParameterHexInteger ); if( NT_SUCCESS(DumStatus) ) { pThisDev->FirSensitivity = pParameterValue->ParameterData.IntegerData; } } #endif NdisCloseConfiguration( ConfigurationHandle ); } if( NT_SUCCESS(ntStatus) ) { // fixup settings if ( pThisDev->TransceiverType == TRANSCEIVER_HP ) pThisDev->ReceiveMode = RXMODE_SLOWFAST; if ( pThisDev->ReceiveMode == RXMODE_SLOW && pThisDev->BaudRateMask == NDIS_IRDA_SPEED_MASK_4M) pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_115200; } if( NT_SUCCESS(ntStatus) ) { // Maximum data size pDesc->bmDataSize = BM_DATA_SIZE_2048; #ifdef LOW_PRIORITY_POLL pDesc->bmDataSize = BM_DATA_SIZE_1024; #endif // Speed pDesc->wBaudRate = NDIS_IRDA_SPEED_MASK_4M; #if defined(WORKAROUND_BROKEN_MIR) pDesc->wBaudRate &= (~NDIS_IRDA_SPEED_1152K & ~NDIS_IRDA_SPEED_576K); #endif #if defined(WORKAROUND_CASIO) pDesc->wBaudRate &= (~NDIS_IRDA_SPEED_57600 & ~NDIS_IRDA_SPEED_19200); #endif // Extra BOFs #if defined(WORKAROUND_CASIO) pDesc->bmExtraBofs = BM_EXTRA_BOFS_0; #else pDesc->bmExtraBofs = BM_EXTRA_BOFS_24; #endif } return ntStatus; } /***************************************************************************** * * Function: IrUsb_SetDongleCaps * * Synopsis: Set the DONGLE_CAPABILITIES struct in our device from the information * we have already gotten from the USB Class-Specific descriptor. * Some data items are usable directly as formatted in the Class-Specific descriptor, * but some need to be translated to a different format for OID_xxx use; * The donglecaps struct is thus used to hold the info in a form * usable directly by OID_xxx 's. * * Arguments: pThisDev - pointer to IR device * * Returns: None * * Notes: * *****************************************************************************/ VOID IrUsb_SetDongleCaps( IN OUT PIR_DEVICE pThisDev ) { DONGLE_CAPABILITIES *pCaps = &(pThisDev->dongleCaps); IRUSB_CLASS_SPECIFIC_DESCRIPTOR *pDesc = &(pThisDev->ClassDesc); DEBUGMSG( DBG_FUNC,("+IrUsb_SetDongleCaps\n")); // MS Security bug #539291 IRUSB_ASSERT(pThisDev != NULL); IRUSB_ASSERT(pDesc != NULL); IRUSB_ASSERT(pCaps != NULL); DEBUGMSG( DBG_FUNC, (" IrUsb_SetDongleCaps() RAW ClassDesc BUFFER:\n")); IRUSB_DUMP( DBG_FUNC,( (PUCHAR) pDesc, 12 ) ); // // Deal with the turnaround time // switch( pDesc->bmMinTurnaroundTime ) { case BM_TURNAROUND_TIME_0ms: pCaps->turnAroundTime_usec = 0; break; case BM_TURNAROUND_TIME_0p01ms: pCaps->turnAroundTime_usec = 10; //device tells us millisec; we store as microsec break; case BM_TURNAROUND_TIME_0p05ms: pCaps->turnAroundTime_usec = 50; break; case BM_TURNAROUND_TIME_0p1ms: pCaps->turnAroundTime_usec = 100; break; case BM_TURNAROUND_TIME_0p5ms: pCaps->turnAroundTime_usec = 500; break; case BM_TURNAROUND_TIME_1ms: pCaps->turnAroundTime_usec = 1000; break; case BM_TURNAROUND_TIME_5ms: pCaps->turnAroundTime_usec = 5000; break; case BM_TURNAROUND_TIME_10ms: pCaps->turnAroundTime_usec = 10000; break; default: IRUSB_ASSERT( 0 ); // we should have covered all the cases here pCaps->turnAroundTime_usec = 1000; } // // We probably support many window sizes and will have multiple of these bits set; // Just save the biggest we support for now to tell ndis // if( pDesc->bmWindowSize & BM_WINDOW_SIZE_7 ) pCaps->windowSize = 7; else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_6 ) pCaps->windowSize = 6; else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_5 ) pCaps->windowSize = 5; else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_4 ) pCaps->windowSize = 4; else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_3 ) pCaps->windowSize = 3; else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_2 ) pCaps->windowSize = 2; else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_1 ) pCaps->windowSize = 1; else { IRUSB_ASSERT( 0 ); // we should have covered all the cases here pCaps->windowSize = 1; } // // Extra BOFS // switch( (USHORT)pDesc->bmExtraBofs ) { case BM_EXTRA_BOFS_0: pCaps->extraBOFS = 0; break; case BM_EXTRA_BOFS_1: pCaps->extraBOFS = 1; break; case BM_EXTRA_BOFS_2: pCaps->extraBOFS = 2; break; case BM_EXTRA_BOFS_3: pCaps->extraBOFS = 3; break; case BM_EXTRA_BOFS_6: pCaps->extraBOFS = 6; break; case BM_EXTRA_BOFS_12: pCaps->extraBOFS = 12; break; case BM_EXTRA_BOFS_24: pCaps->extraBOFS = 24; break; case BM_EXTRA_BOFS_48: pCaps->extraBOFS = 48; break; default: IRUSB_ASSERT( 0 ); // we should have covered all the cases here pCaps->extraBOFS = 0; } // // We probably support many data sizes and will have multiple of these bits set; // Just save biggest we support for now to tell ndis // if( pDesc->bmDataSize & BM_DATA_SIZE_2048 ) pCaps->dataSize = 2048; else if( pDesc->bmDataSize & BM_DATA_SIZE_1024 ) pCaps->dataSize = 1024; else if( pDesc->bmDataSize & BM_DATA_SIZE_512 ) pCaps->dataSize = 512; else if( pDesc->bmDataSize & BM_DATA_SIZE_256 ) pCaps->dataSize = 256; else if( pDesc->bmDataSize & BM_DATA_SIZE_128 ) pCaps->dataSize = 128; else if( pDesc->bmDataSize & BM_DATA_SIZE_64 ) pCaps->dataSize = 64; else { IRUSB_ASSERT( 0 ); // we should have covered all the cases here pCaps->dataSize = 2048; } pDesc->wBaudRate &= pThisDev->BaudRateMask; // mask defaults to 0xffff; may be set in registry // // max frame size is 2051; max irda dataSize should be 2048 // IRUSB_ASSERT( MAX_TOTAL_SIZE_WITH_ALL_HEADERS > pCaps->dataSize); DEBUGMSG( DBG_FUNC,(" IrUsb_SetDongleCaps pCaps->turnAroundTime_usec = dec %d\n",pCaps->turnAroundTime_usec)); DEBUGMSG( DBG_FUNC,(" extraBOFS = dec %d\n",pCaps->extraBOFS)); DEBUGMSG( DBG_FUNC,(" dataSize = dec %d\n",pCaps->dataSize)); DEBUGMSG( DBG_FUNC,(" windowSize = dec %d\n",pCaps->windowSize)); DEBUGMSG( DBG_FUNC,(" MAX_TOTAL_SIZE_WITH_ALL_HEADERS == dec %d\n",MAX_TOTAL_SIZE_WITH_ALL_HEADERS)); DEBUGMSG( DBG_FUNC,(" pDesc->bmDataSize = 0x%02x\n",pDesc->bmDataSize)); DEBUGMSG( DBG_FUNC,(" pDesc->bmWindowSize = 0x%02x\n",pDesc->bmWindowSize)); DEBUGMSG( DBG_FUNC,(" pDesc->bmMinTurnaroundTime = 0x%02x\n",pDesc->bmMinTurnaroundTime)); DEBUGMSG( DBG_FUNC,(" pDesc->wBaudRate = 0x%04x\n",pDesc->wBaudRate)); DEBUGMSG( DBG_FUNC,(" pDesc->bmExtraBofs = 0x%02x\n",pDesc->bmExtraBofs)); DEBUGMSG( DBG_FUNC,("-IrUsb_SetDongleCaps\n")); }