Leaked source code of windows server 2003
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.

1472 lines
44 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. rasirda.c
  5. Abstract:
  6. Miniport peice of the irda NDIS 5 miniport (WAN driver)
  7. Author:
  8. mbert 9-97
  9. --*/
  10. #include "rasirdap.h"
  11. // Globals
  12. #if DBG
  13. #include <irioctl.h>
  14. #if 0
  15. int DbgSettings =
  16. DBG_INIT |
  17. DBG_CONFIG |
  18. DBG_CONNECT |
  19. // DBG_SEND |
  20. // DBG_RECV |
  21. DBG_LIB_OBJ |
  22. DBG_LIB_CONNECT |
  23. DBG_ERROR |
  24. 1;
  25. #else
  26. int DbgSettings = 0;
  27. #endif
  28. int DbgOutput =
  29. DBG_OUTPUT_BUFFER |
  30. DBG_OUTPUT_DEBUGGER |
  31. 0;
  32. PDRIVER_OBJECT pRasIrDriverObject;
  33. PDEVICE_OBJECT pRasIrDeviceObject;
  34. NTSTATUS
  35. DbgDispatch(
  36. PDEVICE_OBJECT pDeviceObject,
  37. PIRP pIrp);
  38. #endif
  39. NDIS_SPIN_LOCK RasIrSpinLock;
  40. LIST_ENTRY RasIrAdapterList;
  41. const USHORT FcsTable[256] = {
  42. 0x0000,0x1189,0x2312,0x329B,0x4624,0x57AD,0x6536,0x74BF,
  43. 0x8C48,0x9DC1,0xAF5A,0xBED3,0xCA6C,0xDBE5,0xE97E,0xF8F7,
  44. 0x1081,0x0108,0x3393,0x221A,0x56A5,0x472C,0x75B7,0x643E,
  45. 0x9CC9,0x8D40,0xBFDB,0xAE52,0xDAED,0xCB64,0xF9FF,0xE876,
  46. 0x2102,0x308B,0x0210,0x1399,0x6726,0x76AF,0x4434,0x55BD,
  47. 0xAD4A,0xBCC3,0x8E58,0x9FD1,0xEB6E,0xFAE7,0xC87C,0xD9F5,
  48. 0x3183,0x200A,0x1291,0x0318,0x77A7,0x662E,0x54B5,0x453C,
  49. 0xBDCB,0xAC42,0x9ED9,0x8F50,0xFBEF,0xEA66,0xD8FD,0xC974,
  50. 0x4204,0x538D,0x6116,0x709F,0x0420,0x15A9,0x2732,0x36BB,
  51. 0xCE4C,0xDFC5,0xED5E,0xFCD7,0x8868,0x99E1,0xAB7A,0xBAF3,
  52. 0x5285,0x430C,0x7197,0x601E,0x14A1,0x0528,0x37B3,0x263A,
  53. 0xDECD,0xCF44,0xFDDF,0xEC56,0x98E9,0x8960,0xBBFB,0xAA72,
  54. 0x6306,0x728F,0x4014,0x519D,0x2522,0x34AB,0x0630,0x17B9,
  55. 0xEF4E,0xFEC7,0xCC5C,0xDDD5,0xA96A,0xB8E3,0x8A78,0x9BF1,
  56. 0x7387,0x620E,0x5095,0x411C,0x35A3,0x242A,0x16B1,0x0738,
  57. 0xFFCF,0xEE46,0xDCDD,0xCD54,0xB9EB,0xA862,0x9AF9,0x8B70,
  58. 0x8408,0x9581,0xA71A,0xB693,0xC22C,0xD3A5,0xE13E,0xF0B7,
  59. 0x0840,0x19C9,0x2B52,0x3ADB,0x4E64,0x5FED,0x6D76,0x7CFF,
  60. 0x9489,0x8500,0xB79B,0xA612,0xD2AD,0xC324,0xF1BF,0xE036,
  61. 0x18C1,0x0948,0x3BD3,0x2A5A,0x5EE5,0x4F6C,0x7DF7,0x6C7E,
  62. 0xA50A,0xB483,0x8618,0x9791,0xE32E,0xF2A7,0xC03C,0xD1B5,
  63. 0x2942,0x38CB,0x0A50,0x1BD9,0x6F66,0x7EEF,0x4C74,0x5DFD,
  64. 0xB58B,0xA402,0x9699,0x8710,0xF3AF,0xE226,0xD0BD,0xC134,
  65. 0x39C3,0x284A,0x1AD1,0x0B58,0x7FE7,0x6E6E,0x5CF5,0x4D7C,
  66. 0xC60C,0xD785,0xE51E,0xF497,0x8028,0x91A1,0xA33A,0xB2B3,
  67. 0x4A44,0x5BCD,0x6956,0x78DF,0x0C60,0x1DE9,0x2F72,0x3EFB,
  68. 0xD68D,0xC704,0xF59F,0xE416,0x90A9,0x8120,0xB3BB,0xA232,
  69. 0x5AC5,0x4B4C,0x79D7,0x685E,0x1CE1,0x0D68,0x3FF3,0x2E7A,
  70. 0xE70E,0xF687,0xC41C,0xD595,0xA12A,0xB0A3,0x8238,0x93B1,
  71. 0x6B46,0x7ACF,0x4854,0x59DD,0x2D62,0x3CEB,0x0E70,0x1FF9,
  72. 0xF78F,0xE606,0xD49D,0xC514,0xB1AB,0xA022,0x92B9,0x8330,
  73. 0x7BC7,0x6A4E,0x58D5,0x495C,0x3DE3,0x2C6A,0x1EF1,0x0F78
  74. };
  75. NDIS_STATUS
  76. DriverEntry(
  77. IN PDRIVER_OBJECT DriverObject,
  78. IN PUNICODE_STRING RegistryPath);
  79. NDIS_STATUS
  80. QueryInformation(
  81. IN PRASIR_ADAPTER pAdapter,
  82. IN PRASIR_VC pVc,
  83. IN NDIS_OID Oid,
  84. IN PVOID InformationBuffer,
  85. IN ULONG InformationBufferLength,
  86. OUT PULONG BytesWritten,
  87. OUT PULONG BytesNeeded);
  88. NDIS_STATUS
  89. SetInformation(
  90. IN PRASIR_ADAPTER pAdapter,
  91. IN PRASIR_VC pVc,
  92. IN NDIS_OID Oid,
  93. IN PVOID InformationBuffer,
  94. IN ULONG InformationBufferLength,
  95. OUT PULONG BytesRead,
  96. OUT PULONG BytesNeeded);
  97. #pragma NDIS_INIT_FUNCTION(DriverEntry)
  98. NDIS_STATUS
  99. DriverEntry(
  100. IN PDRIVER_OBJECT DriverObject,
  101. IN PUNICODE_STRING RegistryPath )
  102. {
  103. NDIS_STATUS Status;
  104. NDIS_MINIPORT_CHARACTERISTICS MiniportChr;
  105. NDIS_HANDLE NdisWrapperHandle;
  106. #if DBG
  107. UNICODE_STRING DeviceName;
  108. int i;
  109. #endif
  110. DEBUGMSG(DBG_INIT, ("RASIR: DriverEntry\n"));
  111. IrdaClientInitialize();
  112. NdisAllocateSpinLock(&RasIrSpinLock);
  113. InitializeListHead(&RasIrAdapterList);
  114. NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject,
  115. RegistryPath, NULL );
  116. NdisZeroMemory( &MiniportChr, sizeof(MiniportChr) );
  117. MiniportChr.MajorNdisVersion = NDIS_MajorVersion;
  118. MiniportChr.MinorNdisVersion = NDIS_MinorVersion;
  119. MiniportChr.Reserved = NDIS_USE_WAN_WRAPPER;
  120. MiniportChr.HaltHandler = RasIrHalt;
  121. MiniportChr.InitializeHandler = RasIrInitialize;
  122. MiniportChr.ResetHandler = RasIrReset;
  123. MiniportChr.ReturnPacketHandler = RasIrReturnPacket;
  124. MiniportChr.CoActivateVcHandler = RasIrCoActivateVc;
  125. MiniportChr.CoDeactivateVcHandler = RasIrCoDeactivateVc;
  126. MiniportChr.CoSendPacketsHandler = RasIrCoSendPackets;
  127. MiniportChr.CoRequestHandler = RasIrCoRequest;
  128. // no CheckForHangHandler
  129. // no DisableInterruptHandler
  130. // no EnableInterruptHandler
  131. // no HandleInterruptHandler
  132. // no ISRHandler
  133. // no QueryInformationHandler (see CoRequestHandler)
  134. // no SendHandler (see CoSendPacketsHandler)
  135. // no WanSendHandler (see CoSendPacketsHandler)
  136. // no SetInformationHandler (see CoRequestHandler)
  137. // no TransferDataHandler
  138. // no WanTransferDataHandler
  139. // no SendPacketsHandler (see CoSendPacketsHandler)
  140. // no AllocateCompleteHandler
  141. Status = NdisMRegisterMiniport(NdisWrapperHandle, &MiniportChr, sizeof(MiniportChr));
  142. if (Status != NDIS_STATUS_SUCCESS)
  143. {
  144. DEBUGMSG(DBG_ERROR, ("RASIR: ->NdisMRegisterMiniport failed %x\n", Status));
  145. NdisTerminateWrapper(NdisWrapperHandle, NULL);
  146. }
  147. #if 0
  148. DbgMsgInit();
  149. RtlInitUnicodeString(&DeviceName, L"\\Device\\RASIR");
  150. Status = IoCreateDevice(
  151. DriverObject, // DriverObject
  152. 0, // DeviceExtensionSize
  153. &DeviceName, // DeviceName
  154. FILE_DEVICE_NETWORK, // DeviceType
  155. 0, // DeviceCharacteristics
  156. FALSE, // Exclusive?
  157. &pRasIrDeviceObject); // DeviceObject pointer returned
  158. if (Status != STATUS_SUCCESS)
  159. DbgPrint("Failed to create device\n");
  160. else
  161. {
  162. DriverObject->DriverUnload = NULL;
  163. DriverObject->FastIoDispatch = NULL;
  164. for (i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
  165. {
  166. DriverObject->MajorFunction[i] = DbgDispatch;
  167. }
  168. pRasIrDeviceObject->Flags |= DO_DIRECT_IO;
  169. }
  170. #endif
  171. return Status;
  172. }
  173. VOID
  174. FreeAdapter(PRASIR_ADAPTER pAdapter)
  175. {
  176. ASSERT(IsListEmpty(&pAdapter->VcList));
  177. #if DBG
  178. pAdapter->Sig = 0xBAD;
  179. #endif
  180. NdisDeleteNPagedLookasideList(&pAdapter->WorkItemsLList);
  181. NdisDeleteNPagedLookasideList(&pAdapter->AsyncBufLList);
  182. NdisFreeMemory(pAdapter, sizeof(PRASIR_ADAPTER), 0);
  183. }
  184. NDIS_STATUS
  185. RasIrInitialize(
  186. OUT PNDIS_STATUS OpenErrorStatus,
  187. OUT PUINT SelectedMediumIndex,
  188. IN PNDIS_MEDIUM MediumArray,
  189. IN UINT MediumArraySize,
  190. IN NDIS_HANDLE MiniportAdapterHandle,
  191. IN NDIS_HANDLE WrapperConfigurationContext)
  192. {
  193. UINT i;
  194. PRASIR_ADAPTER pAdapter;
  195. NDIS_CALL_MANAGER_CHARACTERISTICS CallMgrChr;
  196. CO_ADDRESS_FAMILY Family;
  197. NDIS_STATUS Status;
  198. NDIS_HANDLE hConfig;
  199. PNDIS_CONFIGURATION_PARAMETER Value;
  200. NDIS_STRING TapiLineNameString = NDIS_STRING_CONST("TapiLineName");
  201. NDIS_STRING ModemPortString = NDIS_STRING_CONST("ModemPort");
  202. ULONG ModemPort;
  203. DEBUGMSG(DBG_ERROR, ("RASIR: Miniport initialize\n"));
  204. for (i = 0; i < MediumArraySize; ++i)
  205. {
  206. if (MediumArray[i] == NdisMediumCoWan)
  207. break;
  208. }
  209. if (i == MediumArraySize)
  210. {
  211. DEBUGMSG(DBG_ERROR, ("RASIR: No matching media\n"));
  212. return NDIS_STATUS_FAILURE;
  213. }
  214. *SelectedMediumIndex = i;
  215. NdisAllocateMemoryWithTag((PVOID *)&pAdapter, sizeof(RASIR_ADAPTER),
  216. MT_RASIR_ADAPTER);
  217. if (pAdapter == NULL)
  218. return NDIS_STATUS_RESOURCES;
  219. NdisZeroMemory(pAdapter, sizeof(RASIR_ADAPTER));
  220. InitializeListHead(&pAdapter->VcList);
  221. InitializeListHead(&pAdapter->EndpList);
  222. NdisInitializeNPagedLookasideList(
  223. &pAdapter->WorkItemsLList,
  224. NULL, NULL, 0,
  225. sizeof(NDIS_WORK_ITEM),
  226. MT_RASIR_WORKITEM, // RasIr work item
  227. 10);
  228. NdisInitializeNPagedLookasideList(
  229. &pAdapter->AsyncBufLList,
  230. NULL, NULL, 0,
  231. sizeof(ASYNC_BUFFER),
  232. MT_RASIR_ASYNCBUF, // RasIr work item
  233. 0);
  234. NdisAllocateSpinLock(&pAdapter->SpinLock);
  235. NdisOpenConfiguration(&Status, &hConfig, WrapperConfigurationContext);
  236. if (Status == NDIS_STATUS_SUCCESS)
  237. {
  238. pAdapter->TapiLineNameBuf[0] = 0;
  239. pAdapter->TapiLineName.Buffer = pAdapter->TapiLineNameBuf;
  240. pAdapter->TapiLineName.Length = 0;
  241. pAdapter->TapiLineName.MaximumLength = sizeof(pAdapter->TapiLineNameBuf);
  242. NdisReadConfiguration(&Status,
  243. &Value,
  244. hConfig,
  245. &TapiLineNameString,
  246. NdisParameterString);
  247. if (Status == NDIS_STATUS_SUCCESS)
  248. {
  249. RtlCopyUnicodeString(&pAdapter->TapiLineName, &Value->ParameterData.StringData);
  250. *(PWCHAR)(pAdapter->TapiLineName.Buffer + (pAdapter->TapiLineName.MaximumLength)/sizeof(WCHAR)) = UNICODE_NULL;
  251. } else {
  252. //
  253. // could not get the line name
  254. //
  255. NdisCloseConfiguration(hConfig);
  256. goto Done;
  257. }
  258. NdisReadConfiguration(&Status,
  259. &Value,
  260. hConfig,
  261. &ModemPortString,
  262. NdisParameterInteger);
  263. if (Status == NDIS_STATUS_SUCCESS)
  264. {
  265. pAdapter->ModemPort = (BOOLEAN) Value->ParameterData.IntegerData;
  266. }
  267. NdisCloseConfiguration(hConfig);
  268. } else {
  269. //
  270. // could open the config info
  271. //
  272. goto Done;
  273. }
  274. DEBUGMSG(DBG_CONFIG, ("RASIR: ModemPort = %d\n", pAdapter->ModemPort));
  275. pAdapter->MiniportAdapterHandle = MiniportAdapterHandle;
  276. pAdapter->Info.MaxFrameSize = IRDA_MAX_DATA_SIZE;
  277. pAdapter->Info.MaxSendWindow = 4;
  278. pAdapter->Info.FramingBits = PPP_FRAMING |
  279. PPP_COMPRESS_ADDRESS_CONTROL |
  280. PPP_COMPRESS_PROTOCOL_FIELD;
  281. pAdapter->Info.DesiredACCM = 0;
  282. #if DBG
  283. pAdapter->Sig = (ULONG)ADAPTER_SIG;
  284. #endif
  285. // Inform NDIS of the attributes of our adapter. Set the
  286. // 'MiniportAdapterContext' returned to us by NDIS when it calls our
  287. // handlers to the address of our adapter control block. Turn off
  288. // hardware oriented timeouts.
  289. //
  290. NdisMSetAttributesEx(
  291. MiniportAdapterHandle,
  292. (NDIS_HANDLE)pAdapter,
  293. (UINT)-1,
  294. NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT
  295. | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT,
  296. NdisInterfaceInternal);
  297. NdisZeroMemory(&Family, sizeof(Family));
  298. Family.MajorVersion = NDIS_MajorVersion;
  299. Family.MinorVersion = NDIS_MinorVersion;
  300. Family.AddressFamily = CO_ADDRESS_FAMILY_TAPI_PROXY;
  301. NdisZeroMemory(&CallMgrChr, sizeof(CallMgrChr));
  302. CallMgrChr.MajorVersion = NDIS_MajorVersion;
  303. CallMgrChr.MinorVersion = NDIS_MinorVersion;
  304. CallMgrChr.CmCreateVcHandler = RasIrCmCreateVc;
  305. CallMgrChr.CmDeleteVcHandler = RasIrCmDeleteVc;
  306. CallMgrChr.CmOpenAfHandler = RasIrCmOpenAf;
  307. CallMgrChr.CmCloseAfHandler = RasIrCmCloseAf;
  308. CallMgrChr.CmRegisterSapHandler = RasIrCmRegisterSap;
  309. CallMgrChr.CmDeregisterSapHandler = RasIrCmDeregisterSap;
  310. CallMgrChr.CmMakeCallHandler = RasIrCmMakeCall;
  311. CallMgrChr.CmCloseCallHandler = RasIrCmCloseCall;
  312. CallMgrChr.CmIncomingCallCompleteHandler= RasIrCmIncomingCallComplete;
  313. CallMgrChr.CmActivateVcCompleteHandler = RasIrCmActivateVcComplete;
  314. CallMgrChr.CmDeactivateVcCompleteHandler= RasIrCmDeactivateVcComplete;
  315. CallMgrChr.CmModifyCallQoSHandler = RasIrCmModifyCallQoS;
  316. CallMgrChr.CmRequestHandler = RasIrCmRequest;
  317. // no CmAddPartyHandler
  318. // no CmDropPartyHandler
  319. Status = NdisMCmRegisterAddressFamily(
  320. MiniportAdapterHandle, &Family, &CallMgrChr,
  321. sizeof(CallMgrChr));
  322. Done:
  323. if (Status != NDIS_STATUS_SUCCESS)
  324. {
  325. FreeAdapter(pAdapter);
  326. DEBUGMSG(DBG_ERROR, ("RASIR: NdisMCmRegisterFamily failed %X\n",
  327. Status));
  328. }
  329. else
  330. {
  331. NdisInterlockedInsertTailList(&RasIrAdapterList,
  332. &pAdapter->Linkage,
  333. &RasIrSpinLock);
  334. }
  335. return Status;
  336. }
  337. VOID
  338. RasIrHalt(
  339. IN NDIS_HANDLE MiniportAdapterContext)
  340. {
  341. PRASIR_ADAPTER pAdapter = MiniportAdapterContext;
  342. GOODADAPTER(pAdapter);
  343. NdisAcquireSpinLock(&RasIrSpinLock);
  344. RemoveEntryList(&pAdapter->Linkage);
  345. NdisReleaseSpinLock(&RasIrSpinLock);
  346. DEBUGMSG(DBG_ERROR, ("RASIR: Halt!\n"));
  347. FreeAdapter(pAdapter);
  348. return;
  349. }
  350. NDIS_STATUS
  351. RasIrReset(
  352. OUT PBOOLEAN AddressingReset,
  353. IN NDIS_HANDLE MiniportAdapterContext)
  354. {
  355. return NDIS_STATUS_NOT_RESETTABLE;
  356. }
  357. NDIS_STATUS
  358. RasIrCoActivateVc(
  359. IN NDIS_HANDLE MiniportVcContext,
  360. IN OUT PCO_CALL_PARAMETERS CallParameters)
  361. {
  362. return STATUS_SUCCESS;
  363. }
  364. NDIS_STATUS
  365. RasIrCoDeactivateVc(
  366. IN NDIS_HANDLE MiniportVcContext)
  367. {
  368. return STATUS_SUCCESS;
  369. }
  370. UINT
  371. AddAsyncFraming(
  372. IN PUCHAR pOutBuf,
  373. IN PNDIS_BUFFER pNdisBuf,
  374. IN ULONG Accm)
  375. {
  376. PUCHAR pData;
  377. int DataLen;
  378. USHORT Fcs = 0xFFFF;
  379. PUCHAR pBuf = pOutBuf;
  380. PUCHAR pEndBuf = pOutBuf + ASYNC_BUF_SIZE;
  381. NdisQueryBufferSafe(pNdisBuf, &pData, &DataLen, NormalPagePriority);
  382. if (pData == NULL)
  383. {
  384. return 0;
  385. }
  386. ASSERT(DataLen);
  387. *pBuf++ = AF_FLAG_CHAR;
  388. while (DataLen != 0)
  389. {
  390. int i;
  391. for (i = 0; i < DataLen; i++)
  392. {
  393. Fcs = CALC_FCS(Fcs, pData[i]);
  394. STUFF_BYTE(pBuf, pData[i], Accm);
  395. }
  396. NdisGetNextBuffer(pNdisBuf, &pNdisBuf);
  397. if (pNdisBuf)
  398. {
  399. NdisQueryBufferSafe(pNdisBuf, &pData, &DataLen, NormalPagePriority);
  400. if (pData == NULL)
  401. {
  402. return 0;
  403. }
  404. }
  405. else
  406. {
  407. break;
  408. }
  409. if (pBuf > pEndBuf)
  410. {
  411. return 0;
  412. }
  413. }
  414. Fcs = ~(Fcs);
  415. STUFF_BYTE(pBuf, ((CHAR) (Fcs & 0xFF)), Accm);
  416. STUFF_BYTE(pBuf, ((CHAR) (Fcs >> 8)), Accm);
  417. *pBuf++ = AF_FLAG_CHAR;
  418. return (UINT)((UINT_PTR)pBuf - (UINT_PTR) pOutBuf);
  419. }
  420. VOID
  421. RasIrCoSendPackets(
  422. IN NDIS_HANDLE MiniportVcContext,
  423. IN PPNDIS_PACKET PacketArray,
  424. IN UINT NumberOfPackets )
  425. {
  426. PRASIR_VC pVc = MiniportVcContext;
  427. UINT i;
  428. PNDIS_BUFFER pNdisBuf;
  429. UINT PacketLen;
  430. NTSTATUS Status = NDIS_STATUS_SUCCESS;
  431. BOOLEAN VcDown = FALSE;
  432. PASYNC_BUFFER pAsyncBuf;
  433. PMDL pSendNdisBuf;
  434. GOODVC(pVc);
  435. for (i = 0; i < NumberOfPackets; i++)
  436. {
  437. Status = NDIS_STATUS_SUCCESS;
  438. NdisQueryPacket(PacketArray[i], NULL, NULL, &pNdisBuf, &PacketLen);
  439. ASSERT(PacketLen <= IRDA_MAX_DATA_SIZE);
  440. *((PVOID *) &PacketArray[i]->MiniportReserved[0]) = NULL;
  441. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  442. REFADD(&pVc->RefCnt, 'DNES');
  443. pVc->OutstandingSends += 1;
  444. if (!(pVc->Flags & VCF_IRDA_OPEN))
  445. {
  446. DEBUGMSG(DBG_ERROR, ("RASIR: Not sending on Vc %X, Irda is closed\n", pVc));
  447. Status = NDIS_STATUS_CLOSED;
  448. }
  449. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  450. if (Status == NDIS_STATUS_SUCCESS)
  451. {
  452. if (!pVc->AsyncFraming)
  453. {
  454. pSendNdisBuf = pNdisBuf;
  455. }
  456. else
  457. {
  458. pAsyncBuf = NdisAllocateFromNPagedLookasideList(
  459. &pVc->pAdapter->AsyncBufLList);
  460. *((PVOID *) &PacketArray[i]->MiniportReserved[0]) = pAsyncBuf;
  461. if (!pAsyncBuf)
  462. {
  463. Status = NDIS_STATUS_RESOURCES;
  464. }
  465. else
  466. {
  467. UINT FrameLen;
  468. pAsyncBuf->pNdisBuf = NULL;
  469. FrameLen = AddAsyncFraming(pAsyncBuf->Buf, pNdisBuf,
  470. pVc->LinkInfo.SendACCM);
  471. if (!FrameLen)
  472. {
  473. DEBUGMSG(DBG_ERROR, ("RASIR: not sending, AsyncFraming failed\n"));
  474. IrdaSendComplete(pVc, PacketArray[i], Status);
  475. continue;
  476. }
  477. NdisAllocateBuffer(&Status, &pAsyncBuf->pNdisBuf,
  478. pVc->TxBufferPool, pAsyncBuf->Buf, FrameLen);
  479. if (Status == NDIS_STATUS_SUCCESS)
  480. {
  481. pSendNdisBuf = pAsyncBuf->pNdisBuf;
  482. }
  483. else
  484. {
  485. DEBUGMSG(DBG_ERROR, ("RASIR: NdisAllocateBuffer failed %X\n", Status));
  486. }
  487. }
  488. }
  489. }
  490. if (Status == NDIS_STATUS_SUCCESS)
  491. {
  492. IrdaSend(pVc->IrdaConnContext, pSendNdisBuf, PacketArray[i]);
  493. }
  494. else
  495. {
  496. IrdaSendComplete(pVc, PacketArray[i], Status);
  497. continue;
  498. }
  499. DEBUGMSG(DBG_SEND, ("RASIR: IrdaSend %X len %d pending\n",
  500. PacketArray[i], PacketLen));
  501. }
  502. }
  503. VOID
  504. RasIrReceiveComplete(
  505. PRASIR_VC pVc,
  506. PVOID pRxBuf)
  507. {
  508. if (pVc->AsyncFraming)
  509. {
  510. // Async frames where already completed in
  511. // ProcessAsyncRxPacket() so just return the
  512. // buffer owned by rasir to the BufList
  513. NdisFreeToNPagedLookasideList(
  514. &pVc->pAdapter->AsyncBufLList,
  515. pRxBuf);
  516. }
  517. else
  518. {
  519. IrdaReceiveComplete(pVc->IrdaConnContext,
  520. (PIRDA_RECVBUF) pRxBuf);
  521. }
  522. }
  523. VOID
  524. RasIrReturnPacket(
  525. IN NDIS_HANDLE MiniportAdapterContext,
  526. IN PNDIS_PACKET pNdisPacket)
  527. {
  528. PVOID pRxBuf;
  529. PRASIR_VC pVc;
  530. PNDIS_BUFFER pNdisBuf;
  531. pVc = *((PRASIR_VC *) &pNdisPacket->MiniportReserved[0]);
  532. pRxBuf = *((PVOID *) &pNdisPacket->MiniportReserved[sizeof(PUCHAR)]);
  533. GOODVC(pVc);
  534. DEBUGMSG(DBG_RECV, ("RASIR: ReturnPacket %X\n", pRxBuf));
  535. RasIrReceiveComplete(pVc, pRxBuf);
  536. NdisUnchainBufferAtFront(pNdisPacket, &pNdisBuf);
  537. NdisFreeBuffer(pNdisBuf);
  538. NdisFreePacket(pNdisPacket);
  539. REFDEL(&pVc->RefCnt, 'VCER');
  540. return;
  541. }
  542. NDIS_STATUS
  543. RasIrCoRequest(
  544. IN NDIS_HANDLE MiniportAdapterContext,
  545. IN NDIS_HANDLE MiniportVcContext,
  546. IN OUT PNDIS_REQUEST NdisRequest)
  547. {
  548. NDIS_STATUS Status;
  549. PRASIR_ADAPTER pAdapter = MiniportAdapterContext;
  550. PRASIR_VC pVc = MiniportVcContext;
  551. DEBUGMSG(DBG_CONFIG, ("RASIR: RasIrCoRequest() type %X\n",
  552. NdisRequest->RequestType));
  553. switch (NdisRequest->RequestType)
  554. {
  555. case NdisRequestQueryInformation:
  556. {
  557. Status = QueryInformation(
  558. pAdapter,
  559. pVc,
  560. NdisRequest->DATA.QUERY_INFORMATION.Oid,
  561. NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
  562. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
  563. &NdisRequest->DATA.QUERY_INFORMATION.BytesWritten,
  564. &NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded );
  565. break;
  566. }
  567. case NdisRequestSetInformation:
  568. {
  569. Status = SetInformation(
  570. pAdapter,
  571. pVc,
  572. NdisRequest->DATA.SET_INFORMATION.Oid,
  573. NdisRequest->DATA.SET_INFORMATION.InformationBuffer,
  574. NdisRequest->DATA.SET_INFORMATION.InformationBufferLength,
  575. &NdisRequest->DATA.SET_INFORMATION.BytesRead,
  576. &NdisRequest->DATA.SET_INFORMATION.BytesNeeded );
  577. break;
  578. }
  579. default:
  580. {
  581. Status = NDIS_STATUS_NOT_SUPPORTED;
  582. break;
  583. }
  584. }
  585. return Status;
  586. }
  587. NDIS_STATUS
  588. QueryInformation(
  589. IN PRASIR_ADAPTER pAdapter,
  590. IN PRASIR_VC pVc,
  591. IN NDIS_OID Oid,
  592. IN PVOID InformationBuffer,
  593. IN ULONG InformationBufferLength,
  594. OUT PULONG BytesWritten,
  595. OUT PULONG BytesNeeded)
  596. {
  597. NDIS_STATUS status;
  598. ULONG ulInfo;
  599. VOID* pInfo;
  600. ULONG ulInfoLen;
  601. status = NDIS_STATUS_SUCCESS;
  602. // The cases in this switch statement find or create a buffer containing
  603. // the requested information and point 'pInfo' at it, noting it's length
  604. // in 'ulInfoLen'. Since many of the OIDs return a ULONG, a 'ulInfo'
  605. // buffer is set up as the default.
  606. //
  607. ulInfo = 0;
  608. pInfo = &ulInfo;
  609. ulInfoLen = sizeof(ulInfo);
  610. DEBUGMSG(DBG_CONFIG, ("RASIR: QueryInformation oid:%X\n", Oid));
  611. switch (Oid)
  612. {
  613. case OID_GEN_MAXIMUM_LOOKAHEAD:
  614. {
  615. DEBUGMSG(DBG_CONFIG, (" OID_GET_MAXIMUM_LOOKAHEAD = %d\n",
  616. IRDA_MAX_DATA_SIZE));
  617. ulInfo = IRDA_MAX_DATA_SIZE;
  618. break;
  619. }
  620. case OID_GEN_MAC_OPTIONS:
  621. {
  622. // Report a bitmask defining optional properties of the driver.
  623. //
  624. // NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA promises that our receive
  625. // buffer is not on a device-specific card.
  626. //
  627. // NDIS_MAC_OPTION_TRANSFERS_NOT_PEND promises we won't return
  628. // NDIS_STATUS_PENDING from our TransferData handler which is true
  629. // since we don't have one.
  630. //
  631. ulInfo = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
  632. | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND;
  633. DEBUGMSG(DBG_CONFIG, (" OID_GEN_MAC_OPTIONS = %d\n",ulInfo));
  634. break;
  635. }
  636. case OID_WAN_MEDIUM_SUBTYPE:
  637. {
  638. // Report the media subtype we support. NDISWAN may use this in
  639. // the future (doesn't now) to provide framing differences for
  640. // different media.
  641. //
  642. DEBUGMSG(DBG_CONFIG, (" OID_WAN_MEDIUM_SUBTYPE\n"));
  643. if (pAdapter->ModemPort)
  644. {
  645. ulInfo = NdisWanMediumSerial;
  646. }
  647. else
  648. {
  649. ulInfo = NdisWanMediumIrda;
  650. }
  651. break;
  652. }
  653. case OID_WAN_CO_GET_INFO:
  654. {
  655. // Report the capabilities of the adapter.
  656. //
  657. DEBUGMSG(DBG_CONFIG, (" OID_WAN_CO_GET_INFO\n"));
  658. pInfo = &pAdapter->Info;
  659. ulInfoLen = sizeof(NDIS_WAN_CO_INFO);
  660. break;
  661. }
  662. case OID_WAN_CO_GET_LINK_INFO:
  663. {
  664. // Report the current state of the link.
  665. //
  666. DEBUGMSG(DBG_CONFIG, (" OID_WAN_CO_GET_LINK_INFO\n"));
  667. if (!pVc)
  668. return NDIS_STATUS_INVALID_DATA;
  669. pInfo = &pVc->LinkInfo;
  670. ulInfoLen = sizeof(NDIS_WAN_CO_GET_LINK_INFO);
  671. break;
  672. }
  673. case OID_WAN_CO_GET_COMP_INFO:
  674. {
  675. // Report the type of compression we provide, which is none.
  676. //
  677. DEBUGMSG(DBG_CONFIG, (" OID_WAN_CO_GET_COMP_INFO\n"));
  678. status = NDIS_STATUS_NOT_SUPPORTED;
  679. ulInfoLen = 0;
  680. break;
  681. }
  682. case OID_WAN_CO_GET_STATS_INFO:
  683. {
  684. // Because L2TP doesn't do compression, NDISWAN will use it's own
  685. // statistics and not query ours.
  686. //
  687. ASSERT( !"OID_WAN_CO_GET_STATS_INFO?" );
  688. status = NDIS_STATUS_NOT_SUPPORTED;
  689. ulInfoLen = 0;
  690. break;
  691. }
  692. case OID_PNP_QUERY_POWER:
  693. DEBUGMSG(DBG_CONFIG, (" OID_PNP_QUERY_POWER\n"));
  694. status = NDIS_STATUS_NOT_SUPPORTED;
  695. ulInfoLen = 0;
  696. break;
  697. case OID_PNP_CAPABILITIES:
  698. DEBUGMSG(DBG_CONFIG, (" OID_PNP_CAP\n"));
  699. status = NDIS_STATUS_NOT_SUPPORTED;
  700. ulInfoLen = 0;
  701. break;
  702. case OID_PNP_SET_POWER:
  703. DEBUGMSG(DBG_CONFIG, (" OID_PNP_SET_POWER\n"));
  704. status = NDIS_STATUS_NOT_SUPPORTED;
  705. ulInfoLen = 0;
  706. break;
  707. default:
  708. {
  709. DEBUGMSG(DBG_CONFIG, ( " Oid $%08x?\n", Oid));
  710. status = NDIS_STATUS_INVALID_OID;
  711. ulInfoLen = 0;
  712. break;
  713. }
  714. }
  715. if (ulInfoLen > InformationBufferLength)
  716. {
  717. // Caller's buffer is too small. Tell him what he needs.
  718. //
  719. *BytesNeeded = ulInfoLen;
  720. status = NDIS_STATUS_INVALID_LENGTH;
  721. }
  722. else
  723. {
  724. // Copy the found result to caller's buffer.
  725. //
  726. if (ulInfoLen > 0)
  727. {
  728. NdisMoveMemory( InformationBuffer, pInfo, ulInfoLen );
  729. }
  730. *BytesNeeded = *BytesWritten = ulInfoLen;
  731. }
  732. return status;
  733. }
  734. NDIS_STATUS
  735. SetInformation(
  736. IN PRASIR_ADAPTER pAdapter,
  737. IN PRASIR_VC pVc,
  738. IN NDIS_OID Oid,
  739. IN PVOID InformationBuffer,
  740. IN ULONG InformationBufferLength,
  741. OUT PULONG BytesRead,
  742. OUT PULONG BytesNeeded)
  743. {
  744. NDIS_STATUS Status;
  745. DEBUGMSG(DBG_CONFIG, ("RASIR: SetInformation oid:%X\n", Oid));
  746. Status = NDIS_STATUS_SUCCESS;
  747. switch (Oid)
  748. {
  749. case OID_WAN_CO_SET_LINK_INFO:
  750. {
  751. // Read new link state settings.
  752. //
  753. DEBUGMSG(DBG_CONFIG, (" OID_WAN_CO_SET_LINK_INFO\n"));
  754. if (InformationBufferLength < sizeof(NDIS_WAN_CO_SET_LINK_INFO))
  755. {
  756. Status = NDIS_STATUS_INVALID_LENGTH;
  757. *BytesRead = 0;
  758. }
  759. else
  760. {
  761. if (!pVc)
  762. return NDIS_STATUS_INVALID_DATA;
  763. ASSERT( sizeof(pVc->LinkInfo)
  764. == sizeof(NDIS_WAN_CO_SET_LINK_INFO) );
  765. NdisMoveMemory(&pVc->LinkInfo, InformationBuffer,
  766. sizeof(pVc->LinkInfo) );
  767. DEBUGMSG(DBG_CONFIG, (" MaxSend %d MaxRecv %d SendAccm %X RecvAccm %X\n",
  768. pVc->LinkInfo.MaxSendFrameSize,
  769. pVc->LinkInfo.MaxRecvFrameSize,
  770. pVc->LinkInfo.SendACCM,
  771. pVc->LinkInfo.RecvACCM));
  772. *BytesRead = sizeof(NDIS_WAN_CO_SET_LINK_INFO);
  773. }
  774. *BytesNeeded = sizeof(NDIS_WAN_CO_SET_LINK_INFO);
  775. }
  776. break;
  777. case OID_WAN_CO_SET_COMP_INFO:
  778. {
  779. // L2TP doesn't provide compression. Neither does IrDA
  780. //
  781. DEBUGMSG(DBG_CONFIG, (" OID_WAN_CO_SET_COMP_INFO\n"));
  782. Status = NDIS_STATUS_NOT_SUPPORTED;
  783. *BytesRead = *BytesNeeded = 0;
  784. break;
  785. }
  786. case OID_PNP_QUERY_POWER:
  787. DEBUGMSG(DBG_CONFIG, (" OID_PNP_QUERY_POWER\n"));
  788. Status = NDIS_STATUS_NOT_SUPPORTED;
  789. *BytesRead = *BytesNeeded = 0;
  790. break;
  791. case OID_PNP_CAPABILITIES:
  792. DEBUGMSG(DBG_CONFIG, (" OID_PNP_CAP\n"));
  793. Status = NDIS_STATUS_NOT_SUPPORTED;
  794. *BytesRead = *BytesNeeded = 0;
  795. break;
  796. case OID_PNP_SET_POWER:
  797. DEBUGMSG(DBG_CONFIG, (" OID_PNP_SET_POWER\n"));
  798. Status = NDIS_STATUS_NOT_SUPPORTED;
  799. *BytesRead = *BytesNeeded = 0;
  800. break;
  801. #if 0
  802. // These OIDs are mandatory according to current doc, but since
  803. // NDISWAN never requests them they are omitted.
  804. //
  805. case OID_GEN_CURRENT_PACKET_FILTER:
  806. case OID_GEN_CURRENT_LOOKAHEAD:
  807. case OID_GEN_PROTOCOL_OPTIONS:
  808. case OID_WAN_PROTOCOL_TYPE:
  809. case OID_WAN_HEADER_FORMAT:
  810. #endif
  811. default:
  812. {
  813. DEBUGMSG(DBG_CONFIG, ("Oid $%08x?\n", Oid ));
  814. Status = NDIS_STATUS_INVALID_OID;
  815. *BytesRead = *BytesNeeded = 0;
  816. break;
  817. }
  818. }
  819. return Status;
  820. }
  821. VOID
  822. ProcessAsyncRxPacket(
  823. PRASIR_VC pVc,
  824. PIRDA_RECVBUF pIrdaRxBuf)
  825. {
  826. PASYNC_BUFFER pReturnRxBuf = NULL;
  827. BOOLEAN EndOfFrame = FALSE;
  828. PASYNC_BUFFER pCurrAsyncBuf;
  829. UINT i;
  830. CHAR Byte;
  831. //DbgMsgBuf(pIrdaRxBuf->Buf, pIrdaRxBuf->BufLen);
  832. for (i = 0; i < pIrdaRxBuf->BufLen; i++)
  833. {
  834. //
  835. // If we are not currently reasembling a frame
  836. // in pCurrAsyncBuf then get a new one
  837. //
  838. if (pVc->pCurrAsyncBuf == NULL)
  839. {
  840. pVc->AsyncFramingState = RX_READY;
  841. if (!(pCurrAsyncBuf = NdisAllocateFromNPagedLookasideList(
  842. &pVc->pAdapter->AsyncBufLList)))
  843. {
  844. DEBUGMSG(DBG_ERROR, ("RASIR: Failed to allocate AsyncBuf\n"));
  845. return;
  846. }
  847. pCurrAsyncBuf->BufLen = 0;
  848. pVc->pCurrAsyncBuf = pCurrAsyncBuf;
  849. }
  850. else
  851. {
  852. pCurrAsyncBuf = pVc->pCurrAsyncBuf;
  853. }
  854. Byte = pIrdaRxBuf->Buf[i];
  855. switch (pVc->AsyncFramingState)
  856. {
  857. case RX_READY:
  858. if (Byte == AF_FLAG_CHAR)
  859. {
  860. pVc->AsyncFramingState = RX_RX;
  861. }
  862. break;
  863. case RX_RX:
  864. switch (Byte)
  865. {
  866. case AF_FLAG_CHAR:
  867. // We have a complete frame, put it on the completed
  868. // list
  869. pVc->AsyncFramingState = RX_READY;
  870. if (pCurrAsyncBuf->BufLen > 2)
  871. {
  872. // remove FCS, IrDA is reliable so I don't look at it
  873. pCurrAsyncBuf->BufLen -= 2;
  874. NdisInterlockedInsertTailList(
  875. &pVc->CompletedAsyncBufList,
  876. &pCurrAsyncBuf->Linkage,
  877. &pVc->pAdapter->SpinLock);
  878. DEBUGMSG(DBG_RECV, ("RASIR: Complete async frame %d, %d of %d\n",
  879. pVc->pCurrAsyncBuf->BufLen, i, pIrdaRxBuf->BufLen));
  880. pVc->pCurrAsyncBuf = NULL;
  881. }
  882. else
  883. {
  884. // frame too small, we'll just ignore it
  885. pCurrAsyncBuf->BufLen = 0;
  886. DEBUGMSG(DBG_ERROR, ("RASIR: Async failure 1\n"));
  887. }
  888. break;
  889. case AF_ESC_CHAR:
  890. pVc->AsyncFramingState = RX_ESC;
  891. break;
  892. default:
  893. if (pCurrAsyncBuf->BufLen >= ASYNC_BUF_SIZE)
  894. {
  895. pCurrAsyncBuf->BufLen = 0;
  896. pVc->AsyncFramingState = RX_READY;
  897. DEBUGMSG(DBG_ERROR, ("RASIR: Async buffer overflow\n"));
  898. }
  899. else
  900. {
  901. pCurrAsyncBuf->Buf[pCurrAsyncBuf->BufLen] = Byte;
  902. pCurrAsyncBuf->BufLen += 1;
  903. }
  904. }
  905. break;
  906. case RX_ESC:
  907. if (pCurrAsyncBuf->BufLen >= ASYNC_BUF_SIZE)
  908. {
  909. pCurrAsyncBuf->BufLen = 0;
  910. pVc->AsyncFramingState = RX_READY;
  911. DEBUGMSG(DBG_ERROR, ("RASIR: Async failure 2\n"));
  912. }
  913. else
  914. {
  915. pCurrAsyncBuf->Buf[pCurrAsyncBuf->BufLen] = (Byte ^= AF_COMP_BIT);
  916. pCurrAsyncBuf->BufLen += 1;
  917. pVc->AsyncFramingState = RX_RX;
  918. break;
  919. }
  920. }
  921. }
  922. }
  923. VOID
  924. IndicateReceive(
  925. PRASIR_VC pVc,
  926. PIRDA_RECVBUF pRecvBuf,
  927. PASYNC_BUFFER pAsyncBuf,
  928. BOOLEAN LastBuf)
  929. {
  930. PNDIS_PACKET pNdisPacket;
  931. PNDIS_BUFFER pNdisBuf;
  932. NDIS_STATUS Status;
  933. KIRQL OldIrql;
  934. PVOID pRecvOrAsyncBuf = NULL;
  935. int Len;
  936. REFADD(&pVc->RefCnt, 'VCER');
  937. if (pVc->AsyncFraming)
  938. {
  939. ASSERT(pAsyncBuf && !pRecvBuf);
  940. pRecvOrAsyncBuf = pAsyncBuf;
  941. Len = pAsyncBuf->BufLen;
  942. }
  943. else
  944. {
  945. ASSERT(pRecvBuf && !pAsyncBuf);
  946. pRecvOrAsyncBuf = pRecvBuf;
  947. Len = pRecvBuf->BufLen;
  948. }
  949. if (!(pVc->Flags & VCF_OPEN))
  950. {
  951. DEBUGMSG(DBG_ERROR, ("RASIR: VC not open yet, dropping packet\n"));
  952. goto error1;
  953. }
  954. NdisAllocatePacket(&Status, &pNdisPacket, pVc->RxPacketPool);
  955. if (Status != NDIS_STATUS_SUCCESS)
  956. {
  957. DEBUGMSG(DBG_ERROR, ("RASIR: NdisAllocatePacket failed, %X\n",
  958. Status));
  959. goto error1;
  960. }
  961. if (pVc->AsyncFraming)
  962. {
  963. NdisAllocateBuffer(&Status, &pNdisBuf, pVc->RxBufferPool,
  964. pAsyncBuf->Buf, pAsyncBuf->BufLen);
  965. }
  966. else
  967. {
  968. NdisAllocateBuffer(&Status, &pNdisBuf, pVc->RxBufferPool,
  969. pRecvBuf->Buf, pRecvBuf->BufLen);
  970. }
  971. if (Status != NDIS_STATUS_SUCCESS)
  972. {
  973. DEBUGMSG(DBG_ERROR, ("RASIR: NdisAllocateBuffer failed, %X\n",
  974. Status));
  975. goto error2;
  976. }
  977. NdisChainBufferAtFront(pNdisPacket, pNdisBuf);
  978. *((PRASIR_VC *) &pNdisPacket->MiniportReserved[0]) = pVc;
  979. *((PVOID *) &pNdisPacket->MiniportReserved[sizeof(PUCHAR)]) = pRecvOrAsyncBuf;
  980. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  981. if (LastBuf)
  982. {
  983. NDIS_SET_PACKET_STATUS(pNdisPacket, NDIS_STATUS_RESOURCES);
  984. DEBUGMSG(DBG_RECV, ("RASIR: Irtdi out of buffers\n"));
  985. }
  986. else
  987. {
  988. NDIS_SET_PACKET_STATUS(pNdisPacket, NDIS_STATUS_SUCCESS);
  989. }
  990. Status = NDIS_GET_PACKET_STATUS(pNdisPacket);
  991. DEBUGMSG(DBG_RECV, ("RASIR: ->NdisMCoIndicateReceive %d\n", Len));
  992. NdisMCoIndicateReceivePacket(pVc->NdisVcHandle, &pNdisPacket, 1);
  993. NdisMCoReceiveComplete(pVc->pAdapter->MiniportAdapterHandle);
  994. KeLowerIrql(OldIrql);
  995. if (Status == NDIS_STATUS_SUCCESS) {
  996. //
  997. // the packets will be returned later
  998. //
  999. return;
  1000. }
  1001. NdisUnchainBufferAtFront(pNdisPacket, &pNdisBuf);
  1002. NdisFreeBuffer(pNdisBuf);
  1003. error2:
  1004. NdisFreePacket(pNdisPacket);
  1005. error1:
  1006. DEBUGMSG(DBG_RECV, ("RASIR: RecvIndication completed synchronously for %X\n",
  1007. pRecvOrAsyncBuf));
  1008. RasIrReceiveComplete(pVc, pRecvOrAsyncBuf);
  1009. REFDEL(&pVc->RefCnt, 'VCER');
  1010. }
  1011. VOID
  1012. IrdaReceiveIndication(
  1013. PVOID ConnectionContext,
  1014. PIRDA_RECVBUF pRecvBuf,
  1015. BOOLEAN LastBuf)
  1016. {
  1017. PRASIR_VC pVc = ConnectionContext;
  1018. PASYNC_BUFFER pAsyncRxBuf;
  1019. DEBUGMSG(DBG_RECV, ("RASIR: IrdaReceiveIndication %X, %d bytes\n",
  1020. pRecvBuf, pRecvBuf->BufLen));
  1021. if (!pVc)
  1022. {
  1023. DEBUGMSG(DBG_ERROR, ("RASIR: IrdaReceiveIndication NULL vc\n"));
  1024. ASSERT(0);
  1025. return;
  1026. }
  1027. GOODVC(pVc);
  1028. GOODADAPTER(pVc->pAdapter);
  1029. if (pVc->IrModemCall && pVc->ModemState < MS_ONLINE)
  1030. {
  1031. ProcessOfflineRxBuf(pVc, pRecvBuf);
  1032. IrdaReceiveComplete(pVc->IrdaConnContext, pRecvBuf);
  1033. return;
  1034. }
  1035. if (pVc->AsyncFraming)
  1036. {
  1037. ProcessAsyncRxPacket(pVc, pRecvBuf);
  1038. // We are done with pRecvBuf. The async framing has
  1039. // been removed and the data is now contained in a buffer
  1040. // on the CompletedAsyncBufList or if not a full frame
  1041. // then in pCurrAsyncBuf
  1042. IrdaReceiveComplete(pVc->IrdaConnContext, pRecvBuf);
  1043. while ((pAsyncRxBuf = (PASYNC_BUFFER) NdisInterlockedRemoveHeadList(
  1044. &pVc->CompletedAsyncBufList,
  1045. &pVc->pAdapter->SpinLock)) != NULL)
  1046. {
  1047. IndicateReceive(pVc, NULL, pAsyncRxBuf, LastBuf);
  1048. }
  1049. }
  1050. else
  1051. {
  1052. IndicateReceive(pVc, pRecvBuf, NULL, LastBuf);
  1053. }
  1054. return;
  1055. }
  1056. VOID
  1057. IrdaSendComplete(
  1058. PVOID ConnectContext,
  1059. PVOID SendContext,
  1060. NTSTATUS Status)
  1061. {
  1062. PRASIR_VC pVc = ConnectContext;
  1063. PNDIS_PACKET pNdisPacket = (PNDIS_PACKET) SendContext;
  1064. DEBUGMSG(DBG_SEND, ("RASIR: IrdaSendComplete vc:%X, Packet %X\n", pVc, SendContext));
  1065. GOODVC(pVc);
  1066. if (SendContext == RASIR_INTERNAL_SEND)
  1067. {
  1068. ASSERT(pVc->pOfflineNdisBuf);
  1069. NdisFreeBuffer(pVc->pOfflineNdisBuf);
  1070. pVc->pOfflineNdisBuf = NULL;
  1071. goto EXIT;
  1072. }
  1073. if (pVc->AsyncFraming)
  1074. {
  1075. PASYNC_BUFFER pAsyncBuf;
  1076. pAsyncBuf = *((PASYNC_BUFFER *) &pNdisPacket->MiniportReserved[0]);
  1077. if (pAsyncBuf)
  1078. {
  1079. if (pAsyncBuf->pNdisBuf)
  1080. {
  1081. NdisFreeBuffer(pAsyncBuf->pNdisBuf);
  1082. }
  1083. NdisFreeToNPagedLookasideList(&pVc->pAdapter->AsyncBufLList,
  1084. pAsyncBuf);
  1085. }
  1086. }
  1087. NdisMCoSendComplete(Status, pVc->NdisVcHandle, pNdisPacket);
  1088. NdisAcquireSpinLock(&pVc->pAdapter->SpinLock);
  1089. pVc->OutstandingSends -= 1; // do interlockedDec dork
  1090. NdisReleaseSpinLock(&pVc->pAdapter->SpinLock);
  1091. if ((pVc->Flags & VCF_CLOSE_PEND) && (pVc->OutstandingSends == 0))
  1092. {
  1093. DEBUGMSG(DBG_CONNECT, ("RASIR: Outstanding send to 0, CompleteClose\n"));
  1094. CompleteClose(pVc);
  1095. }
  1096. EXIT:
  1097. REFDEL(&pVc->RefCnt, 'DNES');
  1098. }
  1099. NDIS_STATUS
  1100. ScheduleWork(
  1101. IN PRASIR_ADAPTER pAdapter,
  1102. IN NDIS_PROC pProc,
  1103. IN PVOID pContext )
  1104. // Schedules a PASSIVE IRQL callback to routine 'pProc' which will be
  1105. // passed 'pContext'. 'PAdapter' is the adapter control block from which
  1106. // the work item is allocated.
  1107. //
  1108. // Returns NDIS_STATUS_SUCCESS or an error code.
  1109. //
  1110. {
  1111. NDIS_STATUS status;
  1112. NDIS_WORK_ITEM* pWork;
  1113. pWork = NdisAllocateFromNPagedLookasideList(&pAdapter->WorkItemsLList);
  1114. if (!pWork)
  1115. {
  1116. ASSERT( !"Alloc work?" );
  1117. return NDIS_STATUS_RESOURCES;
  1118. }
  1119. NdisInitializeWorkItem( pWork, pProc, pContext );
  1120. status = NdisScheduleWorkItem( pWork );
  1121. if (status != NDIS_STATUS_SUCCESS)
  1122. {
  1123. ASSERT( !"SchedWork?" );
  1124. NdisFreeToNPagedLookasideList(&pAdapter->WorkItemsLList, pWork);
  1125. }
  1126. return status;
  1127. }
  1128. #if DBG
  1129. NTSTATUS
  1130. DbgDispatch(
  1131. PDEVICE_OBJECT pDeviceObject,
  1132. PIRP pIrp)
  1133. {
  1134. PIO_STACK_LOCATION pIrpSp;
  1135. pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  1136. if (pIrpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL)
  1137. {
  1138. pIrp->IoStatus.Status = STATUS_SUCCESS;
  1139. pIrp->IoStatus.Information = 0;
  1140. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  1141. return STATUS_SUCCESS;
  1142. }
  1143. ASSERT(pIrpSp->MajorFunction != IRP_MJ_INTERNAL_DEVICE_CONTROL);
  1144. switch(pIrpSp->Parameters.DeviceIoControl.IoControlCode)
  1145. {
  1146. case IOCTL_IRDA_GET_DBG_MSGS:
  1147. {
  1148. NTSTATUS Status;
  1149. if ((Status = DbgMsgIrp(pIrp, pIrpSp)) == STATUS_PENDING)
  1150. {
  1151. return STATUS_PENDING;
  1152. }
  1153. break;
  1154. }
  1155. case IOCTL_IRDA_GET_DBG_SETTINGS:
  1156. {
  1157. UINT *Settings = pIrp->AssociatedIrp.SystemBuffer;
  1158. Settings[0] = DbgSettings;
  1159. Settings[1] = DbgOutput;
  1160. pIrp->IoStatus.Information = sizeof(UINT)*2;
  1161. pIrp->IoStatus.Status = STATUS_SUCCESS;
  1162. break;
  1163. }
  1164. case IOCTL_IRDA_SET_DBG_SETTINGS:
  1165. {
  1166. UINT *Settings = pIrp->AssociatedIrp.SystemBuffer;
  1167. DbgSettings = Settings[0];
  1168. DbgOutput = Settings[1];
  1169. pIrp->IoStatus.Information = 0;
  1170. pIrp->IoStatus.Status = STATUS_SUCCESS;
  1171. break;
  1172. }
  1173. default:
  1174. pIrp->IoStatus.Information = 0;
  1175. pIrp->IoStatus.Status = STATUS_SUCCESS;
  1176. }
  1177. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  1178. return STATUS_SUCCESS;
  1179. }
  1180. #endif