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.
513 lines
14 KiB
513 lines
14 KiB
/*
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
(C) Copyright 1998
|
|
All rights reserved.
|
|
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
Portions of this software are:
|
|
|
|
(C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
|
|
License to use this software is granted under the terms outlined in
|
|
the TriplePoint Software Services Agreement.
|
|
|
|
(C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
|
|
License to use this software is granted under the terms outlined in
|
|
the Microsoft Windows Device Driver Development Kit.
|
|
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@doc INTERNAL Port Port_c
|
|
|
|
@module Port.c |
|
|
|
|
This module implements the interface to the <t PORT_OBJECT>.
|
|
|
|
@head3 Contents |
|
|
@index class,mfunc,func,msg,mdata,struct,enum | Port_c
|
|
|
|
@end
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
*/
|
|
|
|
#define __FILEID__ PORT_OBJECT_TYPE
|
|
// Unique file ID for error logging
|
|
|
|
#include "Miniport.h" // Defines all the miniport objects
|
|
|
|
#if defined(NDIS_LCODE)
|
|
# pragma NDIS_LCODE // Windows 95 wants this code locked down!
|
|
# pragma NDIS_LDATA
|
|
#endif
|
|
|
|
|
|
DBG_STATIC ULONG g_PortInstanceCounter = 0;
|
|
// Keeps track of how many <t PORT_OBJECT>s are created.
|
|
|
|
|
|
/* @doc EXTERNAL INTERNAL Port Port_c g_PortParameters
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@topic 5.6 Port Parameters |
|
|
|
|
This section describes the registry parameters read into the
|
|
<t PORT_OBJECT>.
|
|
|
|
@globalv PARAM_TABLE | g_PortParameters |
|
|
|
|
This table defines the registry based parameters to be assigned to data
|
|
members of the <t PORT_OBJECT>.
|
|
|
|
<f Note>:
|
|
If you add any registry based data members to <t PORT_OBJECT>
|
|
you will need to modify <f PortReadParameters> and add the parameter
|
|
definitions to the <f g_PortParameters> table.
|
|
|
|
*/
|
|
|
|
DBG_STATIC PARAM_TABLE g_PortParameters[] =
|
|
{
|
|
PARAM_ENTRY(PORT_OBJECT,
|
|
SwitchType, PARAM_SwitchType,
|
|
FALSE, NdisParameterInteger, 0,
|
|
0x0001, 0x0001, 0x8000),
|
|
|
|
PARAM_ENTRY(PORT_OBJECT,
|
|
NumChannels, PARAM_NumBChannels,
|
|
FALSE, NdisParameterInteger, 0,
|
|
2, 2, 24),
|
|
|
|
/* The last entry must be an empty string! */
|
|
{ { 0 } }
|
|
};
|
|
|
|
|
|
DBG_STATIC NDIS_STRING PortPrefix = INIT_STRING_CONST(PARAM_PORT_PREFIX);
|
|
|
|
|
|
/* @doc INTERNAL Port Port_c PortReadParameters
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f PortReadParameters> reads the Port parameters from the registry
|
|
and initializes the associated data members. This should only be called
|
|
by <f PortCreate>.
|
|
|
|
<f Note>:
|
|
If you add any registry based data members to <t PORT_OBJECT>
|
|
you will need to modify <f PortReadParameters> and add the parameter
|
|
definitions to the <f g_PortParameters> table.
|
|
|
|
@rdesc
|
|
|
|
<f PortReadParameters> returns zero if it is successful.<nl>
|
|
Otherwise, a non-zero return value indicates an error condition.
|
|
|
|
*/
|
|
|
|
DBG_STATIC NDIS_STATUS PortReadParameters(
|
|
IN PPORT_OBJECT pPort // @parm
|
|
// A pointer to the <t PORT_OBJECT> returned by <f PortCreate>.
|
|
)
|
|
{
|
|
DBG_FUNC("PortReadParameters")
|
|
|
|
NDIS_STATUS Status;
|
|
// Status result returned from an NDIS function call.
|
|
|
|
PMINIPORT_ADAPTER_OBJECT pAdapter;
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
|
|
pAdapter = GET_ADAPTER_FROM_PORT(pPort);
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
/*
|
|
// Parse the registry parameters.
|
|
*/
|
|
Status = ParamParseRegistry(
|
|
pAdapter->MiniportAdapterHandle,
|
|
pAdapter->WrapperConfigurationContext,
|
|
(PUCHAR)pPort,
|
|
g_PortParameters
|
|
);
|
|
|
|
DBG_NOTICE(pAdapter,("PortPrefixLen=%d:%d:%ls\n",
|
|
PortPrefix.Length, PortPrefix.MaximumLength, PortPrefix.Buffer));
|
|
|
|
if (Status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
/*
|
|
// Make sure the parameters are valid.
|
|
*/
|
|
if (pPort->TODO)
|
|
{
|
|
DBG_ERROR(pAdapter,("Invalid parameter\n"
|
|
));
|
|
NdisWriteErrorLogEntry(
|
|
pAdapter->MiniportAdapterHandle,
|
|
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
|
|
3,
|
|
pPort->TODO,
|
|
__FILEID__,
|
|
__LINE__
|
|
);
|
|
Status = NDIS_STATUS_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
// Finish setting up data members based on registry settings.
|
|
*/
|
|
}
|
|
}
|
|
|
|
DBG_RETURN(pAdapter, Status);
|
|
return (Status);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Port Port_c PortCreateObjects
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f PortCreateObjects> calls the create routines for all the objects
|
|
contained in <t PORT_OBJECT>. This should only be called
|
|
by <f PortCreate>.
|
|
|
|
<f Note>:
|
|
If you add any new objects to <t PORT_OBJECT> you will need
|
|
to modify <f PortCreateObjects> and <f PortDestroyObjects> so they
|
|
will get created and destroyed properly.
|
|
|
|
@rdesc
|
|
|
|
<f PortCreateObjects> returns zero if it is successful.<nl>
|
|
Otherwise, a non-zero return value indicates an error condition.
|
|
|
|
*/
|
|
|
|
DBG_STATIC NDIS_STATUS PortCreateObjects(
|
|
IN PPORT_OBJECT pPort // @parm
|
|
// A pointer to the <t PORT_OBJECT> returned by <f PortCreate>.
|
|
)
|
|
{
|
|
DBG_FUNC("PortCreateObjects")
|
|
|
|
NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
|
|
// Holds the result code returned by this function.
|
|
|
|
PMINIPORT_ADAPTER_OBJECT pAdapter;
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
|
|
pAdapter = GET_ADAPTER_FROM_PORT(pPort);
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
// TODO - Add code here
|
|
|
|
DBG_RETURN(pAdapter, Result);
|
|
return (Result);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Port Port_c PortCreate
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f PortCreate> allocates memory for a <t PORT_OBJECT> and then
|
|
initializes the data members to their starting state.
|
|
If successful, <p ppPort> will be set to point to the newly created
|
|
<t PORT_OBJECT>. Otherwise, <p ppPort> will be set to NULL.
|
|
|
|
@comm
|
|
|
|
This function should be called only once when the Miniport is loaded.
|
|
Before the Miniport is unloaded, <f PortDestroy> must be called to
|
|
release the <t PORT_OBJECT> created by this function.
|
|
|
|
@rdesc
|
|
|
|
<f PortCreate> returns zero if it is successful.<nl>
|
|
Otherwise, a non-zero return value indicates an error condition.
|
|
|
|
*/
|
|
|
|
NDIS_STATUS PortCreate(
|
|
OUT PPORT_OBJECT * ppPort, // @parm
|
|
// Points to a caller-defined memory location to which this function
|
|
// writes the virtual address of the allocated <t PORT_OBJECT>.
|
|
|
|
IN PCARD_OBJECT pCard // @parm
|
|
// A pointer to the <t CARD_OBJECT> returned by <f CardCreate>.
|
|
)
|
|
{
|
|
DBG_FUNC("PortCreate")
|
|
|
|
PPORT_OBJECT pPort;
|
|
// Pointer to our newly allocated object.
|
|
|
|
NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
|
|
// Holds the result code returned by this function.
|
|
|
|
PMINIPORT_ADAPTER_OBJECT pAdapter;
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
ASSERT(pCard && pCard->ObjectType == CARD_OBJECT_TYPE);
|
|
pAdapter = GET_ADAPTER_FROM_CARD(pCard);
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
/*
|
|
// Make sure the caller's object pointer is NULL to begin with.
|
|
// It will be set later only if everything is successful.
|
|
*/
|
|
*ppPort = NULL;
|
|
|
|
/*
|
|
// Allocate memory for the object.
|
|
*/
|
|
Result = ALLOCATE_OBJECT(pPort, pAdapter->MiniportAdapterHandle);
|
|
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
/*
|
|
// Zero everything to begin with.
|
|
// Then set the object type and assign a unique ID .
|
|
*/
|
|
pPort->ObjectType = PORT_OBJECT_TYPE;
|
|
pPort->ObjectID = ++g_PortInstanceCounter;
|
|
|
|
/*
|
|
// Initialize the member variables to their default settings.
|
|
*/
|
|
pPort->pCard = pCard;
|
|
|
|
// TODO - Add code here
|
|
|
|
/*
|
|
// Parse the registry parameters.
|
|
*/
|
|
Result = PortReadParameters(pPort);
|
|
|
|
/*
|
|
// If all goes well, we are ready to create the sub-components.
|
|
*/
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
Result = PortCreateObjects(pPort);
|
|
}
|
|
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
/*
|
|
// All is well, so return the object pointer to the caller.
|
|
*/
|
|
*ppPort = pPort;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
// Something went wrong, so let's make sure everything is
|
|
// cleaned up.
|
|
*/
|
|
PortDestroy(pPort);
|
|
}
|
|
}
|
|
|
|
DBG_RETURN(pAdapter, Result);
|
|
return (Result);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Port Port_c PortDestroyObjects
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f PortDestroyObjects> calls the destroy routines for all the objects
|
|
contained in <t PORT_OBJECT>. This should only be called by
|
|
<f PortDestroy>.
|
|
|
|
<f Note>:
|
|
If you add any new objects to <t PPORT_OBJECT> you will need to
|
|
modify <f PortCreateObjects> and <f PortDestroyObjects> so they
|
|
will get created and destroyed properly.
|
|
|
|
*/
|
|
|
|
DBG_STATIC void PortDestroyObjects(
|
|
IN PPORT_OBJECT pPort // @parm
|
|
// A pointer to the <t PORT_OBJECT> instance.
|
|
)
|
|
{
|
|
DBG_FUNC("PortDestroyObjects")
|
|
|
|
PMINIPORT_ADAPTER_OBJECT pAdapter;
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
|
|
pAdapter = GET_ADAPTER_FROM_PORT(pPort);
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
// TODO - Add code here
|
|
|
|
DBG_LEAVE(pAdapter);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Port Port_c PortDestroy
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f PortDestroy> frees the memory for this <t PORT_OBJECT>.
|
|
All memory allocated by <f PortCreate> will be released back to the
|
|
OS.
|
|
|
|
*/
|
|
|
|
void PortDestroy(
|
|
IN PPORT_OBJECT pPort // @parm
|
|
// A pointer to the <t PORT_OBJECT> returned by <f PortCreate>.
|
|
)
|
|
{
|
|
DBG_FUNC("PortDestroy")
|
|
|
|
PMINIPORT_ADAPTER_OBJECT pAdapter;
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
if (pPort)
|
|
{
|
|
ASSERT(pPort->ObjectType == PORT_OBJECT_TYPE);
|
|
|
|
pAdapter = GET_ADAPTER_FROM_PORT(pPort);
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
// TODO - Add code here
|
|
|
|
/*
|
|
// Release all objects allocated within this object.
|
|
*/
|
|
PortDestroyObjects(pPort);
|
|
|
|
/*
|
|
// Make sure we fail the ASSERT if we see this object again.
|
|
*/
|
|
pPort->ObjectType = 0;
|
|
FREE_OBJECT(pPort);
|
|
|
|
DBG_LEAVE(pAdapter);
|
|
}
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Port Port_c PortOpen
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f PortOpen> makes the Port connection ready to transmit and
|
|
receive data.
|
|
|
|
@rdesc
|
|
|
|
<f PortOpen> returns zero if it is successful.<nl>
|
|
Otherwise, a non-zero return value indicates an error condition.
|
|
|
|
*/
|
|
|
|
NDIS_STATUS PortOpen(
|
|
IN PPORT_OBJECT pPort, // @parm
|
|
// A pointer to the <t PORT_OBJECT> associated with this request.
|
|
|
|
IN PBCHANNEL_OBJECT pBChannel // @parm
|
|
// A pointer to the <t BCHANNEL_OBJECT> to be associated with this
|
|
// Port.
|
|
)
|
|
{
|
|
DBG_FUNC("PortOpen")
|
|
|
|
NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
|
|
// Holds the result code returned by this function.
|
|
|
|
PMINIPORT_ADAPTER_OBJECT pAdapter;
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
ASSERT(pBChannel);
|
|
ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
|
|
pAdapter = GET_ADAPTER_FROM_PORT(pPort);
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
if (!pPort->IsOpen)
|
|
{
|
|
DBG_NOTICE(pAdapter,("Opening Port #%d\n",
|
|
pPort->ObjectID));
|
|
|
|
// TODO - Add code here
|
|
|
|
pPort->IsOpen = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DBG_ERROR(pAdapter,("Port #%d already opened\n",
|
|
pPort->ObjectID));
|
|
}
|
|
|
|
DBG_RETURN(pAdapter, Result);
|
|
return (Result);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Port Port_c PortClose
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f PortClose> closes the given B-channel.
|
|
|
|
*/
|
|
|
|
void PortClose(
|
|
IN PPORT_OBJECT pPort // @parm
|
|
// A pointer to the <t PORT_OBJECT> associated with this request.
|
|
)
|
|
{
|
|
DBG_FUNC("PortClose")
|
|
|
|
PMINIPORT_ADAPTER_OBJECT pAdapter;
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
|
|
pAdapter = GET_ADAPTER_FROM_PORT(pPort);
|
|
|
|
DBG_ENTER(pAdapter);
|
|
|
|
if (pPort->IsOpen)
|
|
{
|
|
DBG_NOTICE(pAdapter,("Closing Port #%d\n",
|
|
pPort->ObjectID));
|
|
|
|
// TODO - Add code here
|
|
|
|
pPort->IsOpen = FALSE;
|
|
}
|
|
else
|
|
{
|
|
DBG_ERROR(pAdapter,("Port #%d already closed\n",
|
|
pPort->ObjectID));
|
|
}
|
|
|
|
DBG_LEAVE(pAdapter);
|
|
}
|
|
|
|
|