Source code of Windows XP (NT5)
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.

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