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.
1146 lines
29 KiB
1146 lines
29 KiB
/**************************************************************************************************************************
|
|
* IRCOMMON.H SigmaTel STIR4200 common USB/IR definitions
|
|
**************************************************************************************************************************
|
|
* (C) Unpublished Copyright of Sigmatel, Inc. All Rights Reserved.
|
|
*
|
|
*
|
|
* Created: 04/06/2000
|
|
* Version 0.9
|
|
* Edited: 04/24/2000
|
|
* Version 0.91
|
|
* Edited: 04/27/2000
|
|
* Version 0.92
|
|
* Edited: 05/03/2000
|
|
* Version 0.93
|
|
* Edited: 05/12/2000
|
|
* Version 0.94
|
|
* Edited: 05/19/2000
|
|
* Version 0.95
|
|
* Edited: 07/27/2000
|
|
* Version 1.01
|
|
* Edited: 09/16/2000
|
|
* Version 1.03
|
|
* Edited: 09/25/2000
|
|
* Version 1.10
|
|
* Edited: 11/09/2000
|
|
* Version 1.12
|
|
* Edited: 02/20/2001
|
|
* Version 1.15
|
|
*
|
|
**************************************************************************************************************************/
|
|
|
|
#ifndef _IRCOM_H
|
|
#define _IRCOM_H
|
|
|
|
#include "stir4200.h"
|
|
|
|
//
|
|
// This is for use by check-for-hang handler and is just a reasonable guess;
|
|
// Total # of USBD control errors, read aerrors and write errors;
|
|
// Used by check-for-hang handler to decide if we need a reset
|
|
//
|
|
#define IRUSB_100ns_PER_ms 10000
|
|
#define IRUSB_100ns_PER_us 10
|
|
#define IRUSB_ms_PER_SEC 1000
|
|
#define IRUSB_100ns_PER_SEC ( IRUSB_100ns_PER_ms * IRUSB_ms_PER_SEC )
|
|
|
|
#define MAX_QUERY_TIME_100ns ( 8 * IRUSB_100ns_PER_SEC ) //8 sec
|
|
#define MAX_SET_TIME_100ns MAX_QUERY_TIME_100ns
|
|
#define MAX_SEND_TIME_100ns ( 20 * IRUSB_100ns_PER_SEC ) //20 sec
|
|
|
|
#define MAX_TURNAROUND_usec 10000
|
|
|
|
#define DEFAULT_TURNAROUND_usec 1000
|
|
|
|
//
|
|
// Customer data area size.
|
|
// Big enough for 2 byte header (7e7e) + one byte count + 255 bytes data.
|
|
// Header bytes are not sent back to app.
|
|
//
|
|
#define STIR4200_CUST_DATA_SIZE (2+256)
|
|
|
|
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
|
|
#define MAX(a,b) (((a) >= (b)) ? (a) : (b))
|
|
|
|
//
|
|
// A receive buffer is either FREE (not holding anything) FULL
|
|
// (holding undelivered data) or PENDING (holding data delivered
|
|
// asynchronously)
|
|
//
|
|
typedef enum
|
|
{
|
|
RCV_STATE_FREE,
|
|
RCV_STATE_FULL,
|
|
RCV_STATE_PENDING
|
|
} RCV_BUFFER_STATE, FIFO_BUFFER_STATE;
|
|
|
|
//
|
|
// Structure to keep track of receive packets and buffers to indicate
|
|
// receive data to the protocol.
|
|
//
|
|
typedef struct
|
|
{
|
|
PVOID pPacket;
|
|
UINT DataLen;
|
|
PUCHAR pDataBuf;
|
|
PVOID pThisDev;
|
|
ULONG fInRcvDpc;
|
|
RCV_BUFFER_STATE BufferState;
|
|
#if defined(DIAGS)
|
|
LIST_ENTRY ListEntry; // This will be used to do the diags queueing
|
|
#endif
|
|
#if defined(WORKAROUND_MISSING_C1)
|
|
BOOLEAN MissingC1Detected;
|
|
BOOLEAN MissingC1Possible;
|
|
#endif
|
|
} RCV_BUFFER, *PRCV_BUFFER;
|
|
|
|
//
|
|
// Structure to read data from the FIFO
|
|
//
|
|
typedef struct
|
|
{
|
|
UINT DataLen;
|
|
PUCHAR pDataBuf;
|
|
PVOID pThisDev;
|
|
PVOID pIrp;
|
|
PURB pUrb; // urb allocated by irp send routine, deallocated
|
|
UINT UrbLen; // by irp completion handler
|
|
FIFO_BUFFER_STATE BufferState;
|
|
} FIFO_BUFFER, *PFIFO_BUFFER;
|
|
|
|
//
|
|
// All different sizes for data
|
|
//
|
|
#define IRDA_ADDRESS_FIELD_SIZE 1
|
|
#define IRDA_CONTROL_FIELD_SIZE 1
|
|
#define IRDA_A_C_TOTAL_SIZE ( IRDA_ADDRESS_FIELD_SIZE + IRDA_CONTROL_FIELD_SIZE )
|
|
|
|
#define USB_IRDA_TOTAL_NON_DATA_SIZE ( IRDA_ADDRESS_FIELD_SIZE + IRDA_CONTROL_FIELD_SIZE )
|
|
#define IRDA_MAX_DATAONLY_SIZE 2048
|
|
#define MAX_TOTAL_SIZE_WITH_ALL_HEADERS ( IRDA_MAX_DATAONLY_SIZE + USB_IRDA_TOTAL_NON_DATA_SIZE )
|
|
|
|
#define MAX_NUM_EXTRA_BOFS 48
|
|
|
|
// Fix for MS Security Bug #533267
|
|
#define MAX_POSSIBLE_IR_PACKET_SIZE_FOR_DATA(dataLen) ( \
|
|
(dataLen) * 2 + (MAX_NUM_EXTRA_BOFS + 1) * \
|
|
SLOW_IR_BOF_SIZE + IRDA_ADDRESS_FIELD_SIZE + IRDA_CONTROL_FIELD_SIZE + \
|
|
(2 * FAST_IR_FCS_SIZE) + (2 * SLOW_IR_FCS_SIZE) + SLOW_IR_EOF_SIZE) + \
|
|
sizeof(STIR4200_FRAME_HEADER)
|
|
|
|
//
|
|
// Note that the receive size needs to be incremented to account for
|
|
// the way the decoding can use one more byte
|
|
//
|
|
#define MAX_RCV_DATA_SIZE (MAX_TOTAL_SIZE_WITH_ALL_HEADERS + FAST_IR_FCS_SIZE + 1)
|
|
|
|
#define MAX_IRDA_DATA_SIZE MAX_POSSIBLE_IR_PACKET_SIZE_FOR_DATA(IRDA_MAX_DATAONLY_SIZE)
|
|
|
|
//
|
|
// Possible speeds
|
|
//
|
|
typedef enum _BAUD_RATE
|
|
{
|
|
//
|
|
// Slow IR
|
|
//
|
|
BAUDRATE_2400 = 0,
|
|
BAUDRATE_9600,
|
|
BAUDRATE_19200,
|
|
BAUDRATE_38400,
|
|
BAUDRATE_57600,
|
|
BAUDRATE_115200,
|
|
|
|
//
|
|
// Medium IR
|
|
//
|
|
#if !defined(DWORKAROUND_BROKEN_MIR)
|
|
BAUDRATE_576000,
|
|
BAUDRATE_1152000,
|
|
#endif
|
|
//
|
|
// Fast IR
|
|
//
|
|
BAUDRATE_4000000,
|
|
|
|
//
|
|
// must be last
|
|
//
|
|
NUM_BAUDRATES
|
|
|
|
} BAUD_RATE;
|
|
|
|
typedef enum _IR_MODE
|
|
{
|
|
IR_MODE_SIR = 0,
|
|
IR_MODE_MIR,
|
|
IR_MODE_FIR,
|
|
NUM_IR_MODES
|
|
} IR_MODE;
|
|
|
|
//
|
|
// Speeds
|
|
//
|
|
#define SPEED_2400 2400
|
|
#define SPEED_9600 9600
|
|
#define SPEED_19200 19200
|
|
#define SPEED_38400 38400
|
|
#define SPEED_57600 57600
|
|
#define SPEED_115200 115200
|
|
#define SPEED_576000 576000
|
|
#define SPEED_1152000 1152000
|
|
#define SPEED_4000000 4000000
|
|
|
|
#define DEFAULT_BAUD_RATE SPEED_9600
|
|
|
|
#define MAX_SIR_SPEED SPEED_115200
|
|
#define MAX_MIR_SPEED SPEED_1152000
|
|
|
|
|
|
//
|
|
// Sizes of IrLAP frame fields:
|
|
// Beginning Of Frame (BOF)
|
|
// End Of Frame (EOF)
|
|
// Address
|
|
// Control
|
|
//
|
|
#define SLOW_IR_BOF_TYPE UCHAR
|
|
#define SLOW_IR_BOF_SIZE sizeof(SLOW_IR_BOF_TYPE)
|
|
#define SLOW_IR_EOF_TYPE UCHAR
|
|
#define SLOW_IR_EOF_SIZE sizeof(SLOW_IR_EOF_TYPE)
|
|
#define SLOW_IR_FCS_TYPE USHORT
|
|
#define SLOW_IR_FCS_SIZE sizeof(SLOW_IR_FCS_TYPE)
|
|
#define SLOW_IR_BOF 0xC0
|
|
#define SLOW_IR_EOF 0xC1
|
|
#define SLOW_IR_ESC 0x7D
|
|
#define SLOW_IR_ESC_COMP 0x20
|
|
#define SLOW_IR_EXTRA_BOF_TYPE UCHAR
|
|
#define SLOW_IR_EXTRA_BOF_SIZE sizeof(SLOW_IR_EXTRA_BOF_TYPE)
|
|
#define SLOW_IR_EXTRA_BOF 0xC0
|
|
|
|
#define MEDIUM_IR_BOF 0x7E
|
|
#define MEDIUM_IR_EOF 0x7E
|
|
#define MEDIUM_IR_FCS_TYPE USHORT
|
|
#define MEDIUM_IR_FCS_SIZE sizeof(MEDIUM_IR_FCS_TYPE)
|
|
|
|
#define FAST_IR_FCS_TYPE ULONG
|
|
#define FAST_IR_FCS_SIZE sizeof(FAST_IR_FCS_TYPE)
|
|
#define FAST_IR_EOF_TYPE ULONG
|
|
#define FAST_IR_EOF_SIZE sizeof(FAST_IR_EOF_TYPE)
|
|
|
|
//
|
|
// Definition for speed masks
|
|
//
|
|
#define NDIS_IRDA_SPEED_MASK_2400 0x001 // SLOW IR ...
|
|
#define NDIS_IRDA_SPEED_MASK_9600 0x003
|
|
#define NDIS_IRDA_SPEED_MASK_19200 0x007
|
|
#define NDIS_IRDA_SPEED_MASK_38400 0x00f
|
|
#define NDIS_IRDA_SPEED_MASK_57600 0x01f
|
|
#define NDIS_IRDA_SPEED_MASK_115200 0x03f
|
|
#define NDIS_IRDA_SPEED_MASK_576K 0x07f // MEDIUM IR ...
|
|
#define NDIS_IRDA_SPEED_MASK_1152K 0x0ff
|
|
#define NDIS_IRDA_SPEED_MASK_4M 0x1ff // FAST IR
|
|
|
|
#define GOOD_FCS ((USHORT) ~0xf0b8)
|
|
#define FIR_GOOD_FCS ((ULONG) ~0xdebb20e3)
|
|
|
|
typedef struct
|
|
{
|
|
BAUD_RATE TableIndex;
|
|
UINT BitsPerSec;
|
|
IR_MODE IrMode;
|
|
UINT NdisCode; // bitmask element as used by ndis and in class-specific descriptor
|
|
UCHAR Stir4200Divisor;
|
|
} BAUDRATE_INFO;
|
|
|
|
|
|
//
|
|
// Struct to hold the IR USB dongle's USB Class-Specific Descriptor as per
|
|
// "Universal Serial Bus IrDA Bridge Device Definition" doc, section 7.2
|
|
// This is the struct returned by USBD as the result of a request with an urb
|
|
// of type _URB_CONTROL_VENDOR_OR_CLASS_REQUEST, function URB_FUNCTION_CLASS_DEVICE
|
|
//
|
|
|
|
// Enable 1-byte alignment in the below struct
|
|
#pragma pack (push,1)
|
|
|
|
typedef struct _IRUSB_CLASS_SPECIFIC_DESCRIPTOR
|
|
{
|
|
BOOLEAN ClassConfigured;
|
|
|
|
UCHAR bmDataSize; // max bytes allowed in any frame as per IrLAP spec, where:
|
|
|
|
#define BM_DATA_SIZE_2048 (1 << 5)
|
|
#define BM_DATA_SIZE_1024 (1 << 4)
|
|
#define BM_DATA_SIZE_512 (1 << 3)
|
|
#define BM_DATA_SIZE_256 (1 << 2)
|
|
#define BM_DATA_SIZE_128 (1 << 1)
|
|
#define BM_DATA_SIZE_64 (1 << 0)
|
|
|
|
UCHAR bmWindowSize; // max un-acked frames that can be received
|
|
// before an ack is sent, where:
|
|
#define BM_WINDOW_SIZE_7 (1 << 6)
|
|
#define BM_WINDOW_SIZE_6 (1 << 5)
|
|
#define BM_WINDOW_SIZE_5 (1 << 4)
|
|
#define BM_WINDOW_SIZE_4 (1 << 3)
|
|
#define BM_WINDOW_SIZE_3 (1 << 2)
|
|
#define BM_WINDOW_SIZE_2 (1 << 1)
|
|
#define BM_WINDOW_SIZE_1 (1 << 0)
|
|
|
|
UCHAR bmMinTurnaroundTime; // min millisecs required for recovery between
|
|
// end of last xmission and can receive again, where:
|
|
#define BM_TURNAROUND_TIME_0ms (1 << 7) // 0 ms
|
|
#define BM_TURNAROUND_TIME_0p01ms (1 << 6) // 0.01 ms
|
|
#define BM_TURNAROUND_TIME_0p05ms (1 << 5) // 0.05 ms
|
|
#define BM_TURNAROUND_TIME_0p1ms (1 << 4) // 0.1 ms
|
|
#define BM_TURNAROUND_TIME_0p5ms (1 << 3) // 0.5 ms
|
|
#define BM_TURNAROUND_TIME_1ms (1 << 2) // 1 ms
|
|
#define BM_TURNAROUND_TIME_5ms (1 << 1) // 5 ms
|
|
#define BM_TURNAROUND_TIME_10ms (1 << 0) // 10 ms
|
|
|
|
USHORT wBaudRate;
|
|
|
|
//
|
|
// ir speed masks as used both by NDIS and as formatted in USB class-specfic descriptor
|
|
//
|
|
#define NDIS_IRDA_SPEED_2400 (1 << 0) // SLOW IR ...
|
|
#define NDIS_IRDA_SPEED_9600 (1 << 1)
|
|
#define NDIS_IRDA_SPEED_19200 (1 << 2)
|
|
#define NDIS_IRDA_SPEED_38400 (1 << 3)
|
|
#define NDIS_IRDA_SPEED_57600 (1 << 4)
|
|
#define NDIS_IRDA_SPEED_115200 (1 << 5)
|
|
#define NDIS_IRDA_SPEED_576K (1 << 6) // MEDIUM IR ...
|
|
#define NDIS_IRDA_SPEED_1152K (1 << 7)
|
|
#define NDIS_IRDA_SPEED_4M (1 << 8) // FAST IR
|
|
|
|
|
|
UCHAR bmExtraBofs; // #BOFS required at 115200; 0 if slow speeds <=115200 not supported
|
|
|
|
#define BM_EXTRA_BOFS_0 (1 << 7)
|
|
#define BM_EXTRA_BOFS_1 (1 << 6)
|
|
#define BM_EXTRA_BOFS_2 (1 << 5)
|
|
#define BM_EXTRA_BOFS_3 (1 << 4)
|
|
#define BM_EXTRA_BOFS_6 (1 << 3)
|
|
#define BM_EXTRA_BOFS_12 (1 << 2)
|
|
#define BM_EXTRA_BOFS_24 (1 << 1)
|
|
#define BM_EXTRA_BOFS_48 (1 << 0)
|
|
|
|
} IRUSB_CLASS_SPECIFIC_DESCRIPTOR, *PIRUSB_CLASS_SPECIFIC_DESCRIPTOR;
|
|
|
|
#pragma pack (pop) //disable 1-byte alignment
|
|
|
|
|
|
typedef struct _DONGLE_CAPABILITIES
|
|
{
|
|
//
|
|
// Time (in microseconds) that must transpire between
|
|
// a transmit and the next receive.
|
|
//
|
|
LONG turnAroundTime_usec; // gotten from class-specific descriptor
|
|
|
|
//
|
|
// Max un-acked frames that can be received
|
|
// before an ack is sent
|
|
//
|
|
UINT windowSize; // gotten from class-specific descriptor
|
|
|
|
//
|
|
// #BOFS required at 115200; 0 if slow speeds <=115200 are not supported
|
|
//
|
|
UINT extraBOFS; // gotten from class-specific descriptor
|
|
|
|
//
|
|
// max bytes allowed in any frame as per IrLAP spec
|
|
//
|
|
UINT dataSize; // gotten from class-specific descriptor
|
|
|
|
} DONGLE_CAPABILITIES, *PDONGLE_CAPABILITIES;
|
|
|
|
|
|
//
|
|
// Enum of context types for SendPacket
|
|
//
|
|
typedef enum _CONTEXT_TYPE
|
|
{
|
|
CONTEXT_NDIS_PACKET,
|
|
CONTEXT_SET_SPEED,
|
|
CONTEXT_READ_WRITE_REGISTER,
|
|
CONTEXT_DIAGS_ENABLE,
|
|
CONTEXT_DIAGS_DISABLE,
|
|
CONTEXT_DIAGS_READ_REGISTERS,
|
|
CONTEXT_DIAGS_WRITE_REGISTER,
|
|
CONTEXT_DIAGS_BULK_OUT,
|
|
CONTEXT_DIAGS_BULK_IN,
|
|
CONTEXT_DIAGS_SEND
|
|
} CONTEXT_TYPE;
|
|
|
|
typedef NTSTATUS (*WORK_PROC)(struct _IR_WORK_ITEM *);
|
|
|
|
typedef struct _IR_WORK_ITEM
|
|
{
|
|
PVOID pIrDevice;
|
|
WORK_PROC Callback;
|
|
PUCHAR pInfoBuf;
|
|
ULONG InfoBufLen;
|
|
ULONG fInUse; // declared as ulong for use with interlockedexchange
|
|
} IR_WORK_ITEM, *PIR_WORK_ITEM;
|
|
|
|
//
|
|
// Transceiver type definition
|
|
//
|
|
typedef enum _TRANSCEIVER_TYPE
|
|
{
|
|
TRANSCEIVER_4012 = 0,
|
|
TRANSCEIVER_4000,
|
|
TRANSCEIVER_VISHAY,
|
|
TRANSCEIVER_VISHAY_6102F,
|
|
TRANSCEIVER_INFINEON,
|
|
TRANSCEIVER_HP,
|
|
TRANSCEIVER_CUSTOM
|
|
} TRANSCEIVER_TYPE;
|
|
|
|
//
|
|
// Receive mode definition
|
|
//
|
|
typedef enum _RXMODE
|
|
{
|
|
RXMODE_SLOW = 0,
|
|
RXMODE_SLOWFAST,
|
|
RXMODE_FAST
|
|
} RXMODE;
|
|
|
|
//
|
|
// Chip revision definition
|
|
//
|
|
typedef enum _CHIP_REVISION
|
|
{
|
|
CHIP_REVISION_6 = 5,
|
|
CHIP_REVISION_7,
|
|
CHIP_REVISION_8
|
|
} CHIP_REVISION;
|
|
|
|
typedef struct _IR_DEVICE
|
|
{
|
|
//
|
|
// Keep track of various device objects.
|
|
//
|
|
PDEVICE_OBJECT pUsbDevObj; //'Next Device Object'
|
|
PDEVICE_OBJECT pPhysDevObj; // Physical Device Object
|
|
|
|
//
|
|
// This is the handle that the NDIS wrapper associates with a connection.
|
|
// (The handle that the miniport driver associates with the connection
|
|
// is just an index into the devStates array).
|
|
//
|
|
HANDLE hNdisAdapter;
|
|
|
|
//
|
|
// The dongle interface allows us to check the tranceiver type once
|
|
// and then set up the interface to allow us to init, set speed,
|
|
// and deinit the dongle.
|
|
//
|
|
// We also want the dongle capabilities.
|
|
//
|
|
DONGLE_CAPABILITIES dongleCaps;
|
|
|
|
//
|
|
// Type of transceiver installed
|
|
//
|
|
TRANSCEIVER_TYPE TransceiverType;
|
|
|
|
//
|
|
// Receive mode
|
|
//
|
|
RXMODE ReceiveMode;
|
|
|
|
//
|
|
// Revision of the installed 4200
|
|
//
|
|
CHIP_REVISION ChipRevision;
|
|
|
|
//
|
|
// Current speed setting, in bits/sec.
|
|
// Note: This is updated when we ACTUALLY change the speed,
|
|
// not when we get the request to change speed via
|
|
// irusbSetInformation.
|
|
//
|
|
//
|
|
// When speed is changed, we have to clear the send queue before
|
|
// setting the new speed on the hardware.
|
|
// These vars let us remember to do it.
|
|
//
|
|
UINT currentSpeed;
|
|
|
|
//
|
|
// Current link speed information. This also will maintain the
|
|
// chosen speed if the protocol requests a speed change.
|
|
//
|
|
BAUDRATE_INFO *linkSpeedInfo;
|
|
|
|
//
|
|
// Maintain statistical debug info.
|
|
//
|
|
ULONG packetsReceived;
|
|
ULONG packetsReceivedDropped;
|
|
ULONG packetsReceivedOverflow;
|
|
ULONG packetsReceivedChecksum;
|
|
ULONG packetsReceivedRunt;
|
|
ULONG packetsReceivedNoBuffer;
|
|
ULONG packetsSent;
|
|
ULONG packetsSentDropped;
|
|
ULONG packetsSentRejected;
|
|
ULONG packetsSentInvalid;
|
|
|
|
#if DBG
|
|
ULONG packetsHeldByProtocol;
|
|
ULONG MaxPacketsHeldByProtocol;
|
|
ULONG TotalBytesReceived;
|
|
ULONG TotalBytesSent;
|
|
ULONG NumYesQueryMediaBusyOids;
|
|
ULONG NumNoQueryMediaBusyOids;
|
|
ULONG NumSetMediaBusyOids;
|
|
ULONG NumMediaBusyIndications;
|
|
ULONG NumPacketsSentRequiringTurnaroundTime;
|
|
ULONG NumPacketsSentNotRequiringTurnaroundTime;
|
|
#endif
|
|
|
|
//
|
|
// used by check hang handler to track Query, Set, and Send times
|
|
//
|
|
LARGE_INTEGER LastQueryTime;
|
|
LARGE_INTEGER LastSetTime;
|
|
BOOLEAN fSetpending;
|
|
BOOLEAN fQuerypending;
|
|
|
|
//
|
|
// Set when device has been started; use for safe cleanup after failed initialization
|
|
//
|
|
BOOLEAN fDeviceStarted;
|
|
|
|
//
|
|
// Indicates that we have received an OID_GEN_CURRENT_PACKET_FILTER
|
|
// indication from the protocol. We can deliver received packets to the
|
|
// protocol.
|
|
//
|
|
BOOLEAN fGotFilterIndication;
|
|
|
|
//
|
|
// NDIS calls most of the MiniportXxx function with IRQL DISPATCH_LEVEL.
|
|
// There are a number of instances where the ir device must send
|
|
// requests to the device which may be synchronous and
|
|
// we can't block in DISPATCH_LEVEL. Therefore, we set up a thread to deal
|
|
// with request which require PASSIVE_LEVEL. An event is used to signal
|
|
// the thread that work is required.
|
|
//
|
|
HANDLE hPassiveThread;
|
|
BOOLEAN fKillPassiveLevelThread;
|
|
|
|
KEVENT EventPassiveThread;
|
|
|
|
/*
|
|
According to W2000 ddk doc:
|
|
The IrDA protocol driver sets this OID to zero to request the miniport to
|
|
start monitoring for a media busy condition. The IrDA protocol
|
|
can then query this OID to determine whether the media is busy.
|
|
If the media is not busy, the miniport returns a zero for this
|
|
OID when queried. If the media is busy,that is, if the miniport
|
|
has detected some traffic since the IrDA protocol driver last
|
|
set OID_IRDA_MEDIA_BUSY to zero the miniport returns a non-zero
|
|
value for this OID when queried. On detecting the media busy
|
|
condition. the miniport must also call NdisMIndicateStatus to
|
|
indicate NDIS_STATUS_MEDIA_BUSY. When the media is busy,
|
|
the IrDA protocol driver will not send packets to the miniport
|
|
for transmission. After the miniport has detected a busy state,
|
|
it does not have to monitor for a media busy condition until
|
|
the IrDA protocol driver again sets OID_IRDA_MEDIA_BUSY to zero.
|
|
|
|
According to USB IrDA Bridge Device Definition Doc sec 5.4.1.2:
|
|
|
|
The bmStatus field indicators shall be set by the Device as follows:
|
|
Media_Busy
|
|
· Media_Busy shall indicate zero (0) if the Device:
|
|
. has not received a Check Media Busy class-specific request
|
|
. has detected no traffic on the infrared media since receiving a Check Media Busy
|
|
. class-specific request
|
|
. Has returned a header with Media_Busy set to one (1) since receiving a Check
|
|
Media Busy class-specific request.
|
|
|
|
· Media_Busy shall indicate one (1) if the Device has detected traffic on the infrared
|
|
media since receiving a Check Media Busy class-specific request. Note that
|
|
Media_Busy shall indicate one (1) in exactly one header following receipt of each
|
|
Check Media Busy class-specific request.
|
|
|
|
According to USB IrDA Bridge Device Definition Doc sec 6.2.2:
|
|
|
|
Check Media Busy
|
|
This class-specific request instructs the Device to look for a media busy condition. If infrared
|
|
traffic of any kind is detected by this Device, the Device shall set the Media_Busy field in the
|
|
bmStatus field in the next Data-In packet header sent to the host. In the case where a Check
|
|
Media Busy command has been received, a media busy condition detected, and no IrLAP frame
|
|
traffic is ready to transmit to the host, the Device shall set the Media_Busy field and send it in a
|
|
Data-In packet with no IrLAP frame following the header.
|
|
|
|
bmRequestType bRequest wValue wIndex wLength Data
|
|
00100001B 3 Zero Interface Zero [None]
|
|
|
|
*/
|
|
ULONG fMediaBusy; // declare as ULONGS for use with InterlockedExchange
|
|
ULONG fIndicatedMediaBusy;
|
|
|
|
//
|
|
// The variable fProcessing is used to indicate that the ir device
|
|
// object has an active polling thread,
|
|
//
|
|
// Under normal circumstances fReceiving should always be TRUE.
|
|
// However sometimes the processing has to be stopped
|
|
// and this variable is used to synchronize
|
|
//
|
|
ULONG fProcessing;
|
|
|
|
//
|
|
// To be set to true when really receiving packets
|
|
//
|
|
ULONG fCurrentlyReceiving;
|
|
|
|
//
|
|
// The variables fPendingHalt and fPendingReset allow the send and receive
|
|
// completion routines to complete the current pending irp and
|
|
// then cleanup and stop sending irps to the USB driver.
|
|
//
|
|
BOOLEAN fPendingHalt;
|
|
BOOLEAN fPendingReset;
|
|
|
|
|
|
ULONG fPendingReadClearStall;
|
|
ULONG fPendingWriteClearStall;
|
|
|
|
//
|
|
// This is required when the part gets into a complete USB hang and a reset is required
|
|
//
|
|
ULONG fPendingClearTotalStall;
|
|
|
|
//
|
|
// We keep an array of receive buffers so that we don't continually
|
|
// need to allocate buffers to indicate packets to the protocol.
|
|
// Since the protocol can retain ownership of up to eight packets
|
|
// and we can be receiving up to WindowSize ( 7 ) packets while the protocol has
|
|
// ownership of eight packets, we will allocate 16 packets for
|
|
// receiving.
|
|
//
|
|
#define NUM_RCV_BUFS 16
|
|
|
|
RCV_BUFFER rcvBufs[NUM_RCV_BUFS];
|
|
PRCV_BUFFER pCurrentRecBuf;
|
|
|
|
FIFO_BUFFER PreReadBuffer;
|
|
|
|
//
|
|
// Can have max of NUM_RCV_BUFS packets pending + one set and one query
|
|
//
|
|
#define NUM_WORK_ITEMS (NUM_RCV_BUFS+3)
|
|
|
|
IR_WORK_ITEM WorkItems[NUM_WORK_ITEMS];
|
|
|
|
//
|
|
// Since we can have multiple write irps pending with the USB driver,
|
|
// we track the irp contexts for each one so we have all the info we need at each
|
|
// invokation of the USB write completion routine. See the IRUSB_CONTEXT definition below
|
|
// There are 128 contexts for sending, one for read/write operations, one for setting the speed
|
|
// and one for diagnostic operations
|
|
//
|
|
#define NUM_SEND_CONTEXTS 131
|
|
|
|
PVOID pSendContexts;
|
|
|
|
//
|
|
// Handles to the NDIS packet pool and NDIS buffer pool
|
|
// for allocating the receive buffers.
|
|
//
|
|
HANDLE hPacketPool;
|
|
HANDLE hBufferPool;
|
|
BOOLEAN BufferPoolAllocated;
|
|
|
|
KEVENT EventSyncUrb;
|
|
KEVENT EventAsyncUrb;
|
|
|
|
NTSTATUS StatusControl;
|
|
NTSTATUS StatusReadWrite;
|
|
NTSTATUS StatusSendReceive;
|
|
|
|
//
|
|
// track pending IRPS; this should be zero at halt time
|
|
//
|
|
UINT PendingIrpCount;
|
|
ULONG NumReads;
|
|
ULONG NumWrites;
|
|
ULONG NumReadWrites;
|
|
|
|
//
|
|
// various USB errors
|
|
//
|
|
ULONG NumDataErrors;
|
|
ULONG NumReadWriteErrors;
|
|
|
|
HANDLE BulkInPipeHandle;
|
|
HANDLE BulkOutPipeHandle;
|
|
|
|
HANDLE hPollingThread;
|
|
BOOLEAN fKillPollingThread;
|
|
|
|
//
|
|
// The IR USB dongle's USB Class-Specific Descriptor as per
|
|
// "Universal Serial Bus IrDA Bridge Device Definition" doc, section 7.2
|
|
// This is the struct returned by USBD as the result of a request with an urb
|
|
// of type _URB_CONTROL_VENDOR_OR_CLASS_REQUEST, function URB_FUNCTION_CLASS_DEVICE.
|
|
// Note this struct is in-line, not a pointer
|
|
//
|
|
IRUSB_CLASS_SPECIFIC_DESCRIPTOR ClassDesc;
|
|
|
|
UINT IdVendor; // USB vendor Id read from dongle
|
|
|
|
//
|
|
// We don't define it here because we need to isolate USB stuff so we
|
|
// can build things referencing NDIS with the BINARY_COMPATIBLE flag for win9x
|
|
//
|
|
PUCHAR pUsbInfo;
|
|
|
|
//
|
|
// Optional registry entry for debugging; limit baud rate.
|
|
// The mask is set up as per the USB Class-Specific descriptor 'wBaudRate'
|
|
// This is 'and'ed with value from Class descriptor to possibly limit baud rate;
|
|
// It defaults to 0xffff
|
|
//
|
|
UINT BaudRateMask;
|
|
|
|
//
|
|
// Necessary to read the registry fields
|
|
//
|
|
NDIS_HANDLE WrapperConfigurationContext;
|
|
|
|
//
|
|
// IR Tranceiver Model
|
|
//
|
|
STIR4200_TRANCEIVER StIrTranceiver;
|
|
|
|
//
|
|
// Send buffers (works only if sending is serialied)
|
|
//
|
|
PUCHAR pBuffer;
|
|
UINT BufLen;
|
|
PUCHAR pStagingBuffer;
|
|
|
|
//
|
|
// Send FIFO count
|
|
//
|
|
ULONG SendFifoCount;
|
|
|
|
//
|
|
// Receive adaptive delay
|
|
//
|
|
ULONG ReceiveAdaptiveDelay;
|
|
ULONG ReceiveAdaptiveDelayBoost;
|
|
|
|
// MS Security issue - removed pUrb
|
|
|
|
//
|
|
// Receive buffer and positions
|
|
//
|
|
UCHAR pRawBuf[STIR4200_FIFO_SIZE];
|
|
ULONG rawCleanupBytesRead;
|
|
PORT_RCV_STATE rcvState;
|
|
ULONG readBufPos;
|
|
BOOLEAN fReadHoldingReg;
|
|
ULONG PreFifoCount;
|
|
|
|
//
|
|
// Send lists and lock
|
|
//
|
|
LIST_ENTRY SendAvailableQueue;
|
|
LIST_ENTRY SendBuiltQueue;
|
|
LIST_ENTRY SendPendingQueue;
|
|
ULONG SendAvailableCount;
|
|
ULONG SendBuiltCount;
|
|
ULONG SendPendingCount;
|
|
KSPIN_LOCK SendLock;
|
|
|
|
//
|
|
// Read and write register list, shares the other send queues
|
|
//
|
|
LIST_ENTRY ReadWritePendingQueue;
|
|
ULONG ReadWritePendingCount;
|
|
|
|
//
|
|
// Diagnostics
|
|
//
|
|
#if defined(DIAGS)
|
|
ULONG DiagsActive;
|
|
ULONG DiagsPendingActivation;
|
|
PVOID pIOCTL;
|
|
NTSTATUS IOCTLStatus;
|
|
KEVENT EventDiags;
|
|
LIST_ENTRY DiagsReceiveQueue;
|
|
KSPIN_LOCK DiagsReceiveLock;
|
|
#endif
|
|
NDIS_HANDLE NdisDeviceHandle;
|
|
|
|
//
|
|
// Logging
|
|
//
|
|
#if defined(RECEIVE_LOGGING)
|
|
HANDLE ReceiveFileHandle;
|
|
__int64 ReceiveFilePosition;
|
|
#endif
|
|
|
|
#if defined(RECEIVE_ERROR_LOGGING)
|
|
HANDLE ReceiveErrorFileHandle;
|
|
__int64 ReceiveErrorFilePosition;
|
|
#endif
|
|
|
|
#if defined(SEND_LOGGING)
|
|
HANDLE SendFileHandle;
|
|
__int64 SendFilePosition;
|
|
#endif
|
|
|
|
#if !defined(WORKAROUND_BROKEN_MIR)
|
|
//
|
|
// Mir in software
|
|
//
|
|
UCHAR pRawUnstuffedBuf[STIR4200_FIFO_SIZE];
|
|
UCHAR MirIncompleteByte;
|
|
ULONG MirIncompleteBitCount;
|
|
ULONG MirOneBitCount;
|
|
ULONG MirFlagCount;
|
|
#endif
|
|
|
|
//
|
|
// Dummy send fix
|
|
//
|
|
BOOLEAN GearedDown;
|
|
|
|
//
|
|
// Fix for FIR permanent invalid state
|
|
//
|
|
BOOLEAN StuckFir;
|
|
|
|
//
|
|
// Customer data area.
|
|
//
|
|
UCHAR pCustomerData[STIR4200_CUST_DATA_SIZE];
|
|
BOOLEAN CustomerDataRead;
|
|
|
|
//
|
|
// Used in Diagnostic version.
|
|
//
|
|
#if defined(VARIABLE_SETTINGS)
|
|
ULONG SirDpll;
|
|
ULONG FirDpll;
|
|
ULONG SirSensitivity;
|
|
ULONG FirSensitivity;
|
|
#endif
|
|
} IR_DEVICE, *PIR_DEVICE;
|
|
|
|
|
|
//
|
|
// We use a pointer to the IR_DEVICE structure as the miniport's device context.
|
|
//
|
|
|
|
#define CONTEXT_TO_DEV(__deviceContext) ((PIR_DEVICE)(__deviceContext))
|
|
#define DEV_TO_CONTEXT(__irdev) ((HANDLE)(__irdev))
|
|
|
|
#define IRUSB_TAG 'RITS'
|
|
|
|
|
|
VOID
|
|
MyNdisMSetInformationComplete(
|
|
IN PIR_DEVICE pThisDev,
|
|
IN NDIS_STATUS Status
|
|
);
|
|
|
|
VOID
|
|
MyNdisMQueryInformationComplete(
|
|
IN PIR_DEVICE pThisDev,
|
|
IN NDIS_STATUS Status
|
|
);
|
|
|
|
USHORT
|
|
ComputeFCS16(
|
|
IN PUCHAR pData,
|
|
UINT DataLen
|
|
);
|
|
|
|
ULONG
|
|
ComputeFCS32(
|
|
IN PUCHAR pData,
|
|
ULONG DataLen
|
|
);
|
|
|
|
BOOLEAN
|
|
NdisToFirPacket(
|
|
IN PIR_DEVICE pIrDev,
|
|
IN PNDIS_PACKET pPacket,
|
|
OUT PUCHAR pIrPacketBuf,
|
|
ULONG IrPacketBufLen,
|
|
IN PUCHAR pContigPacketBuf,
|
|
OUT PULONG pIrPacketLen
|
|
);
|
|
|
|
BOOLEAN
|
|
NdisToMirPacket(
|
|
IN PIR_DEVICE pIrDev,
|
|
IN PNDIS_PACKET pPacket,
|
|
OUT PUCHAR pIrPacketBuf,
|
|
ULONG IrPacketBufLen,
|
|
IN PUCHAR pContigPacketBuf,
|
|
OUT PULONG pIrPacketLen
|
|
);
|
|
|
|
BOOLEAN
|
|
NdisToSirPacket(
|
|
IN PIR_DEVICE pIrDev,
|
|
IN PNDIS_PACKET pPacket,
|
|
OUT PUCHAR pIrPacketBuf,
|
|
ULONG IrPacketBufLen,
|
|
IN PUCHAR pContigPacketBuf,
|
|
OUT PULONG pIrPacketLen
|
|
);
|
|
|
|
BOOLEAN
|
|
ReceiveFirStepFSM(
|
|
IN OUT PIR_DEVICE pIrDev,
|
|
OUT PULONG pBytesProcessed
|
|
);
|
|
|
|
BOOLEAN
|
|
ReceiveMirStepFSM(
|
|
IN OUT PIR_DEVICE pIrDev,
|
|
OUT PULONG pBytesProcessed
|
|
);
|
|
|
|
#if !defined(WORKAROUND_BROKEN_MIR)
|
|
BOOLEAN
|
|
ReceiveMirUnstuff(
|
|
IN OUT PIR_DEVICE pIrDev,
|
|
IN PUCHAR pInputBuffer,
|
|
ULONG InputBufferSize,
|
|
OUT PUCHAR pOutputBuffer,
|
|
OUT PULONG pOutputBufferSize
|
|
);
|
|
#endif
|
|
|
|
BOOLEAN
|
|
ReceiveSirStepFSM(
|
|
IN OUT PIR_DEVICE pIrDev,
|
|
OUT PULONG pBytesProcessed
|
|
);
|
|
|
|
VOID
|
|
ReceiveProcessFifoData(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
VOID
|
|
ReceiveResetPointers(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
NTSTATUS
|
|
ReceivePreprocessFifo(
|
|
IN OUT PIR_DEVICE pThisDev,
|
|
OUT PULONG pFifoCount
|
|
);
|
|
|
|
NTSTATUS
|
|
ReceiveGetFifoData(
|
|
IN OUT PIR_DEVICE pThisDev,
|
|
OUT PUCHAR pData,
|
|
OUT PULONG pBytesRead,
|
|
ULONG BytesToRead
|
|
);
|
|
|
|
VOID
|
|
ReceiveProcessReturnPacket(
|
|
OUT PIR_DEVICE pThisDev,
|
|
OUT PRCV_BUFFER pReceiveBuffer
|
|
);
|
|
|
|
NTSTATUS
|
|
ReceivePacketRead(
|
|
IN PIR_DEVICE pThisDev,
|
|
OUT PFIFO_BUFFER pRecBuf
|
|
);
|
|
|
|
NTSTATUS
|
|
ReceiveCompletePacketRead(
|
|
IN PDEVICE_OBJECT pUsbDevObj,
|
|
IN PIRP pIrp,
|
|
IN PVOID Context
|
|
);
|
|
|
|
VOID
|
|
IndicateMediaBusy(
|
|
IN PIR_DEVICE pThisDev
|
|
);
|
|
|
|
VOID
|
|
IrUsb_IncIoCount(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
VOID
|
|
IrUsb_DecIoCount(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
NTSTATUS
|
|
IrUsb_GetDongleCaps(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
VOID
|
|
IrUsb_SetDongleCaps(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
VOID
|
|
MyMemFree(
|
|
IN PVOID pMem,
|
|
IN UINT size
|
|
);
|
|
|
|
PVOID
|
|
MyMemAlloc(
|
|
UINT size
|
|
);
|
|
|
|
VOID
|
|
MyUrbFree(
|
|
IN PURB pUrb,
|
|
IN UINT size
|
|
);
|
|
|
|
PURB
|
|
MyUrbAlloc(
|
|
UINT size
|
|
);
|
|
|
|
BOOLEAN
|
|
AllocUsbInfo(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
VOID
|
|
FreeUsbInfo(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
VOID
|
|
PollingThread(
|
|
IN OUT PVOID Context
|
|
);
|
|
|
|
extern BAUDRATE_INFO supportedBaudRateTable[NUM_BAUDRATES];
|
|
|
|
VOID
|
|
ReceiveDeliverBuffer(
|
|
IN OUT PIR_DEVICE pThisDev,
|
|
IN PRCV_BUFFER pRecBuf
|
|
);
|
|
|
|
NTSTATUS
|
|
InitializeProcessing(
|
|
IN OUT PIR_DEVICE pThisDev,
|
|
IN BOOLEAN InitPassiveThread
|
|
);
|
|
|
|
NTSTATUS
|
|
IrUsb_ResetPipe (
|
|
IN PIR_DEVICE pThisDev,
|
|
IN HANDLE Pipe
|
|
);
|
|
|
|
BOOLEAN
|
|
IrUsb_InitSendStructures(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
VOID
|
|
IrUsb_FreeSendStructures(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
NDIS_STATUS
|
|
SendPacketPreprocess(
|
|
IN OUT PIR_DEVICE pThisDev,
|
|
IN PVOID pPacketToSend
|
|
);
|
|
|
|
NDIS_STATUS
|
|
SendPreprocessedPacketSend(
|
|
IN OUT PIR_DEVICE pThisDev,
|
|
IN PVOID pContext
|
|
);
|
|
|
|
NTSTATUS
|
|
SendWaitCompletion(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
NTSTATUS
|
|
SendCheckForOverflow(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
NTSTATUS
|
|
SendCompletePacketSend(
|
|
IN PDEVICE_OBJECT pUsbDevObj,
|
|
IN PIRP pIrp,
|
|
IN PVOID Context
|
|
);
|
|
|
|
PRCV_BUFFER
|
|
ReceiveGetBuf(
|
|
PIR_DEVICE pThisDev,
|
|
OUT PUINT pIndex,
|
|
IN RCV_BUFFER_STATE BufferState
|
|
);
|
|
|
|
VOID
|
|
PassiveLevelThread(
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
ScheduleWorkItem(
|
|
IN OUT PIR_DEVICE pThisDev,
|
|
WORK_PROC Callback,
|
|
IN PVOID pInfoBuf,
|
|
ULONG InfoBufLen
|
|
);
|
|
|
|
VOID
|
|
FreeWorkItem(
|
|
IN OUT PIR_WORK_ITEM pItem
|
|
);
|
|
|
|
VOID
|
|
IrUsb_PrepareSetSpeed(
|
|
IN OUT PIR_DEVICE pThisDev
|
|
);
|
|
|
|
NTSTATUS
|
|
ResetPipeCallback (
|
|
IN PIR_WORK_ITEM pWorkItem
|
|
);
|
|
|
|
PVOID
|
|
AllocXferUrb (
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
FreeXferUrb(
|
|
IN OUT PVOID pUrb
|
|
);
|
|
|
|
#endif // _IRCOM_H
|