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.
3629 lines
98 KiB
3629 lines
98 KiB
//
|
|
// Copyright (c) 1998-1999, Microsoft Corporation, all rights reserved
|
|
//
|
|
// irp.c
|
|
//
|
|
// IEEE1394 mini-port/call-manager driver
|
|
//
|
|
// Routines that issue the numerous Irbs to the 1394 Bus driver
|
|
//
|
|
// 04/01/1999 ADube Created,
|
|
//
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
|
|
//
|
|
// This file will contain all the functions that issue Irps with the various Irbs to the
|
|
// 1394 bus. All Irbs except the actual send/recv irbs will be implemented here
|
|
//
|
|
|
|
//
|
|
// The functions will follow this general algorithm
|
|
// nicGetIrb
|
|
// nicInitialize....Irb
|
|
// nicPrintDebugSpew
|
|
// nicGetIrp
|
|
// nicSubmit_Irp_Synch
|
|
// return Status
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// A Simple template that can be used to send Irps syncronously
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/*
|
|
Comments Template
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
/*
|
|
|
|
// Function Description:
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
// Arguments
|
|
//
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
|
|
|
|
Function template
|
|
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGe....ect, pAdapter %x", pAdapter ) );
|
|
|
|
|
|
ASSERT (pNodeAddress != NULL);
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
nicInit....Irb (..)
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pRemoteNodePdoCb, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_Synch ( pAdapter->pLocalHostPdoCb,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
Copy returned data to nic1394's data structures
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicGet139..., pAdapter %x", pAdapter ) );
|
|
|
|
|
|
return NdisStatus;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Routines begin here
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NDIS_STATUS
|
|
nicAllocateAddressRange_Synch (
|
|
IN PADAPTERCB pAdapter,
|
|
IN PMDL pMdl,
|
|
IN ULONG fulFlags,
|
|
IN ULONG nLength,
|
|
IN ULONG MaxSegmentSize,
|
|
IN ULONG fulAccessType,
|
|
IN ULONG fulNotificationOptions,
|
|
IN PVOID Callback,
|
|
IN PVOID Context,
|
|
IN ADDRESS_OFFSET Required1394Offset,
|
|
IN PSLIST_HEADER FifoSListHead,
|
|
IN PKSPIN_LOCK FifoSpinLock,
|
|
OUT PULONG pAddressesReturned,
|
|
IN OUT PADDRESS_RANGE p1394AddressRange,
|
|
OUT PHANDLE phAddressRange
|
|
)
|
|
// Function Description:
|
|
// Takes the parameter and just passes it down to the bus driver
|
|
// Arguments
|
|
//
|
|
// Return Value:
|
|
//
|
|
|
|
{
|
|
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicAllocateAddressRange_Synch, pAdapter %x, Offset %x", pAdapter, Required1394Offset ) );
|
|
|
|
TRACE (TL_V, TM_Irp, (" pMdl %x, fulFlags %x, nLength %x, MaxSegmentSize %x, fulAcessType %x",
|
|
pMdl, fulFlags, nLength, MaxSegmentSize, fulAccessType ) );
|
|
|
|
TRACE (TL_V, TM_Irp, (" fulNotification %x, Callback %x, Context %x, ReqOffset.High %x, ReqOffset.Low %x" ,
|
|
fulNotificationOptions, Callback, Context, Required1394Offset.Off_High, Required1394Offset.Off_Low ) );
|
|
|
|
TRACE (TL_V, TM_Irp, (" FifoSListHead %x, FifoSpinLock %x, p1394AddressRange %x" ,FifoSListHead, FifoSpinLock, p1394AddressRange ) )
|
|
do
|
|
{
|
|
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicAllocateAddressRange_Synch , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
|
|
NdisStatus = nicGetIrp (pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicAllocateAddressRange_Synch , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
pIrb->FunctionNumber = REQUEST_ALLOCATE_ADDRESS_RANGE;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.AllocateAddressRange.Mdl = pMdl; // Address to map to 1394 space
|
|
pIrb->u.AllocateAddressRange.fulFlags = fulFlags; // Flags for this operation
|
|
pIrb->u.AllocateAddressRange.nLength = nLength; // Length of 1394 space desired
|
|
pIrb->u.AllocateAddressRange.MaxSegmentSize = MaxSegmentSize; // Maximum segment size for a single address element
|
|
pIrb->u.AllocateAddressRange.fulAccessType = fulAccessType; // Desired access: R, W, L
|
|
pIrb->u.AllocateAddressRange.fulNotificationOptions = fulNotificationOptions; // Notify options on Async access
|
|
pIrb->u.AllocateAddressRange.Callback = Callback; // Pointer to callback routine
|
|
pIrb->u.AllocateAddressRange.Context = Context; // Pointer to driver supplied data
|
|
pIrb->u.AllocateAddressRange.Required1394Offset = Required1394Offset; // Offset that must be returned
|
|
pIrb->u.AllocateAddressRange.FifoSListHead = FifoSListHead; // Pointer to SList FIFO head
|
|
pIrb->u.AllocateAddressRange.FifoSpinLock = FifoSpinLock; // Pointer to SList Spin Lock
|
|
pIrb->u.AllocateAddressRange.p1394AddressRange = p1394AddressRange; // Address Range Returned
|
|
|
|
ASSERT ( pIrb->u.AllocateAddressRange.p1394AddressRange != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicAllocateAddressRange_Synch , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
//
|
|
// Update the output values
|
|
//
|
|
|
|
*pAddressesReturned = pIrb->u.AllocateAddressRange.AddressesReturned; // Number of addresses returned
|
|
p1394AddressRange = pIrb->u.AllocateAddressRange.p1394AddressRange; // Pointer to returned 1394 Address Ranges
|
|
*phAddressRange = pIrb->u.AllocateAddressRange.hAddressRange; // Handle to address range
|
|
|
|
TRACE (TL_V, TM_Irp, (" *pAddressesReturned %x, p1394AddressRange %x, phAddressRange %x," ,
|
|
*pAddressesReturned, p1394AddressRange, *phAddressRange ) );
|
|
} while (FALSE);
|
|
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicAllocateAddressRange_Synch, Status %x", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGet1394AddressOfRemoteNode(
|
|
IN PREMOTE_NODE pRemoteNode,
|
|
IN OUT NODE_ADDRESS *pNodeAddress,
|
|
IN ULONG fulFlags
|
|
)
|
|
// Function Description:
|
|
// This function will get the 1394 Address from the device object.
|
|
//
|
|
// Arguments
|
|
// PdoCb * Local Host's Pdo Control Block
|
|
// NodeAddress * Node Address structre wher the address will be returned in
|
|
// fulFlags - Could specify USE_LOCAL_HOST
|
|
//
|
|
// Return Value:
|
|
// Success if the irp succeeeded
|
|
// Failure: if the pdo is not active or the irp failed
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGet1394AddressOfRemoteNode, pRemoteNode %x, pNodeAdddress ", pRemoteNode, pNodeAddress) );
|
|
|
|
|
|
ASSERT (pNodeAddress != NULL);
|
|
do
|
|
{
|
|
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressOfRemoteNode, nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
pIrb->FunctionNumber = REQUEST_GET_ADDR_FROM_DEVICE_OBJECT;
|
|
pIrb->u.Get1394AddressFromDeviceObject.fulFlags = fulFlags;
|
|
|
|
NdisStatus = nicGetIrp (pRemoteNode->pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressOfRemoteNode, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_Synch (pRemoteNode,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressOfRemoteNode, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
(*pNodeAddress) = pIrb->u.Get1394AddressFromDeviceObject.NodeAddress;
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
|
|
nicFreeIrb(pIrb);
|
|
|
|
nicFreeIrp(pIrp);
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicGet1394AddressOfRemoteNode, Status %x, Address %x", NdisStatus, *pNodeAddress ) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGet1394AddressFromDeviceObject(
|
|
IN PDEVICE_OBJECT pPdo,
|
|
IN OUT NODE_ADDRESS *pNodeAddress,
|
|
IN ULONG fulFlags
|
|
)
|
|
// Function Description:
|
|
// This function will get the 1394 Address from the device object.
|
|
//
|
|
// Arguments
|
|
// PdoCb * Local Host's Pdo Control Block
|
|
// NodeAddress * Node Address structre wher the address will be returned in
|
|
// fulFlags - Could specify USE_LOCAL_HOST
|
|
//
|
|
// Return Value:
|
|
// Success if the irp succeeeded
|
|
// Failure: if the pdo is not active or the irp failed
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGet1394AddressFromDeviceObject, pPdo %x, pNodeAdddress ",
|
|
pPdo, pNodeAddress) );
|
|
|
|
|
|
ASSERT (pNodeAddress != NULL);
|
|
ASSERT (pPdo != NULL);
|
|
do
|
|
{
|
|
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
pIrb->Flags = 0;
|
|
pIrb->FunctionNumber = REQUEST_GET_ADDR_FROM_DEVICE_OBJECT;
|
|
pIrb->u.Get1394AddressFromDeviceObject.fulFlags = fulFlags;
|
|
|
|
NdisStatus = nicGetIrp (pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_PDOSynch (pPdo,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
(*pNodeAddress) = pIrb->u.Get1394AddressFromDeviceObject.NodeAddress;
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
|
|
nicFreeIrb(pIrb);
|
|
|
|
nicFreeIrp(pIrp);
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicGet1394AddressFromDeviceObject, Status %x, Address %x", NdisStatus, *pNodeAddress ) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGetGenerationCount(
|
|
IN PADAPTERCB pAdapter,
|
|
IN OUT PULONG GenerationCount
|
|
)
|
|
// This function returns the generation count of the Device Object that PDO points to.
|
|
//
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
PDEVICE_OBJECT pDeviceObject = pAdapter->pNextDeviceObject;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGetGenerationCount, PDO %x, pVc %x", pDeviceObject ) );
|
|
|
|
|
|
|
|
ASSERT( pDeviceObject != NULL);
|
|
|
|
|
|
|
|
do
|
|
{
|
|
|
|
NdisStatus = nicGetIrb( &pIrb );
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "Failed to allocate an Irb in nicGetGenerationCout") );
|
|
NdisStatus = NDIS_STATUS_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
NdisStatus = nicGetIrp (pDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "Failed to allocate an Irp in nicGetGenerationCout") );
|
|
NdisStatus = NDIS_STATUS_RESOURCES;
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
pIrb->FunctionNumber = REQUEST_GET_GENERATION_COUNT;
|
|
pIrb->Flags = 0;
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter, pIrp, pIrb);
|
|
|
|
if (NdisStatus == NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
*GenerationCount = pIrb->u.GetGenerationCount.GenerationCount;
|
|
|
|
TRACE( TL_N, TM_Irp, ("GenerationCount = 0x%x\n", *GenerationCount) );
|
|
}
|
|
else
|
|
{
|
|
|
|
TRACE(TL_A, TM_Irp, ("SubmitIrpSync failed = 0x%x\n", NdisStatus));
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
|
|
} while(FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
|
|
nicFreeIrb(pIrb);
|
|
|
|
nicFreeIrp(pIrp);
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicGetGenerationCount, PDO %x, Generation %x", pDeviceObject, *GenerationCount) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicFreeAddressRange(
|
|
IN PADAPTERCB pAdapter,
|
|
IN ULONG nAddressesToFree,
|
|
IN PADDRESS_RANGE p1394AddressRange,
|
|
IN PHANDLE phAddressRange
|
|
)
|
|
// Function Description:
|
|
// This is the generic call to free an address range. It is the callers responsibility to figure out
|
|
// the reference counting on the RemoteNode
|
|
// This is because in the RecvFIFO code path we allocate one address range on each remote node
|
|
// whereas in the Broadcast channel register, we allocate one addreesss on ONE remote node only
|
|
//
|
|
// Arguments
|
|
// pRemoteNode, - Remote Node used to submit the IRP
|
|
// nAddressesToFree, - Number of addreses to free
|
|
// p1394AddressRange, - pointer to the address range which was allocated
|
|
// phAddressRange - Handle returned by the bus driver
|
|
//
|
|
// Return Value:
|
|
// Success if the irp succeeeded
|
|
// Failure: if the pdo is not active or the irp failed
|
|
//
|
|
|
|
{
|
|
|
|
PIRP pIrp = NULL;
|
|
PIRB pIrb = NULL;
|
|
PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicFreeAddressRange pAdapter %x", pAdapter ) );
|
|
|
|
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
|
|
|
do
|
|
{
|
|
|
|
if (pPdo == NULL)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "pPdo is NULL in nicFreeRecvFifoAddressRange" ) );
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
break;
|
|
}
|
|
|
|
|
|
NdisStatus = nicGetIrb(&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicFreeRecvFifoAddressRange" ) );
|
|
break;
|
|
}
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicFreeRecvFifoAddressRange" ) );
|
|
break;
|
|
}
|
|
|
|
TRACE (TL_V, TM_Cm, (" NumAddresses %x, hAddressRange %x, Hi %x, Length %x, Lo %x",
|
|
nAddressesToFree,
|
|
phAddressRange,
|
|
p1394AddressRange->AR_Off_High,
|
|
p1394AddressRange->AR_Length,
|
|
p1394AddressRange->AR_Off_Low ) );
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_FREE_ADDRESS_RANGE;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.FreeAddressRange.nAddressesToFree = nAddressesToFree;
|
|
pIrb->u.FreeAddressRange.p1394AddressRange = p1394AddressRange;
|
|
pIrb->u.FreeAddressRange.pAddressRange = phAddressRange;
|
|
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Free the locally allocated memory
|
|
//
|
|
nicFreeIrb(pIrb);
|
|
|
|
nicFreeIrp(pIrp);
|
|
|
|
|
|
//
|
|
// We do not care about the status, because we do not know what to do if it fails.
|
|
// However, spew some debug out.
|
|
//
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_N, TM_Irp, ( "nicFreeAddressRangeFAILED %x", NdisStatus) );
|
|
|
|
ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicFreeAddressRangeStatus %x (always success)", NdisStatus) );
|
|
|
|
NdisStatus = NDIS_STATUS_SUCCESS;
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
nicFreeAddressRangeDebugSpew(
|
|
IN PIRB pIrb
|
|
)
|
|
// This functions spews out the parameters in a Free Address Range Irb
|
|
//
|
|
//
|
|
{
|
|
|
|
|
|
TRACE( TL_V, TM_Irp, ( "==>nicFreeAddressRangeDebugSpew, pIrb = %x", pIrb) );
|
|
ASSERT(pIrb != NULL);
|
|
|
|
TRACE( TL_N, TM_Irp, ( "Num Addresses Returned %x ",pIrb->u.FreeAddressRange.nAddressesToFree ) );
|
|
TRACE( TL_N, TM_Irp, ( "Address High %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Off_High ) );
|
|
TRACE( TL_N, TM_Irp, ( "Address Low %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Off_Low ) );
|
|
TRACE( TL_N, TM_Irp, ( "Address Length %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Length ) );
|
|
TRACE( TL_N, TM_Irp, ( "Handle %x", pIrb->u.FreeAddressRange.pAddressRange ) );
|
|
|
|
TRACE( TL_V, TM_Irp, ( "<==nicFreeAddressRangeDebugSpew " ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicFreeChannel(
|
|
IN PADAPTERCB pAdapter,
|
|
IN ULONG nChannel
|
|
)
|
|
// Function Description:
|
|
// This function sends an Irp to the Bus driver to free a channel
|
|
// Any remote Pdo can be used for the Irp. However for the sake of
|
|
// bookkeeping use the same Pdo that the channel was allocated on (maybe)
|
|
// Arguments
|
|
// PdoCb The Pdo for the remote node to which the Irp is submitted
|
|
// Channel Pointer The Channel, requested and the channel returned
|
|
//
|
|
// Return Value:
|
|
// Success if the channel was allocated
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
|
|
PIRP pIrp = NULL;
|
|
PIRB pIrb = NULL;
|
|
PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicFreeChannel pAdapter %x, Channel %x", pAdapter, nChannel) );
|
|
|
|
ASSERT (pAdapter!= NULL);
|
|
ASSERT (pPdo != NULL);
|
|
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
|
|
|
do
|
|
{
|
|
|
|
if (pPdo == NULL)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "pPdo is NULL in nicFreeChannel" ) );
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
break;
|
|
}
|
|
|
|
|
|
NdisStatus = nicGetIrb(&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicFreeChannel" ) );
|
|
break;
|
|
}
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicFreeChannel" ) );
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_FREE_CHANNEL;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochFreeChannel.nChannel = nChannel;
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
//
|
|
// Regardless update the mask, as the channel could have been freed by a bus reset
|
|
//
|
|
if (nChannel != BROADCAST_CHANNEL)
|
|
{
|
|
ADAPTER_ACQUIRE_LOCK (pAdapter);
|
|
|
|
|
|
//
|
|
// Clear the channel in the mask
|
|
//
|
|
pAdapter->ChannelsAllocatedByLocalHost &= (~( g_ullOne <<nChannel ));
|
|
|
|
ADAPTER_RELEASE_LOCK (pAdapter);
|
|
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Free the locally allocated memory
|
|
//
|
|
nicFreeIrb(pIrb);
|
|
|
|
nicFreeIrp(pIrp);
|
|
|
|
|
|
//
|
|
// We do not care about the status, because we do not know what to do if it fails.
|
|
// However, spew some debug out.
|
|
//
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_N, TM_Irp, ( "nicFreeChannel FAILED %x", NdisStatus) );
|
|
}
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicFreeChannel Status %x ", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicAllocateChannel (
|
|
IN PADAPTERCB pAdapter,
|
|
IN ULONG Channel,
|
|
OUT PULARGE_INTEGER pChannelsAvailable OPTIONAL
|
|
)
|
|
// Function Description:
|
|
// This function sends an Irp to the Bus driver to allocate a channel
|
|
// Any remote Pdo can be used for the Irp
|
|
//
|
|
// Arguments
|
|
// PdoCb The Pdo for the remote node to which the Irp is submitted
|
|
// Channel -The Channel, requested and the channel returned
|
|
//
|
|
// Return Value:
|
|
// Success if the channel was allocated
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
PDEVICE_OBJECT pDeviceObject = pAdapter->pNextDeviceObject;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateChannel, PdoCb, %x Channel %d", pAdapter, Channel ) );
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_CHANNEL;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochAllocateChannel.nRequestedChannel = Channel;
|
|
|
|
ASSERT (Channel < 64);
|
|
|
|
NdisStatus = nicGetIrp ( pDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
if (pChannelsAvailable != NULL)
|
|
{
|
|
pChannelsAvailable->QuadPart = pIrb->u.IsochAllocateChannel.ChannelsAvailable.QuadPart;
|
|
|
|
}
|
|
|
|
|
|
TRACE( TL_N, TM_Irp, ( "Channel allocated %d", Channel ) );
|
|
|
|
if (Channel != BROADCAST_CHANNEL)
|
|
{
|
|
|
|
ADAPTER_ACQUIRE_LOCK (pAdapter);
|
|
|
|
|
|
//
|
|
// Set the channel in the mask
|
|
//
|
|
pAdapter->ChannelsAllocatedByLocalHost |= ( g_ullOne <<Channel );
|
|
|
|
ADAPTER_RELEASE_LOCK (pAdapter);
|
|
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateChannel, Channel %d, Status %x", Channel, NdisStatus ) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicQueryChannelMap (
|
|
IN PADAPTERCB pAdapter,
|
|
OUT PULARGE_INTEGER pChannelsAvailable
|
|
)
|
|
// Function Description:
|
|
// This function sends an Irp to the Bus driver to allocate a channel
|
|
// Any remote Pdo can be used for the Irp
|
|
//
|
|
// Arguments
|
|
// PdoCb The Pdo for the remote node to which the Irp is submitted
|
|
// Channel -The Channel, requested and the channel returned
|
|
//
|
|
// Return Value:
|
|
// Success if the channel was allocated
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
PDEVICE_OBJECT pDeviceObject = pAdapter->pNextDeviceObject;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicQueryChannelMap , PdoCb, %x ", pAdapter) );
|
|
|
|
do
|
|
{
|
|
if (pChannelsAvailable == NULL)
|
|
{
|
|
ASSERT (pChannelsAvailable != NULL);
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
break;
|
|
}
|
|
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_QUERY_RESOURCES ;
|
|
pIrb->u.IsochQueryResources.fulSpeed = SPEED_FLAGS_100;
|
|
pIrb->Flags = 0;
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// We get the *available* channels, in network-byte order.
|
|
// We have to byte reverse and flip the bits to get
|
|
// it in the form we want.
|
|
//
|
|
// Looks like we really have to flip the *bits*, not just the bytes.
|
|
//
|
|
{
|
|
LARGE_INTEGER in, out;
|
|
PUCHAR puc;
|
|
UINT u;
|
|
in = pIrb->u.IsochQueryResources.ChannelsAvailable;
|
|
out.LowPart = ~SWAPBYTES_ULONG (in.HighPart );
|
|
out.HighPart = ~SWAPBYTES_ULONG (in.LowPart );
|
|
|
|
// Now swap the bits in each byte.
|
|
//
|
|
puc = (PUCHAR) &out;
|
|
for (u=sizeof(out); u; u--,puc++)
|
|
{
|
|
UCHAR uc,uc1;
|
|
UINT u1;
|
|
uc= *puc;
|
|
uc1=0;
|
|
for (u1=0;u1<8;u1++)
|
|
{
|
|
if (uc & (1<<u1))
|
|
{
|
|
uc1 |= (1 << (7-u1));
|
|
}
|
|
}
|
|
*puc = uc1;
|
|
}
|
|
|
|
pChannelsAvailable->QuadPart = out.QuadPart;
|
|
}
|
|
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicQueryChannelMap , , Status %x", NdisStatus ) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
nicIsochAllocateBandwidth(
|
|
IN PREMOTE_NODE pRemoteNodePdoCb,
|
|
IN ULONG MaxBytesPerFrameRequested,
|
|
IN ULONG SpeedRequested,
|
|
OUT PHANDLE phBandwidth,
|
|
OUT PULONG pBytesPerFrameAvailable,
|
|
OUT PULONG pSpeedSelected
|
|
)
|
|
|
|
// Function Description:
|
|
// This function allocates bandwith on the bus
|
|
//
|
|
// Arguments
|
|
// PdoCb - Remote Nodes Pdo Block
|
|
// MaxBytesPerFrame Requested -
|
|
// SpeedRequested -
|
|
// hBandwidth
|
|
// pSpeedSelected
|
|
// Bytes Per Frame Available
|
|
//
|
|
//
|
|
// Return Value:
|
|
// hBandwidth,
|
|
// Speed and
|
|
// BytesPerFrameAvailable
|
|
//
|
|
//
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateBandwidth, pRemoteNodePdoCb %x", pRemoteNodePdoCb) );
|
|
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
BREAK( TM_Irp, ( "nicIsochAllocateBandwidth, nicGetIrb FAILED" ) );
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_BANDWIDTH;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochAllocateBandwidth.nMaxBytesPerFrameRequested = MaxBytesPerFrameRequested;
|
|
pIrb->u.IsochAllocateBandwidth.fulSpeed = SpeedRequested;
|
|
|
|
|
|
ASSERT (pRemoteNodePdoCb->pPdo != NULL);
|
|
|
|
NdisStatus = nicGetIrp (pRemoteNodePdoCb->pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
BREAK( TM_Irp, ( "nicIsochAllocateBandwidth, nicGetIrp FAILED" ) );
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_Synch ( pRemoteNodePdoCb,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE (TL_N, TM_Irp, ( "nicIsochAllocateBandwidth, nicSubmitIrp_Synch FAILED ") );
|
|
break;
|
|
}
|
|
|
|
*phBandwidth = pIrb->u.IsochAllocateBandwidth.hBandwidth ;
|
|
*pBytesPerFrameAvailable = pIrb->u.IsochAllocateBandwidth.BytesPerFrameAvailable;
|
|
*pSpeedSelected = pIrb->u.IsochAllocateBandwidth.SpeedSelected;
|
|
|
|
TRACE( TL_V, TM_Irp, ( "hBandwidth %x", *phBandwidth) );
|
|
TRACE( TL_V, TM_Irp, ( "BytesPerFrameAvailable %x", *pBytesPerFrameAvailable) );
|
|
TRACE( TL_V, TM_Irp, ( "SpeedSelected %x", *pSpeedSelected) );
|
|
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateBandwidth NdisStatus %x", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicAsyncRead_Synch(
|
|
PREMOTE_NODE pRemoteNode,
|
|
IO_ADDRESS DestinationAddress,
|
|
ULONG nNumberOfBytesToRead,
|
|
ULONG nBlockSize,
|
|
ULONG fulFlags,
|
|
PMDL Mdl,
|
|
ULONG ulGeneration,
|
|
OUT NTSTATUS *pNtStatus
|
|
)
|
|
|
|
|
|
// Function Description:
|
|
// This is an asyc read operation a remote node;s address space
|
|
//
|
|
//
|
|
//
|
|
//
|
|
// Arguments
|
|
//PREMOTE_NODE pRemoteNode // Remote Node which owns the Destination address
|
|
// IO_ADDRESS DestinationAddress; // Address to read from
|
|
// ULONG nNumberOfBytesToRead; // Bytes to read
|
|
// ULONG nBlockSize; // Block size of read
|
|
// ULONG fulFlags; // Flags pertinent to read
|
|
// PMDL Mdl; // Destination buffer
|
|
// ULONG ulGeneration; // Generation as known by driver
|
|
//
|
|
// Return Value:
|
|
// Success - if successful
|
|
// Invalid Generation
|
|
//
|
|
//
|
|
{
|
|
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Mp, ( "==>nicAsyncRead, Remote Node, %x ", pRemoteNode ) );
|
|
|
|
|
|
|
|
TRACE( TL_V, TM_Mp, ( " fulFlags %x, Mdl %x, Generation %x, pNtStatus %x",
|
|
fulFlags, Mdl, ulGeneration, pNtStatus ) );
|
|
|
|
ASSERT(DestinationAddress.IA_Destination_Offset.Off_High == INITIAL_REGISTER_SPACE_HI);
|
|
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
BREAK ( TM_Irp, ( "nicAsyncRead, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
BREAK ( TM_Irp, ( "nicAsyncRead, nicGetIrb FAILED" ) );
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
|
|
pIrb->FunctionNumber = REQUEST_ASYNC_READ;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.AsyncRead.DestinationAddress = DestinationAddress;
|
|
pIrb->u.AsyncRead.nNumberOfBytesToRead = nNumberOfBytesToRead ;
|
|
pIrb->u.AsyncRead.nBlockSize = nBlockSize ;
|
|
pIrb->u.AsyncRead.fulFlags = fulFlags;
|
|
pIrb->u.AsyncRead.Mdl = Mdl;
|
|
pIrb->u.AsyncRead.ulGeneration = ulGeneration;
|
|
|
|
NdisStatus = nicSubmitIrp_Synch ( pRemoteNode,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE ( TL_A, TM_Irp, ( "nicAsyncRead, nicSubmitIrp_Synch FAILED %xm pRemoteNode %x", NdisStatus, pRemoteNode) );
|
|
break;
|
|
}
|
|
|
|
if (pNtStatus != NULL)
|
|
{
|
|
*pNtStatus = pIrp->IoStatus.Status;
|
|
}
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Mp, ( "<==nicAsyncRead, Status, %x ", NdisStatus) );
|
|
|
|
nicFreeIrb(pIrb);
|
|
|
|
nicFreeIrp(pIrp);
|
|
|
|
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicAsyncWrite_Synch(
|
|
PREMOTE_NODE pRemoteNode,
|
|
IO_ADDRESS DestinationAddress, // Address to write to
|
|
ULONG nNumberOfBytesToWrite, // Bytes to write
|
|
ULONG nBlockSize, // Block size of write
|
|
ULONG fulFlags, // Flags pertinent to write
|
|
PMDL Mdl, // Destination buffer
|
|
ULONG ulGeneration, // Generation as known by driver
|
|
OUT NTSTATUS *pNtStatus // pointer to NTSTatus returned by the IRP
|
|
)
|
|
|
|
|
|
|
|
// Function Description:
|
|
// This performs an asynchronous write operation in thje remote node's
|
|
// address space
|
|
//
|
|
// Arguments
|
|
//PREMOTE_NODE pRemoteNode // Remote Node which owns the Destination address
|
|
//IO_ADDRESS DestinationAddress; // Address to write to
|
|
//ULONG nNumberOfBytesToWrite; // Bytes to write
|
|
//ULONG nBlockSize; // Block size of write
|
|
//ULONG fulFlags; // Flags pertinent to write
|
|
//PMDL Mdl; // Destination buffer
|
|
//ULONG ulGeneration; // Generation as known by driver
|
|
//
|
|
// Return Value:
|
|
// Success - if successful
|
|
// Invalid Generation
|
|
//
|
|
//
|
|
{
|
|
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Mp, ( "==>nicAsyncWrite_Synch, Remote Node, %x ", pRemoteNode ) );
|
|
|
|
|
|
TRACE( TL_V, TM_Mp, ( " Destination %x, nNumberOfBytesToWrite %x, nBlockSize %x",
|
|
DestinationAddress, nNumberOfBytesToWrite, nBlockSize) );
|
|
|
|
|
|
TRACE( TL_V, TM_Mp, ( " fulFlags %x, , Mdl %x, Generation %x, pNtStatus %x",
|
|
fulFlags , Mdl, ulGeneration, pNtStatus ) );
|
|
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
BREAK ( TM_Irp, ( "nicAsyncWrite_Synch, nicGetIrb FAILED" ) );
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
pIrb->FunctionNumber = REQUEST_ASYNC_WRITE;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.AsyncWrite.DestinationAddress = DestinationAddress;
|
|
pIrb->u.AsyncWrite.nNumberOfBytesToWrite = nNumberOfBytesToWrite;
|
|
pIrb->u.AsyncWrite.nBlockSize = nBlockSize;
|
|
pIrb->u.AsyncWrite.fulFlags = fulFlags;
|
|
pIrb->u.AsyncWrite.Mdl = Mdl;
|
|
pIrb->u.AsyncWrite.ulGeneration = ulGeneration;
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
BREAK ( TM_Irp, ( "nicAsyncWrite_Synch, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_Synch ( pRemoteNode,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE ( TL_A, TM_Irp, ( "nicAsyncWrite_Synch, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
if (pNtStatus != NULL)
|
|
{
|
|
*pNtStatus = pIrp->IoStatus.Status;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
TRACE( TL_T, TM_Mp, ( "<==nicAsyncWrite_Synch, Success , %x Nt %x", NdisStatus, pIrp->IoStatus.Status) );
|
|
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicIsochAllocateResources (
|
|
IN PADAPTERCB pAdapter,
|
|
IN ULONG fulSpeed, // Speed flags
|
|
IN ULONG fulFlags, // Flags
|
|
IN ULONG nChannel, // Channel to be used
|
|
IN ULONG nMaxBytesPerFrame, // Expected size of Isoch frame
|
|
IN ULONG nNumberOfBuffers, // Number of buffer(s) that will be attached
|
|
IN ULONG nMaxBufferSize, // Max size of buffer(s)
|
|
IN ULONG nQuadletsToStrip, // Number striped from start of every packet
|
|
IN ULARGE_INTEGER uliChannelMask, // ChannelMask for Multiple channels
|
|
IN OUT PHANDLE phResource // handle to Resource
|
|
)
|
|
// Function Description:
|
|
// This function sends an allocate resources irp to the driver. The miniport must do this before it
|
|
// attempts any channel operation
|
|
// Arguments
|
|
// Taken from documentation for the IsochAllocateResources
|
|
// fulSpeed - should be the max speed the tx side is expected to stream
|
|
// The payload size in nMaxBytesPerFram cannot exceed the max payload for
|
|
// for this speed.
|
|
// fulFlags - For receive, wtih the standard header stripped, the field should
|
|
// be = (RESOURCE_USED_IN_LISTEN | RESOURCES_STRIP_ADDITIONAL_QUADLETS)
|
|
// Also nQuadletsToStrip = 1
|
|
// For no stripping set nQuadsTostrip to 0 and dont specify the stripping flag.
|
|
// nMaxBytesPerframe - If not stripping it should include the 8 bytes for header/trailer
|
|
// expected to be recieved for each packet.
|
|
// nNumberOfBuffer - see below
|
|
// nMaxBufferSize - This should be always such mode(nMaxBufferSize,nMaxBytesPerFrame) == 0
|
|
// (integer product of number of bytes per packet).
|
|
// nQuadletsTostrip - If stripping only one quadlet (standrd iso header) this is set to 1
|
|
// if zero, the isoch header will be included AND the trailer. So 8 bytes extra will be recieved
|
|
// hResource - see below
|
|
|
|
// Return Value:
|
|
// Success if the channel was allocated
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateResources ") );
|
|
ASSERT (fulSpeed != 0); // 0 is undefined in ISOCH_SP...
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_RESOURCES;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochAllocateResources.fulSpeed = fulSpeed;
|
|
pIrb->u.IsochAllocateResources.fulFlags = fulFlags;
|
|
pIrb->u.IsochAllocateResources.nChannel = nChannel;
|
|
pIrb->u.IsochAllocateResources.nMaxBytesPerFrame = nMaxBytesPerFrame;
|
|
pIrb->u.IsochAllocateResources.nNumberOfBuffers = nNumberOfBuffers;
|
|
pIrb->u.IsochAllocateResources.nMaxBufferSize = nMaxBufferSize;
|
|
pIrb->u.IsochAllocateResources.nQuadletsToStrip = nQuadletsToStrip;
|
|
pIrb->u.IsochAllocateResources.ChannelMask = uliChannelMask;
|
|
|
|
nicIsochAllocateResourcesDebugSpew(pIrb);
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
|
|
TRACE( TL_N, TM_Irp, ( "nicIsochAllocateResources Succeeded hResource %x", pIrb->u.IsochAllocateResources.hResource) );
|
|
|
|
*phResource = pIrb->u.IsochAllocateResources.hResource;
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateResources , Status %x, hResource %x", NdisStatus, *phResource ) );
|
|
|
|
MATCH_IRQL;
|
|
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
VOID
|
|
nicIsochAllocateResourcesDebugSpew(
|
|
IN PIRB pIrb)
|
|
{
|
|
|
|
|
|
|
|
TRACE( TL_V, TM_Irp, ( " Speed %x", pIrb->u.IsochAllocateResources.fulSpeed ) );
|
|
TRACE( TL_V, TM_Irp, ( " flags %x", pIrb->u.IsochAllocateResources.fulFlags ) );
|
|
TRACE( TL_V, TM_Irp, ( " Channel %x", pIrb->u.IsochAllocateResources.nChannel ) );
|
|
TRACE( TL_V, TM_Irp, ( " nMaxBytesPerFrame %x", pIrb->u.IsochAllocateResources.nMaxBytesPerFrame ) );
|
|
TRACE( TL_V, TM_Irp, ( " nNumberOfBuffers %x", pIrb->u.IsochAllocateResources.nNumberOfBuffers ) );
|
|
TRACE( TL_V, TM_Irp, ( " nMaxBufferSize %x", pIrb->u.IsochAllocateResources.nMaxBufferSize ) );
|
|
TRACE( TL_V, TM_Irp, ( " nQuadletsToStrip %x", pIrb->u.IsochAllocateResources.nQuadletsToStrip ) );
|
|
TRACE( TL_V, TM_Irp, ( " pIrb->u.IsochAllocateResources.ChannelMask %I64x", pIrb->u.IsochAllocateResources.ChannelMask ) );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicIsochFreeResources(
|
|
IN PADAPTERCB pAdapter,
|
|
IN HANDLE hResource
|
|
)
|
|
// Function Description:
|
|
// Arguments
|
|
//
|
|
// Return Value:
|
|
//
|
|
|
|
{
|
|
|
|
PIRP pIrp = NULL;
|
|
PIRB pIrb = NULL;
|
|
PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochFreeResources pAdapter %x, hResource %8x", pAdapter, hResource) );
|
|
|
|
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
|
ASSERT (hResource != NULL);
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb(&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicIsochFreeResources" ) );
|
|
break;
|
|
}
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicIsochFreeResources" ) );
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochFreeResources.hResource = hResource;
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Free the locally allocated memory
|
|
//
|
|
nicFreeIrb(pIrb);
|
|
|
|
nicFreeIrp(pIrp);
|
|
|
|
|
|
//
|
|
// We do not care about the status, because we do not know what to do if it fails.
|
|
// However, spew some debug out.
|
|
//
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_N, TM_Irp, ( "nicIsochFreeResources FAILED %x", NdisStatus) );
|
|
|
|
ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicIsochFreeResources Status %x (always success)", NdisStatus) );
|
|
|
|
NdisStatus = NDIS_STATUS_SUCCESS;
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicIsochModifyStreamProperties (
|
|
PADAPTERCB pAdapter,
|
|
NDIS_HANDLE hResource,
|
|
ULARGE_INTEGER ullChannelMap,
|
|
ULONG ulSpeed)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Sets up the Irp and uses the VDO to do an IoCallDriver
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
PIRP pIrp = NULL;
|
|
PIRB pIrb = NULL;
|
|
PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochModifyStreamProperties pAdapter %x, hResource %x, Speed %x, ChannelMap %I64x",
|
|
pAdapter,
|
|
hResource,
|
|
ulSpeed,
|
|
ullChannelMap) );
|
|
|
|
ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
|
ASSERT (hResource != NULL);
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb(&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicIsochModifyStreamProperties " ) );
|
|
break;
|
|
}
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicIsochModifyStreamProperties " ) );
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_MODIFY_STREAM_PROPERTIES ;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochModifyStreamProperties.hResource = hResource;
|
|
pIrb->u.IsochModifyStreamProperties.ChannelMask = ullChannelMap;
|
|
pIrb->u.IsochModifyStreamProperties.fulSpeed = ulSpeed;
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Free the locally allocated memory
|
|
//
|
|
nicFreeIrb(pIrb);
|
|
|
|
nicFreeIrp(pIrp);
|
|
|
|
|
|
//
|
|
// We do not care about the status, because we do not know what to do if it fails.
|
|
// However, spew some debug out.
|
|
//
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_N, TM_Irp, ( "nicIsochModifyStreamProperties FAILED %x", NdisStatus) );
|
|
|
|
ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicIsochModifyStreamProperties Status %x (always success)", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicBusReset (
|
|
IN PADAPTERCB pAdapter,
|
|
IN OUT ULONG fulFlags
|
|
)
|
|
// Function Description:
|
|
// This function sends an Irp to the Bus driver to reset the bus
|
|
// Any remote Pdo can be used for the Irp.
|
|
// A flag can be set to force the root to be reset
|
|
// Arguments
|
|
// PdoCb The Pdo for the remote node to which the Irp is submitted
|
|
//
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicBusReset , PdoCb, %x Flags %x", pAdapter, fulFlags ) );
|
|
ASSERT (pPdo != NULL);
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicBusReset , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_BUS_RESET;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.BusReset.fulFlags = fulFlags;
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicBusReset, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
TRACE( TL_N, TM_Irp, ( "BUS RESET, Flags%d on pAdapter %x", fulFlags, pAdapter) );
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicBusReset , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
NdisInterlockedIncrement (&pAdapter->AdaptStats.ulNumResetsIssued);
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicBusReset %x", NdisStatus ) );
|
|
MATCH_IRQL;
|
|
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
nicBusResetNotification (
|
|
IN PADAPTERCB pAdapter,
|
|
IN ULONG fulFlags,
|
|
IN PBUS_BUS_RESET_NOTIFICATION pResetRoutine,
|
|
IN PVOID pResetContext
|
|
)
|
|
// Function Description:
|
|
// This function sends an Irp to the Bus driver to register/deregister
|
|
// a notification routine. Any remote Pdo can be used for the Irp.
|
|
//
|
|
// Arguments
|
|
// PdoCb The Pdo for the remote node to which the Irp is submitted
|
|
//
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicBusResetNotification, pAdapter %x, Flags %x, Routine %x, Context %x", pAdapter, fulFlags, pResetRoutine, pResetContext ) );
|
|
|
|
ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_BUS_RESET_NOTIFICATION;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.BusResetNotification.fulFlags = fulFlags;
|
|
pIrb->u.BusResetNotification.ResetRoutine = pResetRoutine;
|
|
pIrb->u.BusResetNotification.ResetContext= pResetContext;
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
TRACE( TL_N, TM_Irp, ( " nicBusResetNotification success, Flags %d on pAdapter %x", fulFlags, pAdapter) );
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<==nicBusResetNotification %x", NdisStatus ) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGetMaxSpeedBetweenDevices (
|
|
PADAPTERCB pAdapter,
|
|
UINT NumOfRemoteNodes,
|
|
PDEVICE_OBJECT pArrayDestinationPDO[MAX_LOCAL_NODES],
|
|
PULONG pSpeed
|
|
)
|
|
// Function Description:
|
|
// This function submits an irp to the bus driver
|
|
// to get the max speed between 2 nodes
|
|
// Uses REQUEST_GET_SPEED_BETWEEN_DEVICES
|
|
//
|
|
//
|
|
// Arguments
|
|
// Remote Node Start of an array of PDOs for remote nodes
|
|
// NumOfRemoteNodes The number of remote nodes we are interested in
|
|
// pArrayDestinationPDO = Array of Destination PDO's
|
|
// Return Value:
|
|
// Success if irp succeeded
|
|
// pSpeed will point to the Speed
|
|
//
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
ULONG NumRemote = NumOfRemoteNodes;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGetMaxSpeedBetweenDevices pRemoteNodeArray %x",
|
|
pArrayDestinationPDO ) );
|
|
TRACE( TL_T, TM_Irp, ( "==>NumOfRemoteNodes %x, pSpeed %x",
|
|
NumOfRemoteNodes, pSpeed ) );
|
|
|
|
do
|
|
{
|
|
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
while (NumRemote != 0)
|
|
{
|
|
pIrb->u.GetMaxSpeedBetweenDevices.hDestinationDeviceObjects[NumRemote-1] = pArrayDestinationPDO[NumRemote-1];
|
|
NumRemote --;
|
|
}
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_GET_SPEED_BETWEEN_DEVICES;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.GetMaxSpeedBetweenDevices.fulFlags = USE_LOCAL_NODE;
|
|
pIrb->u.GetMaxSpeedBetweenDevices.ulNumberOfDestinations = NumOfRemoteNodes;
|
|
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
*pSpeed = pIrb->u.GetMaxSpeedBetweenDevices.fulSpeed ;
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicGetMaxSpeedBetweenDevices Status %x, Speed %x",
|
|
NdisStatus, *pSpeed ) );
|
|
|
|
|
|
|
|
return NdisStatus;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicIsochAttachBuffers (
|
|
IN PADAPTERCB pAdapter,
|
|
IN HANDLE hResource,
|
|
IN ULONG nNumberOfDescriptors,
|
|
PISOCH_DESCRIPTOR pIsochDescriptor
|
|
)
|
|
// Function Description:
|
|
//
|
|
// Arguments
|
|
//
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
ASSERT (pIsochDescriptor!=NULL);
|
|
ASSERT (hResource != NULL);
|
|
ASSERT (nNumberOfDescriptors > 0);
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochAttachBuffers, pAdapter, %x ", pAdapter) );
|
|
TRACE( TL_N, TM_Irp, ( "hResource %x, nNumberOfDescriptors %x, pIsochDescriptor %x, ", hResource, nNumberOfDescriptors, pIsochDescriptor ) );
|
|
|
|
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers, nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_ATTACH_BUFFERS;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochAttachBuffers.hResource = hResource ;
|
|
pIrb->u.IsochAttachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
|
|
pIrb->u.IsochAttachBuffers.pIsochDescriptor = pIsochDescriptor;
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
TRACE( TL_N, TM_Irp, ( "nicIsochAttachBuffers success") );
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<==nicIsochAttachBuffers %x", NdisStatus ) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
NDIS_STATUS
|
|
nicIsochDetachBuffers (
|
|
IN PADAPTERCB pAdapter,
|
|
IN HANDLE hResource,
|
|
IN ULONG nNumberOfDescriptors,
|
|
PISOCH_DESCRIPTOR pIsochDescriptor
|
|
)
|
|
// Function Description:
|
|
//
|
|
// Arguments
|
|
// HANDLE hResource; // Resource handle
|
|
// ULONG nNumberOfDescriptors; // Number to detach
|
|
// PISOCH_DESCRIPTOR pIsochDescriptor; // Pointer to Isoch descriptors - same as
|
|
// pointer used in Attach Buffers
|
|
// Return Status :
|
|
// Success if the Irp succeeded
|
|
//
|
|
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
ASSERT (pIsochDescriptor!=NULL);
|
|
ASSERT (hResource != NULL);
|
|
ASSERT (nNumberOfDescriptors > 0);
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochDetachBuffers, ") );
|
|
TRACE( TL_V, TM_Irp, ( "hResource %x, nNumberOfDescriptors %x, pIsochDescriptor %x, ", hResource, nNumberOfDescriptors, pIsochDescriptor ) );
|
|
|
|
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers, nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_DETACH_BUFFERS;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochDetachBuffers.hResource = hResource ;
|
|
pIrb->u.IsochDetachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
|
|
pIrb->u.IsochDetachBuffers.pIsochDescriptor = pIsochDescriptor;
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
TRACE( TL_V, TM_Irp, ( "nicIsochDetachBuffers success, ") );
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<==nicIsochDetachBuffers %x", NdisStatus ) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicIsochListen (
|
|
IN PADAPTERCB pAdapter,
|
|
HANDLE hResource,
|
|
ULONG fulFlags,
|
|
CYCLE_TIME StartTime
|
|
)
|
|
// Function Description:
|
|
// Activates the bus driver to listen to data on that channel
|
|
// Arguments
|
|
// RemoteNode - Remote Node
|
|
// hResource - Handle to resource with ISochDescriptors
|
|
// Flags - not used yet
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
ASSERT (hResource != NULL);
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochListen, pAdapter %x, hResource %x ", pAdapter,hResource) );
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochListen, nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_LISTEN;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochListen.hResource = hResource ;
|
|
pIrb->u.IsochListen.fulFlags = fulFlags;
|
|
pIrb->u.IsochListen.StartTime = StartTime;
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochListen , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochListen , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
TRACE( TL_N, TM_Irp, ( "nicIsochListen success, pAdapter %x", pAdapter) );
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<==nicIsochListen %x", NdisStatus ) );
|
|
|
|
return NdisStatus;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicIsochStop (
|
|
IN PADAPTERCB pAdapter,
|
|
IN HANDLE hResource
|
|
)
|
|
// Function Description:
|
|
// Issues an IsochStop Irp to the Device
|
|
// Should stop Isoch IO on that resource
|
|
// Arguments
|
|
// PdoCb The Pdo for the remote node to which the Irp is submitted
|
|
//
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicIsochStop , pPdo, %x hResource %x", pPdo, hResource) );
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
pIrb->FunctionNumber = REQUEST_ISOCH_STOP;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.IsochStop.hResource = hResource;
|
|
pIrb->u.IsochStop.fulFlags = 0;
|
|
|
|
NdisStatus = nicGetIrp (pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<== nicIsochStop , Status ", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGetLocalHostCSRTopologyMap(
|
|
IN PADAPTERCB pAdapter,
|
|
IN PULONG pLength,
|
|
IN PVOID pBuffer
|
|
)
|
|
// Function Description:
|
|
// Retrieves the local hosts CSR.
|
|
// Arguments
|
|
// pBuffer - LocalHostBuffer
|
|
//
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
GET_LOCAL_HOST_INFO6 LocalHostInfo6;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
ASSERT (pLength != NULL);
|
|
ASSERT (pBuffer != NULL);
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostCSRTopologyMap , pAdapter %x ,Length %x, Buffer",
|
|
pAdapter, *pLength, pBuffer) );
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
LocalHostInfo6.CsrBaseAddress.Off_High = INITIAL_REGISTER_SPACE_HI;
|
|
LocalHostInfo6.CsrBaseAddress.Off_Low = TOPOLOGY_MAP_LOCATION;
|
|
LocalHostInfo6.CsrDataLength = *pLength;
|
|
LocalHostInfo6.CsrDataBuffer = pBuffer;
|
|
|
|
|
|
pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CSR_CONTENTS;
|
|
pIrb->u.GetLocalHostInformation.Information = &LocalHostInfo6;
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
|
|
TRACE( TL_A, TM_Irp, ( "Length Needed %.x", LocalHostInfo6.CsrDataLength) );
|
|
|
|
if (pIrp->IoStatus.Status == STATUS_INVALID_BUFFER_SIZE)
|
|
{
|
|
*pLength = LocalHostInfo6.CsrDataLength;
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGetLocalHostConfigRom(
|
|
IN PADAPTERCB pAdapter,
|
|
OUT PVOID *ppCRom
|
|
)
|
|
// Function Description:
|
|
// Retrieves the local hosts CSR.
|
|
// Arguments
|
|
// pBuffer - Locally allocated. Caller has to free
|
|
//
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
GET_LOCAL_HOST_INFO5 Info;
|
|
PVOID pCRom;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostConfigRom, pAdapter %x ",
|
|
pAdapter) );
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
Info.ConfigRom = NULL;
|
|
Info.ConfigRomLength = 0;
|
|
|
|
pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO ;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CONFIG_ROM;
|
|
pIrb->u.GetLocalHostInformation.Information = &Info;
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
//
|
|
// First find the length
|
|
//
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (Info.ConfigRomLength == 0)
|
|
{
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
|
|
}
|
|
|
|
nicFreeIrp (pIrp);
|
|
pIrp = NULL;
|
|
|
|
pCRom = ALLOC_NONPAGED (Info.ConfigRomLength, 'C31N');
|
|
|
|
if (pCRom == NULL)
|
|
{
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
break;
|
|
}
|
|
|
|
Info.ConfigRom = pCRom;
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
*ppCRom = pCRom;
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGetConfigRom(
|
|
IN PDEVICE_OBJECT pPdo,
|
|
OUT PVOID *ppCrom
|
|
)
|
|
// Function Description:
|
|
// Retrieves the Config Rom from the Device Object.
|
|
// Caller responsibility to free this memory.
|
|
// Arguments
|
|
// pBuffer - LocalHostBuffer
|
|
//
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
ULONG SizeNeeded= 0;
|
|
PVOID pConfigInfoBuffer;
|
|
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGetConfigRom, pPdo %x ",pPdo ) );
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
|
|
|
|
pIrb->FunctionNumber = REQUEST_GET_CONFIGURATION_INFO;
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_PDOSynch ( pPdo,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
//
|
|
// Clear the Irp so that it will not be double freed if we fail
|
|
//
|
|
pIrp = NULL;
|
|
|
|
SizeNeeded = sizeof(CONFIG_ROM) +pIrb->u.GetConfigurationInformation.UnitDirectoryBufferSize +
|
|
pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize +
|
|
pIrb->u.GetConfigurationInformation.VendorLeafBufferSize +
|
|
pIrb->u.GetConfigurationInformation.ModelLeafBufferSize;
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGetConfigRom , SixeNeeded %x", SizeNeeded) );
|
|
|
|
pConfigInfoBuffer = ALLOC_NONPAGED (SizeNeeded , 'C13N');
|
|
|
|
if (pConfigInfoBuffer == NULL)
|
|
{
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
break;
|
|
|
|
}
|
|
|
|
pIrb->u.GetConfigurationInformation.ConfigRom = (PCONFIG_ROM)pConfigInfoBuffer;
|
|
pIrb->u.GetConfigurationInformation.UnitDirectory = (PVOID)((PUCHAR)pConfigInfoBuffer + sizeof(CONFIG_ROM));
|
|
pIrb->u.GetConfigurationInformation.UnitDependentDirectory = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.UnitDirectory +
|
|
pIrb->u.GetConfigurationInformation.UnitDirectoryBufferSize);
|
|
pIrb->u.GetConfigurationInformation.VendorLeaf = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.UnitDependentDirectory +
|
|
pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize);
|
|
pIrb->u.GetConfigurationInformation.ModelLeaf = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.VendorLeaf +
|
|
pIrb->u.GetConfigurationInformation.VendorLeafBufferSize);
|
|
pIrb->FunctionNumber = REQUEST_GET_CONFIGURATION_INFO;
|
|
|
|
NdisStatus = nicGetIrp ( pPdo, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_PDOSynch ( pPdo,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
|
|
break;
|
|
}
|
|
TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, pConfigRom %x, Size %x", pConfigInfoBuffer , SizeNeeded ) );
|
|
|
|
|
|
*ppCrom = pConfigInfoBuffer;
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGetReadWriteCapLocalHost(
|
|
IN PADAPTERCB pAdapter,
|
|
PGET_LOCAL_HOST_INFO2 pReadWriteCaps
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Gets the ReadWrite Capabilities for the local host
|
|
|
|
Arguments:
|
|
ReadWriteCaps - To be filled up byt the bus driver
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGetReadWriteCapLocalHost, pAdapter %x pReadWriteCaps %x",
|
|
pAdapter, pReadWriteCaps) );
|
|
|
|
do
|
|
{
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
NdisZeroMemory (pReadWriteCaps, sizeof(*pReadWriteCaps));
|
|
|
|
|
|
pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CAPABILITIES;
|
|
pIrb->u.GetLocalHostInformation.Information = pReadWriteCaps;
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost, nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<== nicGetReadWriteCapLocalHost, Status %x", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicSetLocalHostPropertiesCRom (
|
|
IN PADAPTERCB pAdapter,
|
|
IN PUCHAR pConfigRom,
|
|
IN ULONG Length,
|
|
IN ULONG Flags,
|
|
IN OUT PHANDLE phCromData,
|
|
IN OUT PMDL *ppConfigRomMdl
|
|
)
|
|
|
|
|
|
// Function Description:
|
|
// Allocates an MDL pointing to the Buffer
|
|
// and sends it to the bus driver
|
|
//
|
|
// Arguments
|
|
// pAdapter - Local host
|
|
// ConfigRom - Buffer to be sent to the bus driver
|
|
// Length - Length of the Config Rom Buffer
|
|
// Flags - Add or remove
|
|
// phConfigRom - if Remove then this is an input parameter
|
|
// Return Value:
|
|
// Handle - Is successful
|
|
//
|
|
|
|
{
|
|
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
PMDL pMdl = NULL;
|
|
SET_LOCAL_HOST_PROPS3 SetLocalHost3;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicSetLocalHostPropertiesCRom , pAdapter %x, pConfigRom %x",pAdapter, pConfigRom) );
|
|
|
|
if (Flags == SLHP_FLAG_ADD_CROM_DATA)
|
|
{
|
|
TRACE( TL_T, TM_Irp, ( " ADD") );
|
|
|
|
}
|
|
else
|
|
{
|
|
TRACE( TL_T, TM_Irp, ( " REMOVE Handle %x", *pConfigRom) );
|
|
|
|
}
|
|
|
|
|
|
do
|
|
{
|
|
//
|
|
// Get an mdl describing the config rom
|
|
//
|
|
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
// Initialize the set local host struct
|
|
//
|
|
|
|
if (Flags == SLHP_FLAG_ADD_CROM_DATA)
|
|
{
|
|
NdisStatus = nicGetMdl ( Length, pConfigRom, &pMdl);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
|
|
SetLocalHost3.fulFlags = SLHP_FLAG_ADD_CROM_DATA;
|
|
SetLocalHost3.hCromData = NULL;
|
|
SetLocalHost3.nLength = Length;
|
|
SetLocalHost3.Mdl = pMdl;
|
|
}
|
|
else
|
|
{
|
|
SetLocalHost3.fulFlags = SLHP_FLAG_REMOVE_CROM_DATA ;
|
|
ASSERT (phCromData != NULL);
|
|
SetLocalHost3.hCromData = *phCromData;
|
|
}
|
|
|
|
pIrb->FunctionNumber = REQUEST_SET_LOCAL_HOST_PROPERTIES;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.GetLocalHostInformation.nLevel = SET_LOCAL_HOST_PROPERTIES_MODIFY_CROM;
|
|
pIrb->u.GetLocalHostInformation.Information = &SetLocalHost3;
|
|
|
|
|
|
//
|
|
// Get an Irp
|
|
//
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
if (Flags == SLHP_FLAG_ADD_CROM_DATA)
|
|
{
|
|
*phCromData = SetLocalHost3.hCromData;
|
|
*ppConfigRomMdl = pMdl;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Free the Mdl that contains the CROM
|
|
//
|
|
ASSERT (*ppConfigRomMdl);
|
|
nicFreeMdl (*ppConfigRomMdl);
|
|
}
|
|
} while (FALSE);
|
|
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicSetLocalHostPropertiesCRom pAdapter %x", pAdapter ) );
|
|
|
|
|
|
return NdisStatus;
|
|
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
nicGetLocalHostUniqueId(
|
|
IN PADAPTERCB pAdapter,
|
|
IN OUT PGET_LOCAL_HOST_INFO1 pUid
|
|
)
|
|
// Function Description:
|
|
// Retrieves the local hosts UniqueId.
|
|
// Arguments
|
|
// pBuffer - LocalHostBuffer
|
|
//
|
|
// Return Value:
|
|
// Success if the Irp Succeeded
|
|
// Failure otherwise
|
|
//
|
|
|
|
{
|
|
NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
|
|
PIRB pIrb = NULL;
|
|
PIRP pIrp = NULL;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostUniqueId , pAdapter%x ,pUid",
|
|
pAdapter, pUid) );
|
|
|
|
do
|
|
{
|
|
ASSERT (pAdapter->pNextDeviceObject != NULL);
|
|
|
|
NdisStatus = nicGetIrb (&pIrb);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostUniqueId , nicGetIrb FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT ( pIrb != NULL);
|
|
|
|
//
|
|
//Initialize the datastructures in the Irb
|
|
//
|
|
|
|
|
|
pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
|
|
pIrb->Flags = 0;
|
|
pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_UNIQUE_ID;
|
|
pIrb->u.GetLocalHostInformation.Information = (PVOID) pUid;
|
|
|
|
|
|
NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrp FAILED" ) );
|
|
break;
|
|
}
|
|
|
|
ASSERT (pIrp != NULL);
|
|
|
|
|
|
NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
|
|
pIrp,
|
|
pIrb );
|
|
|
|
if (NdisStatus != NDIS_STATUS_SUCCESS)
|
|
{
|
|
TRACE( TL_A, TM_Irp, ( "nicGetLocalHostUniqueId , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Now free all the locally allocated resources. They can point to NULL, in which case the called
|
|
// functions return immediately
|
|
//
|
|
nicFreeIrb (pIrb);
|
|
|
|
nicFreeIrp (pIrp);
|
|
|
|
|
|
MATCH_IRQL;
|
|
TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostUniqueId , Status %x", NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
// The routines to submit Irp's to the bus, synchronously or
|
|
// asynchronously begin here
|
|
//---------------------------------------------------------
|
|
|
|
|
|
NTSTATUS
|
|
nicSubmitIrp(
|
|
IN PDEVICE_OBJECT pPdo,
|
|
IN PIRP pIrp,
|
|
IN PIRB pIrb,
|
|
IN PIO_COMPLETION_ROUTINE pCompletion,
|
|
IN PVOID pContext
|
|
)
|
|
|
|
//
|
|
// This is the generic function used by all Irp Send Handlers
|
|
// to do an IoCallDriver. It sets up the next location in the
|
|
// stack prior to calling the Irp
|
|
// Make sure the Irp knows about the Irb by setting it up as an argument
|
|
//
|
|
{
|
|
|
|
NTSTATUS NtStatus ;
|
|
PIO_STACK_LOCATION NextIrpStack;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp, pPdo %x, Irp %x, Irb %x, ",
|
|
pPdo, pIrp ,pIrb, pCompletion ) );
|
|
|
|
TRACE( TL_T, TM_Irp, ( " pCompletion %x, pContext %x",
|
|
pCompletion, pContext ) );
|
|
|
|
|
|
ASSERT (pPdo != NULL);
|
|
|
|
IoSetCompletionRoutine (pIrp,
|
|
pCompletion,
|
|
pContext,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE);
|
|
|
|
|
|
//
|
|
// Insert the Irp as as the argument in the NextStack location for the IRP
|
|
//
|
|
|
|
|
|
if (pIrb)
|
|
{
|
|
NextIrpStack = IoGetNextIrpStackLocation (pIrp);
|
|
NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
|
|
NextIrpStack->DeviceObject = pPdo;
|
|
NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
|
|
NextIrpStack->Parameters.Others.Argument1 = pIrb;
|
|
}
|
|
else
|
|
{
|
|
IoCopyCurrentIrpStackLocationToNext(pIrp);
|
|
}
|
|
|
|
|
|
//
|
|
// Reference the PDO and Submit the Irp
|
|
// If Ref fails, it means the PDO has been deactivated on another thread
|
|
//
|
|
NtStatus = IoCallDriver (pPdo, pIrp);
|
|
|
|
|
|
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp, PDO %x, NtStatus %x",
|
|
pPdo, NtStatus ) );
|
|
|
|
//
|
|
// Since we did a IoCallDriver, we have a guarantee that the completion
|
|
// routine will be called. Exit gracefully
|
|
//
|
|
|
|
return NtStatus;
|
|
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
nicSubmitIrp_Synch(
|
|
IN REMOTE_NODE *pRemoteNode,
|
|
IN PIRP pIrp,
|
|
IN PIRB pIrb
|
|
)
|
|
|
|
// Callers need to make sure that no context is set for the Irp
|
|
// as it will be a synchronous call for them
|
|
//
|
|
|
|
// We refcount the Pdo block so that the pdo block will not disappear
|
|
// during the duration of the IoCallDriver
|
|
|
|
{
|
|
NDIS_EVENT NdisSynchEvent;
|
|
NTSTATUS NtStatus;
|
|
NDIS_STATUS NdisStatus;
|
|
BOOLEAN bSuccessful = FALSE;
|
|
BOOLEAN bIsPdoValid = FALSE;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_Synch, PDO %x", pRemoteNode->pPdo ) );
|
|
|
|
|
|
ASSERT (pRemoteNode != NULL);
|
|
ASSERT (pRemoteNode->pPdo != NULL);
|
|
|
|
ASSERT (pIrp != NULL);
|
|
ASSERT (pIrb != NULL)
|
|
|
|
|
|
do
|
|
{
|
|
//
|
|
// Check to see if Pdo is Valid. We do not care here if the Pdo is being
|
|
// removed because Vcs may want to submit Irps as part of their cleanup
|
|
// process
|
|
//
|
|
REMOTE_NODE_ACQUIRE_LOCK (pRemoteNode);
|
|
|
|
if ( REMOTE_NODE_TEST_FLAG (pRemoteNode, PDO_Activated )
|
|
&& (nicReferenceRemoteNode (pRemoteNode, SubmitIrp_Synch) == TRUE) )
|
|
{
|
|
bIsPdoValid = TRUE;
|
|
}
|
|
|
|
REMOTE_NODE_RELEASE_LOCK (pRemoteNode);
|
|
|
|
if ( bIsPdoValid == FALSE)
|
|
{
|
|
NtStatus = STATUS_NO_SUCH_DEVICE;
|
|
|
|
TRACE( TL_A, TM_Irp, ( "==>PDO is NOT Valid, nicSubmitIrp_Synch, PdoCb %x, Pdo %x", pRemoteNode, pRemoteNode->pPdo ) );
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Add a reference to the PDO block so it cannot be removed
|
|
// This reference is decremented at the end of this function
|
|
//
|
|
NdisInitializeEvent (&NdisSynchEvent);
|
|
|
|
|
|
NtStatus = nicSubmitIrp ( pRemoteNode->pPdo,
|
|
pIrp,
|
|
pIrb,
|
|
nicSubmitIrp_SynchComplete,
|
|
(PVOID)&NdisSynchEvent);
|
|
|
|
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
|
|
{
|
|
//
|
|
// Now we need to wait for the event to complete
|
|
// and return a good status if we do not hit the timeout
|
|
//
|
|
ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
|
|
|
|
bSuccessful = NdisWaitEvent (&NdisSynchEvent,WAIT_INFINITE);
|
|
|
|
if (bSuccessful == TRUE)
|
|
{
|
|
//
|
|
// We waited successfully. Now lets see how the Irp fared.
|
|
//
|
|
TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
|
|
|
|
NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
|
|
}
|
|
else
|
|
{
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{ //
|
|
// The call to submit Irp failed synvhronously. Presently, the only cause is an
|
|
|
|
NdisStatus = NtStatusToNdisStatus (NtStatus);
|
|
|
|
}
|
|
|
|
if (bIsPdoValid == TRUE)
|
|
{
|
|
//
|
|
// If this variable is set, it means we have referenced the PDO
|
|
//
|
|
nicDereferenceRemoteNode (pRemoteNode, SubmitIrp_Synch);
|
|
}
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_Synch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
nicSubmitIrp_SynchComplete(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP pIrp,
|
|
IN PVOID Context
|
|
)
|
|
// This is the completion routine for functions nicSubmitIrp_synch.
|
|
// It sets the event (int the context) and exits
|
|
//
|
|
|
|
{
|
|
PNDIS_EVENT pNdisSynchEvent = (PNDIS_EVENT) Context;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_SynchComplete, PDO %x, pIrp %x, status %x",DeviceObject,pIrp, pIrp->IoStatus.Status ) );
|
|
|
|
NdisSetEvent (pNdisSynchEvent);
|
|
|
|
return (STATUS_MORE_PROCESSING_REQUIRED);
|
|
|
|
}
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
nicSubmitIrp_LocalHostSynch(
|
|
IN PADAPTERCB pAdapter,
|
|
IN PIRP pIrp,
|
|
IN PIRB pIrb
|
|
)
|
|
|
|
// Callers need to make sure that no context is set for the Irp
|
|
// as it will be a synchronous call for them
|
|
//
|
|
// No Checking
|
|
//
|
|
|
|
{
|
|
NDIS_EVENT NdisSynchEvent;
|
|
NTSTATUS NtStatus;
|
|
NDIS_STATUS NdisStatus;
|
|
BOOLEAN bSuccessful = FALSE;
|
|
BOOLEAN bIsPdoValid = FALSE;
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_LocalHostSynch, PDO %x", pAdapter->pNextDeviceObject ) );
|
|
TRACE( TL_V, TM_Irp, ( "Current Irql , %.2x", KeGetCurrentIrql()) );
|
|
|
|
|
|
|
|
ASSERT (pIrp != NULL);
|
|
ASSERT (pIrb != NULL)
|
|
|
|
|
|
do
|
|
{
|
|
//
|
|
// Check to see if Pdo is Valid.
|
|
//
|
|
|
|
//
|
|
// Add a reference to the PDO block so it cannot be removed
|
|
// This reference is decremented at the end of this function
|
|
//
|
|
// This reference is decrement below
|
|
|
|
|
|
if (ADAPTER_ACTIVE(pAdapter))
|
|
{
|
|
nicReferenceAdapter(pAdapter, "nicSubmitIrp_LocalHostSynch");
|
|
TRACE( TL_V, TM_Irp, ( "Adapter Active pAdapter %x, ulflags %x", pAdapter , pAdapter->ulFlags) );
|
|
|
|
bIsPdoValid = TRUE;
|
|
}
|
|
else
|
|
{
|
|
TRACE( TL_V, TM_Irp, ( "Adapter INActive pAdapter %x, ulflags %x", pAdapter , pAdapter->ulFlags) );
|
|
bIsPdoValid = FALSE;
|
|
|
|
}
|
|
|
|
|
|
if ( bIsPdoValid == FALSE)
|
|
{
|
|
NtStatus = STATUS_NO_SUCH_DEVICE;
|
|
|
|
TRACE( TL_A, TM_Irp, ( "==>PDO is NOT Valid, nicSubmitIrp_LocalHostSynch, pAdapter %x, Pdo %x", pAdapter , pAdapter->pNextDeviceObject) );
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
NdisInitializeEvent (&NdisSynchEvent);
|
|
|
|
|
|
NtStatus = nicSubmitIrp ( pAdapter->pNextDeviceObject,
|
|
pIrp,
|
|
pIrb,
|
|
nicSubmitIrp_SynchComplete,
|
|
(PVOID)&NdisSynchEvent);
|
|
|
|
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
|
|
{
|
|
//
|
|
// Now we need to wait for the event to complete
|
|
// and return a good status if we do not hit the timeout
|
|
//
|
|
|
|
bSuccessful = NdisWaitEvent (&NdisSynchEvent,WAIT_INFINITE);
|
|
|
|
if (bSuccessful == TRUE)
|
|
{
|
|
//
|
|
// We waited successfully. Now lets see how the Irp fared.
|
|
//
|
|
TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
|
|
|
|
NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
|
|
}
|
|
else
|
|
{
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// IoCallDriver failed synchronously
|
|
//
|
|
NdisStatus = NtStatusToNdisStatus (NtStatus);
|
|
}
|
|
|
|
if (bIsPdoValid == TRUE)
|
|
{
|
|
nicDereferenceAdapter(pAdapter, "nicSubmitIrp_LocalHostSynch");
|
|
}
|
|
TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_LocalHostSynch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
|
|
|
|
return NdisStatus;
|
|
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
nicSubmitIrp_PDOSynch(
|
|
IN PDEVICE_OBJECT pPdo,
|
|
IN PIRP pIrp,
|
|
IN PIRB pIrb
|
|
)
|
|
|
|
// Callers need to make sure that no context is set for the Irp
|
|
// as it will be a synchronous call for them
|
|
//
|
|
// No Checking
|
|
//
|
|
|
|
{
|
|
NDIS_EVENT NdisSynchEvent;
|
|
NTSTATUS NtStatus;
|
|
NDIS_STATUS NdisStatus;
|
|
BOOLEAN bSuccessful = FALSE;
|
|
STORE_CURRENT_IRQL;
|
|
|
|
|
|
TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_PDOSynch, PDO %x", pPdo) );
|
|
TRACE( TL_V, TM_Irp, ( "Current Irql , %.2x", KeGetCurrentIrql()) );
|
|
|
|
|
|
|
|
ASSERT (pIrp != NULL);
|
|
ASSERT (pIrb != NULL)
|
|
|
|
//
|
|
// No Checks to see if Pdo is Valid.
|
|
//
|
|
|
|
|
|
//
|
|
// Send the Irp to the bus driver
|
|
//
|
|
NdisInitializeEvent (&NdisSynchEvent);
|
|
|
|
NtStatus = nicSubmitIrp ( pPdo,
|
|
pIrp,
|
|
pIrb,
|
|
nicSubmitIrp_SynchComplete,
|
|
(PVOID)&NdisSynchEvent);
|
|
|
|
|
|
|
|
|
|
|
|
if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
|
|
{
|
|
//
|
|
// Now we need to wait for the event to complete
|
|
// and return a good status if we do not hit the timeout
|
|
//
|
|
ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
|
|
|
|
bSuccessful = NdisWaitEvent (&NdisSynchEvent,WAIT_INFINITE);
|
|
|
|
if (bSuccessful == TRUE)
|
|
{
|
|
//
|
|
// We waited successfully. Now lets see how the Irp fared.
|
|
//
|
|
TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
|
|
|
|
NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
|
|
}
|
|
else
|
|
{
|
|
NdisStatus = NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// IoCallDriver failed synchronously
|
|
//
|
|
NdisStatus = NtStatusToNdisStatus (NtStatus);
|
|
}
|
|
|
|
TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_PDOSynch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
|
|
MATCH_IRQL;
|
|
return NdisStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|