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