Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

703 lines
18 KiB

/**************************************************************************************************************************
* 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"));
}