Hello,

I've been searching for a long time to get an information about I2C
interface function calls. I am trying to send DDC commands over I2C bus
to Monitor. I've used WDM Src\WDM\...\ATIShare source code template to
do this.

With the code, given below, I am able to get I2COpen & I2CAccess
function pointers from Video Adapter.(that supports I2C Interface)

But calling I2COpen function always fails and returns 0xC00000C2 error
code. It is
defined in ntstatus.h as

#define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS)0xC00000C2L)

There is no documentation available for this. Does anyone have any
information about the sequence of calls to be issued to access the I2C
Interface? Any help is appreciated.

I'm calling LockI2Cprovider function after LocateAttachI2CProvider
function call. The program fails in LockI2Cprovider () function.

BOOLEAN
LocateAttachI2CProvider(
PDEVICE_OBJECT pVideoDeviceObject,
PI2C_CONTEXT pstI2CContext
)
{
PIRP pIrp;
BOOLEAN bResult = FALSE;
PIO_STACK_LOCATION pNextStack;
NTSTATUS ntStatus;
KEVENT Event;
I2CINTERFACE* pI2CInterface;


if (pVideoDeviceObject == NULL || pstI2CContext == NULL)
{
return FALSE;
}


pI2CInterface = pstI2CContext->m_i2cProviderInterface;
if (pI2CInterface == NULL)
{
return FALSE;
}


pIrp = IoAllocateIrp (pVideoDeviceObject->StackSize, FALSE);
if( pIrp == NULL)
{
return FALSE;
}


pNextStack = IoGetNextIrpStackLocation (pIrp); // original
if (pNextStack == NULL)
{
return FALSE;
}


pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
pNextStack->MajorFunction = (UCHAR)IRP_MJ_PNP;
pNextStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
KeInitializeEvent( &Event, NotificationEvent, FALSE);


IoSetCompletionRoutine (
pIrp,
I2CScriptIoSynchCompletionRoutine,
&Event,
TRUE,
TRUE,
TRUE);


pNextStack->Parameters.QueryInterface.InterfaceType =
(struct _GUID *)
&GUID_I2C_INTERFACE;
pNextStack->Parameters.QueryInterface.Size =
sizeof( I2CINTERFACE);
pNextStack->Parameters.QueryInterface.Version = 1;
pNextStack->Parameters.QueryInterface.Interface =
(PINTERFACE) pI2CInterface;
pNextStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;

ntStatus = IoCallDriver (pVideoDeviceObject, pIrp);


if( ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject(
&Event,
Suspended,
KernelMode,
FALSE,
NULL);
}


if ((pI2CInterface->i2cOpen == NULL) ||
(pI2CInterface->i2cAccess == NULL))
{
return FALSE;
}
else
{
DebugPrint ("deviceInfo->m_i2cProviderInterface->i2cOpen 0x%x",

pI2CInterface->i2cOpen);


DebugPrint ("deviceInfo->m_i2cProviderInterface->i2cAccess
0x%x",
pI2CInterface->i2cAccess);
}


pstI2CContext->m_pdoDriver= pVideoDeviceObject;


bResult = TRUE;


if( pIrp != NULL)
IoFreeIrp( pIrp);


return bResult;



}


BOOLEAN LockI2CProvider (PI2C_CONTEXT pstContext)
{
NTSTATUS status;

if ((pstContext->m_i2cProviderInterface->i2cOpen == NULL) ||
(pstContext->m_i2cProviderInterface->i2cAccess == NULL) ||
(pstContext->m_pdoDriver == NULL))
{
return FALSE;
}


pstContext->i2cAccessBlock->Status = I2C_STATUS_NOERROR;


status = pstContext->m_i2cProviderInterface->i2cOpen (
pstContext->m_pdoDriver,
TRUE,
pstContext->i2cAccessBlock);


if (status != STATUS_SUCCESS)
{
DebugPrint ( "CI2CScript: LockI2CProvider() status =
0x%lx\n",


status);


return FALSE;
}


pstContext->m_dwI2CAccessKey =
pstContext->i2cAccessBlock->dwCookie;


DebugPrint ("LockI2CProvider m_dwI2CAccessKey %ld",
pstContext->i2cAccessBlock->dwCookie);


return TRUE;



}

Thanks
VK