1078 lines
32 KiB
C
1078 lines
32 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* Copyright (c) 1996-1999 Microsoft Corporation
|
||
|
*
|
||
|
* @doc
|
||
|
* @module request.c | IrSIR NDIS Miniport Driver
|
||
|
* @comm
|
||
|
*
|
||
|
*-----------------------------------------------------------------------------
|
||
|
*
|
||
|
* Author: Scott Holden (sholden)
|
||
|
*
|
||
|
* Date: 10/10/1996 (created)
|
||
|
*
|
||
|
* Contents: Query and set information handlers.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "irsir.h"
|
||
|
|
||
|
VOID
|
||
|
ClearMediaBusyCallback(
|
||
|
PIR_WORK_ITEM pWorkItem
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
QueryMediaBusyCallback(
|
||
|
PIR_WORK_ITEM pWorkItem
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
InitIrDeviceCallback(
|
||
|
PIR_WORK_ITEM pWorkItem
|
||
|
);
|
||
|
|
||
|
#pragma alloc_text(PAGE, ClearMediaBusyCallback)
|
||
|
#pragma alloc_text(PAGE, QueryMediaBusyCallback)
|
||
|
#pragma alloc_text(PAGE, InitIrDeviceCallback)
|
||
|
|
||
|
//
|
||
|
// These are the OIDs we support for querying.
|
||
|
//
|
||
|
|
||
|
UINT supportedOIDs[] =
|
||
|
{
|
||
|
//
|
||
|
// General required OIDs.
|
||
|
//
|
||
|
|
||
|
OID_GEN_SUPPORTED_LIST,
|
||
|
OID_GEN_HARDWARE_STATUS,
|
||
|
OID_GEN_MEDIA_SUPPORTED,
|
||
|
OID_GEN_MEDIA_IN_USE,
|
||
|
OID_GEN_MAXIMUM_LOOKAHEAD,
|
||
|
OID_GEN_MAXIMUM_FRAME_SIZE,
|
||
|
OID_GEN_LINK_SPEED,
|
||
|
OID_GEN_TRANSMIT_BUFFER_SPACE,
|
||
|
OID_GEN_RECEIVE_BUFFER_SPACE,
|
||
|
OID_GEN_TRANSMIT_BLOCK_SIZE,
|
||
|
OID_GEN_RECEIVE_BLOCK_SIZE,
|
||
|
OID_GEN_VENDOR_ID,
|
||
|
OID_GEN_VENDOR_DESCRIPTION,
|
||
|
OID_GEN_CURRENT_PACKET_FILTER,
|
||
|
OID_GEN_CURRENT_LOOKAHEAD,
|
||
|
OID_GEN_DRIVER_VERSION,
|
||
|
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
||
|
OID_GEN_PROTOCOL_OPTIONS,
|
||
|
OID_GEN_MAC_OPTIONS,
|
||
|
OID_GEN_MEDIA_CONNECT_STATUS,
|
||
|
OID_GEN_MAXIMUM_SEND_PACKETS,
|
||
|
OID_GEN_VENDOR_DRIVER_VERSION,
|
||
|
|
||
|
//
|
||
|
// Required statistical OIDs.
|
||
|
//
|
||
|
|
||
|
OID_GEN_XMIT_OK,
|
||
|
OID_GEN_RCV_OK,
|
||
|
OID_GEN_XMIT_ERROR,
|
||
|
OID_GEN_RCV_ERROR,
|
||
|
OID_GEN_RCV_NO_BUFFER,
|
||
|
|
||
|
|
||
|
//
|
||
|
// Infrared-specific OIDs.
|
||
|
//
|
||
|
|
||
|
OID_IRDA_RECEIVING,
|
||
|
OID_IRDA_TURNAROUND_TIME,
|
||
|
OID_IRDA_SUPPORTED_SPEEDS,
|
||
|
OID_IRDA_LINK_SPEED,
|
||
|
OID_IRDA_MEDIA_BUSY,
|
||
|
OID_IRDA_EXTRA_RCV_BOFS
|
||
|
|
||
|
//
|
||
|
// Unsupported Infrared-specific OIDs.
|
||
|
//
|
||
|
// OID_IRDA_RATE_SNIFF,
|
||
|
// OID_IRDA_UNICAST_LIST,
|
||
|
// OID_IRDA_MAX_UNICAST_LIST_SIZE
|
||
|
//
|
||
|
|
||
|
#if 1
|
||
|
,OID_PNP_CAPABILITIES,
|
||
|
OID_PNP_SET_POWER,
|
||
|
OID_PNP_QUERY_POWER,
|
||
|
OID_PNP_ENABLE_WAKE_UP
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
|
||
|
VOID
|
||
|
ClearMediaBusyCallback(PIR_WORK_ITEM pWorkItem)
|
||
|
{
|
||
|
PIR_DEVICE pThisDev = pWorkItem->pIrDevice;
|
||
|
NDIS_STATUS status;
|
||
|
BOOLEAN fSwitchSuccessful;
|
||
|
NDIS_HANDLE hSwitchToMiniport;
|
||
|
|
||
|
SERIALPERF_STATS PerfStats;
|
||
|
|
||
|
//DBGTIME("CLEAR_MEDIA_BUSY");
|
||
|
DEBUGMSG(DBG_STAT, (" primPassive = PASSIVE_CLEAR_MEDIA_BUSY\n"));
|
||
|
|
||
|
status = (NDIS_STATUS) SerialClearStats(pThisDev->pSerialDevObj);
|
||
|
|
||
|
if (status != NDIS_STATUS_SUCCESS)
|
||
|
{
|
||
|
DEBUGMSG(DBG_ERROR, (" SerialClearStats failed = 0x%.8x\n", status));
|
||
|
}
|
||
|
|
||
|
{
|
||
|
NdisMSetInformationComplete(pThisDev->hNdisAdapter,
|
||
|
(NDIS_STATUS)status);
|
||
|
|
||
|
}
|
||
|
|
||
|
FreeWorkItem(pWorkItem);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
QueryMediaBusyCallback(PIR_WORK_ITEM pWorkItem)
|
||
|
{
|
||
|
PIR_DEVICE pThisDev = pWorkItem->pIrDevice;
|
||
|
NDIS_STATUS status;
|
||
|
BOOLEAN fSwitchSuccessful;
|
||
|
NDIS_HANDLE hSwitchToMiniport;
|
||
|
|
||
|
SERIALPERF_STATS PerfStats;
|
||
|
|
||
|
ASSERT(pWorkItem->InfoBuf != NULL);
|
||
|
ASSERT(pWorkItem->InfoBufLen >= sizeof(UINT));
|
||
|
|
||
|
if (pThisDev->pSerialDevObj)
|
||
|
{
|
||
|
status = (NDIS_STATUS) SerialGetStats(pThisDev->pSerialDevObj, &PerfStats);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
PerfStats.ReceivedCount = 1; // Fake media busy
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
if (status == NDIS_STATUS_SUCCESS)
|
||
|
{
|
||
|
if (PerfStats.ReceivedCount > 0 ||
|
||
|
PerfStats.FrameErrorCount > 0 ||
|
||
|
PerfStats.SerialOverrunErrorCount > 0 ||
|
||
|
PerfStats.BufferOverrunErrorCount > 0 ||
|
||
|
PerfStats.ParityErrorCount > 0)
|
||
|
{
|
||
|
DBGTIME("QUERY_MEDIA_BUSY:TRUE");
|
||
|
pThisDev->fMediaBusy = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DBGTIME("QUERY_MEDIA_BUSY:FALSE");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DEBUGMSG(DBG_ERROR, (" SerialGetStats failed = 0x%.8x\n", status));
|
||
|
}
|
||
|
|
||
|
*(UINT *)pWorkItem->InfoBuf = (UINT)pThisDev->fMediaBusy;
|
||
|
pWorkItem->InfoBufLen = sizeof(UINT);
|
||
|
|
||
|
{
|
||
|
NdisMQueryInformationComplete(pThisDev->hNdisAdapter,
|
||
|
(NDIS_STATUS)status);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
FreeWorkItem(pWorkItem);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
InitIrDeviceCallback(PIR_WORK_ITEM pWorkItem)
|
||
|
{
|
||
|
PIR_DEVICE pThisDev = pWorkItem->pIrDevice;
|
||
|
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
|
||
|
BOOLEAN fSwitchSuccessful;
|
||
|
NDIS_HANDLE hSwitchToMiniport;
|
||
|
|
||
|
DEBUGMSG(DBG_FUNC, ("+InitIrDeviceCallback\n"));
|
||
|
|
||
|
(void)ResetIrDevice(pThisDev);
|
||
|
|
||
|
{
|
||
|
NdisMQueryInformationComplete(pThisDev->hNdisAdapter,
|
||
|
(NDIS_STATUS)status);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
FreeWorkItem(pWorkItem);
|
||
|
|
||
|
DEBUGMSG(DBG_FUNC, ("-InitIrDeviceCallback\n"));
|
||
|
return;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Function: IrsirQueryInformation
|
||
|
*
|
||
|
* Synopsis: Queries the capabilities and status of the miniport driver.
|
||
|
*
|
||
|
* Arguments: MiniportAdapterContext - miniport context area (PIR_DEVICE)
|
||
|
* Oid - system defined OID_Xxx
|
||
|
* InformationBuffer - where to return Oid specific info
|
||
|
* InformationBufferLength - specifies size of InformationBuffer
|
||
|
* BytesWritten - bytes written to InformationBuffer
|
||
|
* BytesNeeded - addition bytes required if
|
||
|
* InformationBufferLength is less than
|
||
|
* what the Oid requires to write
|
||
|
*
|
||
|
* Returns: NDIS_STATUS_SUCCESS - success
|
||
|
* NDIS_STATUS_PENDING - will complete asynchronously and
|
||
|
* call NdisMQueryInformationComplete
|
||
|
* NDIS_STATUS_INVALID_OID - don't recognize the Oid
|
||
|
* NDIS_STATUS_INVALID_LENGTH- InformationBufferLength does not
|
||
|
* match length for the Oid
|
||
|
* NDIS_STATUS_NOT_ACCEPTED - failure
|
||
|
* NDIS_STATUS_NOT_SUPPORTED - do not support an optional Oid
|
||
|
* NDIS_STATUS_RESOURCES - failed allocation of resources
|
||
|
*
|
||
|
* Algorithm:
|
||
|
*
|
||
|
* History: dd-mm-yyyy Author Comment
|
||
|
* 10/1/1996 sholden author
|
||
|
*
|
||
|
* Notes:
|
||
|
* Supported OIDs:
|
||
|
* OID_GEN_MAXIMUM_LOOKAHEAD
|
||
|
* - indicate the number of bytes of look ahead data the NIC can
|
||
|
* provide
|
||
|
* OID_GEN_MAC_OPTIONS
|
||
|
* - indicate which NDIS_MAC_OPTION_Xxx the NIC supports
|
||
|
* OID_GEN_MAXIMUM_SEND_PACKETS
|
||
|
* OID_IRDA_RECEIVING
|
||
|
* OID_IRDA_SUPPORTED_SPEEDS
|
||
|
* OID_IRDA_LINK_SPEED
|
||
|
* OID_IRDA_MEDIA_BUSY
|
||
|
* OID_IRDA_TURNAROUND_TIME
|
||
|
* OID_IRDA_EXTRA_RCV_BOFS
|
||
|
*
|
||
|
* Unsupported OIDs:
|
||
|
* OID_IRDA_UNICAST_LIST
|
||
|
* OID_IRDA_MAX_UNICAST_LIST_SIZE
|
||
|
* OID_IRDA_RATE_SNIFF
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
NDIS_STATUS
|
||
|
IrsirQueryInformation(
|
||
|
IN NDIS_HANDLE MiniportAdapterContext,
|
||
|
IN NDIS_OID Oid,
|
||
|
IN PVOID InformationBuffer,
|
||
|
IN ULONG InformationBufferLength,
|
||
|
OUT PULONG BytesWritten,
|
||
|
OUT PULONG BytesNeeded
|
||
|
)
|
||
|
{
|
||
|
PIR_DEVICE pThisDev;
|
||
|
NDIS_STATUS status;
|
||
|
UINT speeds;
|
||
|
UINT i;
|
||
|
UINT infoSizeNeeded;
|
||
|
UINT *infoPtr;
|
||
|
PIR_WORK_ITEM pWorkItem = NULL;
|
||
|
ULONG OidCategory = Oid & 0xFF000000;
|
||
|
|
||
|
static char vendorDesc[] = "Serial Infrared (COM) Port";
|
||
|
|
||
|
DEBUGMSG(DBG_FUNC, ("+IrsirQueryInformation\n"));
|
||
|
|
||
|
pThisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
|
||
|
//
|
||
|
// Figure out buffer size needed.
|
||
|
// Most OIDs just return a single UINT, but there are exceptions.
|
||
|
//
|
||
|
|
||
|
switch (Oid)
|
||
|
{
|
||
|
case OID_GEN_SUPPORTED_LIST:
|
||
|
infoSizeNeeded = sizeof(supportedOIDs);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_DRIVER_VERSION:
|
||
|
infoSizeNeeded = sizeof(USHORT);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_VENDOR_DESCRIPTION:
|
||
|
infoSizeNeeded = sizeof(vendorDesc);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_SUPPORTED_SPEEDS:
|
||
|
speeds = pThisDev->dongleCaps.supportedSpeedsMask &
|
||
|
ALL_SLOW_IRDA_SPEEDS;
|
||
|
|
||
|
for (infoSizeNeeded = 0; speeds; infoSizeNeeded += sizeof(UINT))
|
||
|
{
|
||
|
//
|
||
|
// This instruction clears the lowest set bit in speeds.
|
||
|
// Trust me.
|
||
|
//
|
||
|
|
||
|
speeds &= (speeds - 1);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
infoSizeNeeded = sizeof(UINT);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If the protocol provided a large enough buffer, we can go ahead
|
||
|
// and complete the query.
|
||
|
//
|
||
|
|
||
|
if (InformationBufferLength >= infoSizeNeeded)
|
||
|
{
|
||
|
//
|
||
|
// Set default results.
|
||
|
//
|
||
|
|
||
|
*BytesWritten = infoSizeNeeded;
|
||
|
*BytesNeeded = 0;
|
||
|
|
||
|
switch (Oid)
|
||
|
{
|
||
|
//
|
||
|
// Generic OIDs.
|
||
|
//
|
||
|
|
||
|
case OID_GEN_SUPPORTED_LIST:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_SUPPORTED_LIST)\n"));
|
||
|
|
||
|
NdisMoveMemory(
|
||
|
InformationBuffer,
|
||
|
(PVOID)supportedOIDs,
|
||
|
sizeof(supportedOIDs)
|
||
|
);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_HARDWARE_STATUS:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_HARDWARE_STATUS)\n"));
|
||
|
|
||
|
//
|
||
|
// If we can be called with a context, then we are
|
||
|
// initialized and ready.
|
||
|
//
|
||
|
|
||
|
*(UINT *)InformationBuffer = NdisHardwareStatusReady;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MEDIA_SUPPORTED:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MEDIA_SUPPORTED)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = NdisMediumIrda;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MEDIA_IN_USE:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MEDIA_IN_USE)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = NdisMediumIrda;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MAXIMUM_LOOKAHEAD:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = 256;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAXIMUM_FRAME_SIZE)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = MAX_NDIS_DATA_SIZE;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_LINK_SPEED:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_LINK_SPEED)\n"));
|
||
|
|
||
|
//
|
||
|
// Return MAXIMUM POSSIBLE speed for this device in units
|
||
|
// of 100 bits/sec.
|
||
|
//
|
||
|
|
||
|
*(UINT *)InformationBuffer = 115200/100;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_TRANSMIT_BUFFER_SPACE:
|
||
|
case OID_GEN_RECEIVE_BUFFER_SPACE:
|
||
|
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
||
|
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
||
|
*(UINT *)InformationBuffer = MAX_I_DATA_SIZE;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_VENDOR_ID:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_VENDOR_ID)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = 0x00ffffff;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_VENDOR_DESCRIPTION:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_VENDOR_DESCRIPTION)\n"));
|
||
|
|
||
|
NdisMoveMemory(
|
||
|
InformationBuffer,
|
||
|
(PVOID)vendorDesc,
|
||
|
sizeof(vendorDesc)
|
||
|
);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_CURRENT_PACKET_FILTER)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = NDIS_PACKET_TYPE_PROMISCUOUS;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_CURRENT_LOOKAHEAD)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = 256;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_DRIVER_VERSION:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_DRIVER_VERSION)\n"));
|
||
|
|
||
|
*(USHORT *)InformationBuffer = ((IRSIR_MAJOR_VERSION << 8) |
|
||
|
IRSIR_MINOR_VERSION);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAXIMUM_TOTAL_SIZE)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = MAX_NDIS_DATA_SIZE;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_PROTOCOL_OPTIONS:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_PROTOCOL_OPTIONS)\n"));
|
||
|
|
||
|
DEBUGMSG(DBG_ERROR, ("This is a set-only OID\n"));
|
||
|
*BytesWritten = 0;
|
||
|
status = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MAC_OPTIONS:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAC_OPTIONS)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
|
||
|
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MEDIA_CONNECT_STATUS)\n"));
|
||
|
|
||
|
//
|
||
|
// Since we are not physically connected to a LAN, we
|
||
|
// cannot determine whether or not we are connected;
|
||
|
// so always indicate that we are.
|
||
|
//
|
||
|
|
||
|
*(UINT *)InformationBuffer = NdisMediaStateConnected;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_MAXIMUM_SEND_PACKETS:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAXIMUM_SEND_PACKETS)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = 16;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_VENDOR_DRIVER_VERSION:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_VENDOR_DRIVER_VERSION)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
((IRSIR_MAJOR_VERSION << 16) |
|
||
|
IRSIR_MINOR_VERSION);
|
||
|
|
||
|
break;
|
||
|
|
||
|
//
|
||
|
// Required statistical OIDs.
|
||
|
//
|
||
|
|
||
|
case OID_GEN_XMIT_OK:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_XMIT_OK)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
(UINT)pThisDev->packetsSent;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_RCV_OK:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_RCV_OK)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
(UINT)pThisDev->packetsReceived;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_XMIT_ERROR:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_XMIT_ERROR)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
(UINT)pThisDev->packetsSentDropped;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_RCV_ERROR:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_RCV_ERROR)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
(UINT)pThisDev->packetsReceivedDropped;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_RCV_NO_BUFFER:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_RCV_NO_BUFFER)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
(UINT)pThisDev->packetsReceivedOverflow;
|
||
|
|
||
|
break;
|
||
|
|
||
|
//
|
||
|
// Infrared OIDs.
|
||
|
//
|
||
|
|
||
|
case OID_IRDA_RECEIVING:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_RECEIVING)\n"));
|
||
|
|
||
|
*(UINT *)InformationBuffer = (UINT)pThisDev->fReceiving;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_TURNAROUND_TIME:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_TURNAROUND_TIME)\n"));
|
||
|
|
||
|
//
|
||
|
// Indicate that the tranceiver requires at least 5000us
|
||
|
// (5 millisec) to recuperate after a send.
|
||
|
//
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
pThisDev->dongleCaps.turnAroundTime_usec;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_SUPPORTED_SPEEDS:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_SUPPORTED_SPEEDS)\n"));
|
||
|
|
||
|
if (!pThisDev->pSerialDevObj)
|
||
|
{
|
||
|
(void)pThisDev->dongle.QueryCaps(&pThisDev->dongleCaps);
|
||
|
}
|
||
|
|
||
|
speeds = pThisDev->dongleCaps.supportedSpeedsMask &
|
||
|
pThisDev->AllowedSpeedsMask &
|
||
|
ALL_SLOW_IRDA_SPEEDS;
|
||
|
|
||
|
|
||
|
*BytesWritten = 0;
|
||
|
|
||
|
for (i = 0, infoPtr = (PUINT)InformationBuffer;
|
||
|
(i < NUM_BAUDRATES) &&
|
||
|
speeds &&
|
||
|
(InformationBufferLength >= sizeof(UINT));
|
||
|
i++)
|
||
|
{
|
||
|
if (supportedBaudRateTable[i].ndisCode & speeds)
|
||
|
{
|
||
|
*infoPtr++ = supportedBaudRateTable[i].bitsPerSec;
|
||
|
InformationBufferLength -= sizeof(UINT);
|
||
|
*BytesWritten += sizeof(UINT);
|
||
|
speeds &= ~supportedBaudRateTable[i].ndisCode;
|
||
|
DEBUGMSG(DBG_OUT, (" - supporting speed %d bps\n", supportedBaudRateTable[i].bitsPerSec));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (speeds)
|
||
|
{
|
||
|
//
|
||
|
// This shouldn't happen, since we checked the
|
||
|
// InformationBuffer size earlier.
|
||
|
//
|
||
|
|
||
|
DEBUGMSG(DBG_ERROR, ("Something's wrong; previous check for buf size failed somehow\n"));
|
||
|
|
||
|
for (*BytesNeeded = 0; speeds; *BytesNeeded += sizeof(UINT))
|
||
|
{
|
||
|
//
|
||
|
// This instruction clears the lowest set bit in speeds.
|
||
|
// Trust me.
|
||
|
//
|
||
|
|
||
|
speeds &= (speeds - 1);
|
||
|
}
|
||
|
|
||
|
status = NDIS_STATUS_INVALID_LENGTH;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_LINK_SPEED:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_LINK_SPEED)\n"));
|
||
|
|
||
|
if (pThisDev->linkSpeedInfo)
|
||
|
{
|
||
|
*(UINT *)InformationBuffer =
|
||
|
pThisDev->linkSpeedInfo->bitsPerSec;
|
||
|
}
|
||
|
else {
|
||
|
*(UINT *)InformationBuffer = DEFAULT_BAUD_RATE;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
case OID_IRDA_MEDIA_BUSY:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_MEDIA_BUSY)\n"));
|
||
|
|
||
|
//
|
||
|
// If any data has been received, fMediaBusy = TRUE. However,
|
||
|
// even if fMediaBusy = FALSE, the media may be busy. We need
|
||
|
// to query the serial device object's performance statistics
|
||
|
// to see if there are any overrun or framing errors.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// NOTE: The serial device object's performance stats are
|
||
|
// cleared when the protocol set fMediaBusy to
|
||
|
// FALSE.
|
||
|
//
|
||
|
|
||
|
*(UINT *)InformationBuffer = pThisDev->fMediaBusy;
|
||
|
|
||
|
if (pThisDev->fMediaBusy == FALSE)
|
||
|
{
|
||
|
if (ScheduleWorkItem(PASSIVE_QUERY_MEDIA_BUSY, pThisDev,
|
||
|
QueryMediaBusyCallback, InformationBuffer,
|
||
|
InformationBufferLength) != NDIS_STATUS_SUCCESS)
|
||
|
{
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = NDIS_STATUS_PENDING;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*(UINT *)InformationBuffer = (UINT)pThisDev->fMediaBusy;
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_EXTRA_RCV_BOFS:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_EXTRA_RCV_BOFS)\n"));
|
||
|
|
||
|
//
|
||
|
// Pass back the number of _extra_ BOFs to be prepended
|
||
|
// to packets sent to this unit at 115.2 baud, the
|
||
|
// maximum Slow IR speed. This will be scaled for other
|
||
|
// speed according to the table in the
|
||
|
// 'Infrared Extensions to NDIS' spec.
|
||
|
//
|
||
|
|
||
|
*(UINT *)InformationBuffer =
|
||
|
pThisDev->dongleCaps.extraBOFsRequired;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_MAX_RECEIVE_WINDOW_SIZE:
|
||
|
*(PUINT)InformationBuffer = MAX_RX_PACKETS;
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_MAX_SEND_WINDOW_SIZE:
|
||
|
*(PUINT)InformationBuffer = MAX_TX_PACKETS;
|
||
|
break;
|
||
|
|
||
|
//
|
||
|
// We don't support these
|
||
|
//
|
||
|
|
||
|
case OID_IRDA_RATE_SNIFF:
|
||
|
DEBUGMSG(DBG_WARN, (" IrsirQueryInformation(OID_IRDA_RATE_SNIFF) - UNSUPPORTED\n"));
|
||
|
|
||
|
status = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_UNICAST_LIST:
|
||
|
DEBUGMSG(DBG_WARN, (" IrsirQueryInformation(OID_IRDA_UNICAST_LIST) - UNSUPPORTED\n"));
|
||
|
|
||
|
status = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_MAX_UNICAST_LIST_SIZE:
|
||
|
DEBUGMSG(DBG_WARN, (" IrsirQueryInformation(OID_IRDA_MAX_UNICAST_LIST_SIZE) - UNSUPPORTED\n"));
|
||
|
|
||
|
status = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
// PNP OIDs
|
||
|
|
||
|
case OID_PNP_CAPABILITIES:
|
||
|
case OID_PNP_ENABLE_WAKE_UP:
|
||
|
case OID_PNP_SET_POWER:
|
||
|
case OID_PNP_QUERY_POWER:
|
||
|
DEBUGMSG(DBG_WARN, ("IRSIR: PNP OID %x BufLen:%d\n", Oid, InformationBufferLength));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DEBUGMSG(DBG_WARN, (" IrsirQueryInformation(%d=0x%x), invalid OID\n", Oid, Oid));
|
||
|
|
||
|
status = NDIS_STATUS_INVALID_OID;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*BytesNeeded = infoSizeNeeded - InformationBufferLength;
|
||
|
*BytesWritten = 0;
|
||
|
status = NDIS_STATUS_INVALID_LENGTH;
|
||
|
}
|
||
|
|
||
|
|
||
|
DEBUGMSG(DBG_FUNC, ("-IrsirQueryInformation\n"));
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Function: IrsirSetInformation
|
||
|
*
|
||
|
* Synopsis: IrsirSetInformation allows other layers of the network software
|
||
|
* (e.g., a transport driver) to control the miniport driver
|
||
|
* by changing information that the miniport driver maintains
|
||
|
* in its OIDs, such as the packet filters or multicast addresses.
|
||
|
*
|
||
|
* Arguments: MiniportAdapterContext - miniport context area (PIR_DEVICE)
|
||
|
* Oid - system defined OID_Xxx
|
||
|
* InformationBuffer - buffer containing data for the set Oid
|
||
|
* InformationBufferLength - specifies size of InformationBuffer
|
||
|
* BytesRead - bytes read from InformationBuffer
|
||
|
* BytesNeeded - addition bytes required if
|
||
|
* InformationBufferLength is less than
|
||
|
* what the Oid requires to read
|
||
|
*
|
||
|
* Returns: NDIS_STATUS_SUCCESS - success
|
||
|
* NDIS_STATUS_PENDING - will complete asynchronously and
|
||
|
* call NdisMSetInformationComplete
|
||
|
* NDIS_STATUS_INVALID_OID - don't recognize the Oid
|
||
|
* NDIS_STATUS_INVALID_LENGTH- InformationBufferLength does not
|
||
|
* match length for the Oid
|
||
|
* NDIS_STATUS_INVALID_DATA - supplied data was invalid for the
|
||
|
* given Oid
|
||
|
* NDIS_STATUS_NOT_ACCEPTED - failure
|
||
|
* NDIS_STATUS_NOT_SUPPORTED - do not support an optional Oid
|
||
|
* NDIS_STATUS_RESOURCES - failed allocation of resources
|
||
|
*
|
||
|
* Algorithm:
|
||
|
*
|
||
|
* History: dd-mm-yyyy Author Comment
|
||
|
* 10/1/1996 sholden author
|
||
|
*
|
||
|
* Notes:
|
||
|
*
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
NDIS_STATUS
|
||
|
IrsirSetInformation(
|
||
|
IN NDIS_HANDLE MiniportAdapterContext,
|
||
|
IN NDIS_OID Oid,
|
||
|
IN PVOID InformationBuffer,
|
||
|
IN ULONG InformationBufferLength,
|
||
|
OUT PULONG BytesRead,
|
||
|
OUT PULONG BytesNeeded
|
||
|
)
|
||
|
{
|
||
|
NDIS_STATUS status;
|
||
|
PIR_DEVICE pThisDev;
|
||
|
SERIALPERF_STATS PerfStats;
|
||
|
|
||
|
int i;
|
||
|
|
||
|
DEBUGMSG(DBG_FUNC, ("+IrsirSetInformation\n"));
|
||
|
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
pThisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
|
||
|
|
||
|
if (InformationBufferLength >= sizeof(UINT))
|
||
|
{
|
||
|
//
|
||
|
// Set default results.
|
||
|
//
|
||
|
|
||
|
UINT info = *(UINT *)InformationBuffer;
|
||
|
*BytesRead = sizeof(UINT);
|
||
|
*BytesNeeded = 0;
|
||
|
|
||
|
switch (Oid)
|
||
|
{
|
||
|
//
|
||
|
// Generic OIDs.
|
||
|
//
|
||
|
|
||
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_GEN_CURRENT_PACKET_FILTER, %xh)\n", info));
|
||
|
|
||
|
//
|
||
|
// We ignore the packet filter itself.
|
||
|
//
|
||
|
// Note: The protocol may use a NULL filter, in which case
|
||
|
// we will not get this OID; so don't wait on
|
||
|
// OID_GEN_CURRENT_PACKET_FILTER to start receiving
|
||
|
// frames.
|
||
|
//
|
||
|
|
||
|
pThisDev->fGotFilterIndication = TRUE;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_GEN_CURRENT_LOOKAHEAD, %xh)\n", info));
|
||
|
|
||
|
//
|
||
|
// We always indicate entire receive frames all at once,
|
||
|
// so just ignore this.
|
||
|
//
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_GEN_PROTOCOL_OPTIONS:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_GEN_PROTOCOL_OPTIONS, %xh)\n", info));
|
||
|
|
||
|
//
|
||
|
// Ignore.
|
||
|
//
|
||
|
|
||
|
break;
|
||
|
|
||
|
//
|
||
|
// Infrared OIDs.
|
||
|
//
|
||
|
|
||
|
case OID_IRDA_LINK_SPEED:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_IRDA_LINK_SPEED, %xh)\n", info));
|
||
|
|
||
|
if (pThisDev->currentSpeed == info)
|
||
|
{
|
||
|
//
|
||
|
// We are already set to the requested speed.
|
||
|
//
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
|
||
|
DEBUGMSG(DBG_OUT, (" Link speed already set.\n"));
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
status = NDIS_STATUS_INVALID_DATA;
|
||
|
|
||
|
for (i = 0; i < NUM_BAUDRATES; i++)
|
||
|
{
|
||
|
if (supportedBaudRateTable[i].bitsPerSec == info)
|
||
|
{
|
||
|
//
|
||
|
// Keep a pointer to the link speed which has
|
||
|
// been requested.
|
||
|
//
|
||
|
|
||
|
pThisDev->linkSpeedInfo = &supportedBaudRateTable[i];
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (status == NDIS_STATUS_SUCCESS)
|
||
|
{
|
||
|
DEBUGMSG(DBG_OUT, (" Link speed set pending!\n"));
|
||
|
//
|
||
|
// The requested speed is supported.
|
||
|
//
|
||
|
|
||
|
if (pThisDev->pSerialDevObj==NULL)
|
||
|
{
|
||
|
pThisDev->currentSpeed = info;
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Set fPendingSetSpeed = TRUE.
|
||
|
//
|
||
|
// The receive completion/timeout routine checks the
|
||
|
// fPendingSetSpeed flag, waits for all sends to complete
|
||
|
// and then performs the SetSpeed.
|
||
|
//
|
||
|
|
||
|
pThisDev->fPendingSetSpeed = TRUE;
|
||
|
|
||
|
#if IRSIR_EVENT_DRIVEN
|
||
|
if (ScheduleWorkItem(PASSIVE_SET_SPEED, pThisDev,
|
||
|
SetSpeedCallback, NULL, 0) != NDIS_STATUS_SUCCESS)
|
||
|
{
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = NDIS_STATUS_PENDING;
|
||
|
}
|
||
|
#else
|
||
|
//
|
||
|
// We always return STATUS_PENDING to NDIS.
|
||
|
//
|
||
|
// After the SetSpeed is complete, the receive completion
|
||
|
// routine will call NdisMIndicateSetComplete.
|
||
|
//
|
||
|
|
||
|
|
||
|
status = NDIS_STATUS_PENDING;
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// status = NDIS_STATUS_INVALID_DATA
|
||
|
//
|
||
|
|
||
|
DEBUGMSG(DBG_OUT, (" Invalid link speed\n"));
|
||
|
|
||
|
*BytesRead = 0;
|
||
|
*BytesNeeded = 0;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_MEDIA_BUSY:
|
||
|
DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_IRDA_MEDIA_BUSY, %xh)\n", info));
|
||
|
|
||
|
pThisDev->fMediaBusy = (BOOLEAN)info;
|
||
|
|
||
|
if (pThisDev->pSerialDevObj==NULL ||
|
||
|
ScheduleWorkItem(PASSIVE_CLEAR_MEDIA_BUSY,
|
||
|
pThisDev, ClearMediaBusyCallback, NULL, 0)!=NDIS_STATUS_SUCCESS)
|
||
|
{
|
||
|
status = NDIS_STATUS_SUCCESS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = NDIS_STATUS_PENDING;
|
||
|
}
|
||
|
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_PNP_CAPABILITIES:
|
||
|
case OID_PNP_ENABLE_WAKE_UP:
|
||
|
case OID_PNP_SET_POWER:
|
||
|
case OID_PNP_QUERY_POWER:
|
||
|
DEBUGMSG(DBG_WARN, ("IRSIR: PNP OID %x BufLen:%d\n", Oid, InformationBufferLength));
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_RATE_SNIFF:
|
||
|
case OID_IRDA_UNICAST_LIST:
|
||
|
|
||
|
//
|
||
|
// We don't support these
|
||
|
//
|
||
|
|
||
|
DEBUGMSG(DBG_ERROR, (" IrsirSetInformation(OID=%d=0x%x, value=%xh) - unsupported OID\n", Oid, Oid, info));
|
||
|
|
||
|
*BytesRead = 0;
|
||
|
*BytesNeeded = 0;
|
||
|
status = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case OID_IRDA_SUPPORTED_SPEEDS:
|
||
|
case OID_IRDA_MAX_UNICAST_LIST_SIZE:
|
||
|
case OID_IRDA_TURNAROUND_TIME:
|
||
|
|
||
|
//
|
||
|
// These are query-only parameters (invalid).
|
||
|
//
|
||
|
|
||
|
default:
|
||
|
DEBUGMSG(DBG_ERROR, (" IrsirSetInformation(OID=%d=0x%x, value=%xh) - invalid OID\n", Oid, Oid, info));
|
||
|
|
||
|
*BytesRead = 0;
|
||
|
*BytesNeeded = 0;
|
||
|
status = NDIS_STATUS_INVALID_OID;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// The given data buffer is not large enough for the information
|
||
|
// to set.
|
||
|
//
|
||
|
|
||
|
*BytesRead = 0;
|
||
|
*BytesNeeded = sizeof(UINT);
|
||
|
status = NDIS_STATUS_INVALID_LENGTH;
|
||
|
}
|
||
|
|
||
|
DEBUGMSG(DBG_FUNC, ("-IrsirSetInformation\n"));
|
||
|
|
||
|
return status;
|
||
|
}
|