|
|
/**************************************************************************************************************************
* 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 <ndis.h>
#include <ntddndis.h> // defines OID's
#include <usbdi.h>
#include <usbdlib.h>
#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")); }
|