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.

1077 lines
32 KiB

  1. /*****************************************************************************
  2. *
  3. * Copyright (c) 1996-1999 Microsoft Corporation
  4. *
  5. * @doc
  6. * @module request.c | IrSIR NDIS Miniport Driver
  7. * @comm
  8. *
  9. *-----------------------------------------------------------------------------
  10. *
  11. * Author: Scott Holden (sholden)
  12. *
  13. * Date: 10/10/1996 (created)
  14. *
  15. * Contents: Query and set information handlers.
  16. *
  17. *****************************************************************************/
  18. #include "irsir.h"
  19. VOID
  20. ClearMediaBusyCallback(
  21. PIR_WORK_ITEM pWorkItem
  22. );
  23. VOID
  24. QueryMediaBusyCallback(
  25. PIR_WORK_ITEM pWorkItem
  26. );
  27. VOID
  28. InitIrDeviceCallback(
  29. PIR_WORK_ITEM pWorkItem
  30. );
  31. #pragma alloc_text(PAGE, ClearMediaBusyCallback)
  32. #pragma alloc_text(PAGE, QueryMediaBusyCallback)
  33. #pragma alloc_text(PAGE, InitIrDeviceCallback)
  34. //
  35. // These are the OIDs we support for querying.
  36. //
  37. UINT supportedOIDs[] =
  38. {
  39. //
  40. // General required OIDs.
  41. //
  42. OID_GEN_SUPPORTED_LIST,
  43. OID_GEN_HARDWARE_STATUS,
  44. OID_GEN_MEDIA_SUPPORTED,
  45. OID_GEN_MEDIA_IN_USE,
  46. OID_GEN_MAXIMUM_LOOKAHEAD,
  47. OID_GEN_MAXIMUM_FRAME_SIZE,
  48. OID_GEN_LINK_SPEED,
  49. OID_GEN_TRANSMIT_BUFFER_SPACE,
  50. OID_GEN_RECEIVE_BUFFER_SPACE,
  51. OID_GEN_TRANSMIT_BLOCK_SIZE,
  52. OID_GEN_RECEIVE_BLOCK_SIZE,
  53. OID_GEN_VENDOR_ID,
  54. OID_GEN_VENDOR_DESCRIPTION,
  55. OID_GEN_CURRENT_PACKET_FILTER,
  56. OID_GEN_CURRENT_LOOKAHEAD,
  57. OID_GEN_DRIVER_VERSION,
  58. OID_GEN_MAXIMUM_TOTAL_SIZE,
  59. OID_GEN_PROTOCOL_OPTIONS,
  60. OID_GEN_MAC_OPTIONS,
  61. OID_GEN_MEDIA_CONNECT_STATUS,
  62. OID_GEN_MAXIMUM_SEND_PACKETS,
  63. OID_GEN_VENDOR_DRIVER_VERSION,
  64. //
  65. // Required statistical OIDs.
  66. //
  67. OID_GEN_XMIT_OK,
  68. OID_GEN_RCV_OK,
  69. OID_GEN_XMIT_ERROR,
  70. OID_GEN_RCV_ERROR,
  71. OID_GEN_RCV_NO_BUFFER,
  72. //
  73. // Infrared-specific OIDs.
  74. //
  75. OID_IRDA_RECEIVING,
  76. OID_IRDA_TURNAROUND_TIME,
  77. OID_IRDA_SUPPORTED_SPEEDS,
  78. OID_IRDA_LINK_SPEED,
  79. OID_IRDA_MEDIA_BUSY,
  80. OID_IRDA_EXTRA_RCV_BOFS
  81. //
  82. // Unsupported Infrared-specific OIDs.
  83. //
  84. // OID_IRDA_RATE_SNIFF,
  85. // OID_IRDA_UNICAST_LIST,
  86. // OID_IRDA_MAX_UNICAST_LIST_SIZE
  87. //
  88. #if 1
  89. ,OID_PNP_CAPABILITIES,
  90. OID_PNP_SET_POWER,
  91. OID_PNP_QUERY_POWER,
  92. OID_PNP_ENABLE_WAKE_UP
  93. #endif
  94. };
  95. VOID
  96. ClearMediaBusyCallback(PIR_WORK_ITEM pWorkItem)
  97. {
  98. PIR_DEVICE pThisDev = pWorkItem->pIrDevice;
  99. NDIS_STATUS status;
  100. BOOLEAN fSwitchSuccessful;
  101. NDIS_HANDLE hSwitchToMiniport;
  102. SERIALPERF_STATS PerfStats;
  103. //DBGTIME("CLEAR_MEDIA_BUSY");
  104. DEBUGMSG(DBG_STAT, (" primPassive = PASSIVE_CLEAR_MEDIA_BUSY\n"));
  105. status = (NDIS_STATUS) SerialClearStats(pThisDev->pSerialDevObj);
  106. if (status != NDIS_STATUS_SUCCESS)
  107. {
  108. DEBUGMSG(DBG_ERROR, (" SerialClearStats failed = 0x%.8x\n", status));
  109. }
  110. {
  111. NdisMSetInformationComplete(pThisDev->hNdisAdapter,
  112. (NDIS_STATUS)status);
  113. }
  114. FreeWorkItem(pWorkItem);
  115. return;
  116. }
  117. VOID
  118. QueryMediaBusyCallback(PIR_WORK_ITEM pWorkItem)
  119. {
  120. PIR_DEVICE pThisDev = pWorkItem->pIrDevice;
  121. NDIS_STATUS status;
  122. BOOLEAN fSwitchSuccessful;
  123. NDIS_HANDLE hSwitchToMiniport;
  124. SERIALPERF_STATS PerfStats;
  125. ASSERT(pWorkItem->InfoBuf != NULL);
  126. ASSERT(pWorkItem->InfoBufLen >= sizeof(UINT));
  127. if (pThisDev->pSerialDevObj)
  128. {
  129. status = (NDIS_STATUS) SerialGetStats(pThisDev->pSerialDevObj, &PerfStats);
  130. }
  131. else
  132. {
  133. PerfStats.ReceivedCount = 1; // Fake media busy
  134. status = NDIS_STATUS_SUCCESS;
  135. }
  136. if (status == NDIS_STATUS_SUCCESS)
  137. {
  138. if (PerfStats.ReceivedCount > 0 ||
  139. PerfStats.FrameErrorCount > 0 ||
  140. PerfStats.SerialOverrunErrorCount > 0 ||
  141. PerfStats.BufferOverrunErrorCount > 0 ||
  142. PerfStats.ParityErrorCount > 0)
  143. {
  144. DBGTIME("QUERY_MEDIA_BUSY:TRUE");
  145. pThisDev->fMediaBusy = TRUE;
  146. }
  147. else
  148. {
  149. DBGTIME("QUERY_MEDIA_BUSY:FALSE");
  150. }
  151. }
  152. else
  153. {
  154. DEBUGMSG(DBG_ERROR, (" SerialGetStats failed = 0x%.8x\n", status));
  155. }
  156. *(UINT *)pWorkItem->InfoBuf = (UINT)pThisDev->fMediaBusy;
  157. pWorkItem->InfoBufLen = sizeof(UINT);
  158. {
  159. NdisMQueryInformationComplete(pThisDev->hNdisAdapter,
  160. (NDIS_STATUS)status);
  161. }
  162. FreeWorkItem(pWorkItem);
  163. return;
  164. }
  165. VOID
  166. InitIrDeviceCallback(PIR_WORK_ITEM pWorkItem)
  167. {
  168. PIR_DEVICE pThisDev = pWorkItem->pIrDevice;
  169. NDIS_STATUS status = NDIS_STATUS_SUCCESS;
  170. BOOLEAN fSwitchSuccessful;
  171. NDIS_HANDLE hSwitchToMiniport;
  172. DEBUGMSG(DBG_FUNC, ("+InitIrDeviceCallback\n"));
  173. (void)ResetIrDevice(pThisDev);
  174. {
  175. NdisMQueryInformationComplete(pThisDev->hNdisAdapter,
  176. (NDIS_STATUS)status);
  177. }
  178. FreeWorkItem(pWorkItem);
  179. DEBUGMSG(DBG_FUNC, ("-InitIrDeviceCallback\n"));
  180. return;
  181. }
  182. /*****************************************************************************
  183. *
  184. * Function: IrsirQueryInformation
  185. *
  186. * Synopsis: Queries the capabilities and status of the miniport driver.
  187. *
  188. * Arguments: MiniportAdapterContext - miniport context area (PIR_DEVICE)
  189. * Oid - system defined OID_Xxx
  190. * InformationBuffer - where to return Oid specific info
  191. * InformationBufferLength - specifies size of InformationBuffer
  192. * BytesWritten - bytes written to InformationBuffer
  193. * BytesNeeded - addition bytes required if
  194. * InformationBufferLength is less than
  195. * what the Oid requires to write
  196. *
  197. * Returns: NDIS_STATUS_SUCCESS - success
  198. * NDIS_STATUS_PENDING - will complete asynchronously and
  199. * call NdisMQueryInformationComplete
  200. * NDIS_STATUS_INVALID_OID - don't recognize the Oid
  201. * NDIS_STATUS_INVALID_LENGTH- InformationBufferLength does not
  202. * match length for the Oid
  203. * NDIS_STATUS_NOT_ACCEPTED - failure
  204. * NDIS_STATUS_NOT_SUPPORTED - do not support an optional Oid
  205. * NDIS_STATUS_RESOURCES - failed allocation of resources
  206. *
  207. * Algorithm:
  208. *
  209. * History: dd-mm-yyyy Author Comment
  210. * 10/1/1996 sholden author
  211. *
  212. * Notes:
  213. * Supported OIDs:
  214. * OID_GEN_MAXIMUM_LOOKAHEAD
  215. * - indicate the number of bytes of look ahead data the NIC can
  216. * provide
  217. * OID_GEN_MAC_OPTIONS
  218. * - indicate which NDIS_MAC_OPTION_Xxx the NIC supports
  219. * OID_GEN_MAXIMUM_SEND_PACKETS
  220. * OID_IRDA_RECEIVING
  221. * OID_IRDA_SUPPORTED_SPEEDS
  222. * OID_IRDA_LINK_SPEED
  223. * OID_IRDA_MEDIA_BUSY
  224. * OID_IRDA_TURNAROUND_TIME
  225. * OID_IRDA_EXTRA_RCV_BOFS
  226. *
  227. * Unsupported OIDs:
  228. * OID_IRDA_UNICAST_LIST
  229. * OID_IRDA_MAX_UNICAST_LIST_SIZE
  230. * OID_IRDA_RATE_SNIFF
  231. *
  232. *****************************************************************************/
  233. NDIS_STATUS
  234. IrsirQueryInformation(
  235. IN NDIS_HANDLE MiniportAdapterContext,
  236. IN NDIS_OID Oid,
  237. IN PVOID InformationBuffer,
  238. IN ULONG InformationBufferLength,
  239. OUT PULONG BytesWritten,
  240. OUT PULONG BytesNeeded
  241. )
  242. {
  243. PIR_DEVICE pThisDev;
  244. NDIS_STATUS status;
  245. UINT speeds;
  246. UINT i;
  247. UINT infoSizeNeeded;
  248. UINT *infoPtr;
  249. PIR_WORK_ITEM pWorkItem = NULL;
  250. ULONG OidCategory = Oid & 0xFF000000;
  251. static char vendorDesc[] = "Serial Infrared (COM) Port";
  252. DEBUGMSG(DBG_FUNC, ("+IrsirQueryInformation\n"));
  253. pThisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
  254. status = NDIS_STATUS_SUCCESS;
  255. //
  256. // Figure out buffer size needed.
  257. // Most OIDs just return a single UINT, but there are exceptions.
  258. //
  259. switch (Oid)
  260. {
  261. case OID_GEN_SUPPORTED_LIST:
  262. infoSizeNeeded = sizeof(supportedOIDs);
  263. break;
  264. case OID_GEN_DRIVER_VERSION:
  265. infoSizeNeeded = sizeof(USHORT);
  266. break;
  267. case OID_GEN_VENDOR_DESCRIPTION:
  268. infoSizeNeeded = sizeof(vendorDesc);
  269. break;
  270. case OID_IRDA_SUPPORTED_SPEEDS:
  271. speeds = pThisDev->dongleCaps.supportedSpeedsMask &
  272. ALL_SLOW_IRDA_SPEEDS;
  273. for (infoSizeNeeded = 0; speeds; infoSizeNeeded += sizeof(UINT))
  274. {
  275. //
  276. // This instruction clears the lowest set bit in speeds.
  277. // Trust me.
  278. //
  279. speeds &= (speeds - 1);
  280. }
  281. break;
  282. default:
  283. infoSizeNeeded = sizeof(UINT);
  284. break;
  285. }
  286. //
  287. // If the protocol provided a large enough buffer, we can go ahead
  288. // and complete the query.
  289. //
  290. if (InformationBufferLength >= infoSizeNeeded)
  291. {
  292. //
  293. // Set default results.
  294. //
  295. *BytesWritten = infoSizeNeeded;
  296. *BytesNeeded = 0;
  297. switch (Oid)
  298. {
  299. //
  300. // Generic OIDs.
  301. //
  302. case OID_GEN_SUPPORTED_LIST:
  303. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_SUPPORTED_LIST)\n"));
  304. NdisMoveMemory(
  305. InformationBuffer,
  306. (PVOID)supportedOIDs,
  307. sizeof(supportedOIDs)
  308. );
  309. break;
  310. case OID_GEN_HARDWARE_STATUS:
  311. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_HARDWARE_STATUS)\n"));
  312. //
  313. // If we can be called with a context, then we are
  314. // initialized and ready.
  315. //
  316. *(UINT *)InformationBuffer = NdisHardwareStatusReady;
  317. break;
  318. case OID_GEN_MEDIA_SUPPORTED:
  319. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MEDIA_SUPPORTED)\n"));
  320. *(UINT *)InformationBuffer = NdisMediumIrda;
  321. break;
  322. case OID_GEN_MEDIA_IN_USE:
  323. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MEDIA_IN_USE)\n"));
  324. *(UINT *)InformationBuffer = NdisMediumIrda;
  325. break;
  326. case OID_GEN_MAXIMUM_LOOKAHEAD:
  327. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)\n"));
  328. *(UINT *)InformationBuffer = 256;
  329. break;
  330. case OID_GEN_MAXIMUM_FRAME_SIZE:
  331. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAXIMUM_FRAME_SIZE)\n"));
  332. *(UINT *)InformationBuffer = MAX_NDIS_DATA_SIZE;
  333. break;
  334. case OID_GEN_LINK_SPEED:
  335. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_LINK_SPEED)\n"));
  336. //
  337. // Return MAXIMUM POSSIBLE speed for this device in units
  338. // of 100 bits/sec.
  339. //
  340. *(UINT *)InformationBuffer = 115200/100;
  341. break;
  342. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  343. case OID_GEN_RECEIVE_BUFFER_SPACE:
  344. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  345. case OID_GEN_RECEIVE_BLOCK_SIZE:
  346. *(UINT *)InformationBuffer = MAX_I_DATA_SIZE;
  347. break;
  348. case OID_GEN_VENDOR_ID:
  349. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_VENDOR_ID)\n"));
  350. *(UINT *)InformationBuffer = 0x00ffffff;
  351. break;
  352. case OID_GEN_VENDOR_DESCRIPTION:
  353. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_VENDOR_DESCRIPTION)\n"));
  354. NdisMoveMemory(
  355. InformationBuffer,
  356. (PVOID)vendorDesc,
  357. sizeof(vendorDesc)
  358. );
  359. break;
  360. case OID_GEN_CURRENT_PACKET_FILTER:
  361. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_CURRENT_PACKET_FILTER)\n"));
  362. *(UINT *)InformationBuffer = NDIS_PACKET_TYPE_PROMISCUOUS;
  363. break;
  364. case OID_GEN_CURRENT_LOOKAHEAD:
  365. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_CURRENT_LOOKAHEAD)\n"));
  366. *(UINT *)InformationBuffer = 256;
  367. break;
  368. case OID_GEN_DRIVER_VERSION:
  369. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_DRIVER_VERSION)\n"));
  370. *(USHORT *)InformationBuffer = ((IRSIR_MAJOR_VERSION << 8) |
  371. IRSIR_MINOR_VERSION);
  372. break;
  373. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  374. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAXIMUM_TOTAL_SIZE)\n"));
  375. *(UINT *)InformationBuffer = MAX_NDIS_DATA_SIZE;
  376. break;
  377. case OID_GEN_PROTOCOL_OPTIONS:
  378. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_PROTOCOL_OPTIONS)\n"));
  379. DEBUGMSG(DBG_ERROR, ("This is a set-only OID\n"));
  380. *BytesWritten = 0;
  381. status = NDIS_STATUS_NOT_SUPPORTED;
  382. break;
  383. case OID_GEN_MAC_OPTIONS:
  384. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAC_OPTIONS)\n"));
  385. *(UINT *)InformationBuffer =
  386. NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
  387. NDIS_MAC_OPTION_TRANSFERS_NOT_PEND;
  388. break;
  389. case OID_GEN_MEDIA_CONNECT_STATUS:
  390. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MEDIA_CONNECT_STATUS)\n"));
  391. //
  392. // Since we are not physically connected to a LAN, we
  393. // cannot determine whether or not we are connected;
  394. // so always indicate that we are.
  395. //
  396. *(UINT *)InformationBuffer = NdisMediaStateConnected;
  397. break;
  398. case OID_GEN_MAXIMUM_SEND_PACKETS:
  399. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_MAXIMUM_SEND_PACKETS)\n"));
  400. *(UINT *)InformationBuffer = 16;
  401. break;
  402. case OID_GEN_VENDOR_DRIVER_VERSION:
  403. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_VENDOR_DRIVER_VERSION)\n"));
  404. *(UINT *)InformationBuffer =
  405. ((IRSIR_MAJOR_VERSION << 16) |
  406. IRSIR_MINOR_VERSION);
  407. break;
  408. //
  409. // Required statistical OIDs.
  410. //
  411. case OID_GEN_XMIT_OK:
  412. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_XMIT_OK)\n"));
  413. *(UINT *)InformationBuffer =
  414. (UINT)pThisDev->packetsSent;
  415. break;
  416. case OID_GEN_RCV_OK:
  417. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_RCV_OK)\n"));
  418. *(UINT *)InformationBuffer =
  419. (UINT)pThisDev->packetsReceived;
  420. break;
  421. case OID_GEN_XMIT_ERROR:
  422. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_XMIT_ERROR)\n"));
  423. *(UINT *)InformationBuffer =
  424. (UINT)pThisDev->packetsSentDropped;
  425. break;
  426. case OID_GEN_RCV_ERROR:
  427. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_RCV_ERROR)\n"));
  428. *(UINT *)InformationBuffer =
  429. (UINT)pThisDev->packetsReceivedDropped;
  430. break;
  431. case OID_GEN_RCV_NO_BUFFER:
  432. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_GEN_RCV_NO_BUFFER)\n"));
  433. *(UINT *)InformationBuffer =
  434. (UINT)pThisDev->packetsReceivedOverflow;
  435. break;
  436. //
  437. // Infrared OIDs.
  438. //
  439. case OID_IRDA_RECEIVING:
  440. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_RECEIVING)\n"));
  441. *(UINT *)InformationBuffer = (UINT)pThisDev->fReceiving;
  442. break;
  443. case OID_IRDA_TURNAROUND_TIME:
  444. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_TURNAROUND_TIME)\n"));
  445. //
  446. // Indicate that the tranceiver requires at least 5000us
  447. // (5 millisec) to recuperate after a send.
  448. //
  449. *(UINT *)InformationBuffer =
  450. pThisDev->dongleCaps.turnAroundTime_usec;
  451. break;
  452. case OID_IRDA_SUPPORTED_SPEEDS:
  453. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_SUPPORTED_SPEEDS)\n"));
  454. if (!pThisDev->pSerialDevObj)
  455. {
  456. (void)pThisDev->dongle.QueryCaps(&pThisDev->dongleCaps);
  457. }
  458. speeds = pThisDev->dongleCaps.supportedSpeedsMask &
  459. pThisDev->AllowedSpeedsMask &
  460. ALL_SLOW_IRDA_SPEEDS;
  461. *BytesWritten = 0;
  462. for (i = 0, infoPtr = (PUINT)InformationBuffer;
  463. (i < NUM_BAUDRATES) &&
  464. speeds &&
  465. (InformationBufferLength >= sizeof(UINT));
  466. i++)
  467. {
  468. if (supportedBaudRateTable[i].ndisCode & speeds)
  469. {
  470. *infoPtr++ = supportedBaudRateTable[i].bitsPerSec;
  471. InformationBufferLength -= sizeof(UINT);
  472. *BytesWritten += sizeof(UINT);
  473. speeds &= ~supportedBaudRateTable[i].ndisCode;
  474. DEBUGMSG(DBG_OUT, (" - supporting speed %d bps\n", supportedBaudRateTable[i].bitsPerSec));
  475. }
  476. }
  477. if (speeds)
  478. {
  479. //
  480. // This shouldn't happen, since we checked the
  481. // InformationBuffer size earlier.
  482. //
  483. DEBUGMSG(DBG_ERROR, ("Something's wrong; previous check for buf size failed somehow\n"));
  484. for (*BytesNeeded = 0; speeds; *BytesNeeded += sizeof(UINT))
  485. {
  486. //
  487. // This instruction clears the lowest set bit in speeds.
  488. // Trust me.
  489. //
  490. speeds &= (speeds - 1);
  491. }
  492. status = NDIS_STATUS_INVALID_LENGTH;
  493. }
  494. else
  495. {
  496. status = NDIS_STATUS_SUCCESS;
  497. }
  498. break;
  499. case OID_IRDA_LINK_SPEED:
  500. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_LINK_SPEED)\n"));
  501. if (pThisDev->linkSpeedInfo)
  502. {
  503. *(UINT *)InformationBuffer =
  504. pThisDev->linkSpeedInfo->bitsPerSec;
  505. }
  506. else {
  507. *(UINT *)InformationBuffer = DEFAULT_BAUD_RATE;
  508. }
  509. break;
  510. case OID_IRDA_MEDIA_BUSY:
  511. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_MEDIA_BUSY)\n"));
  512. //
  513. // If any data has been received, fMediaBusy = TRUE. However,
  514. // even if fMediaBusy = FALSE, the media may be busy. We need
  515. // to query the serial device object's performance statistics
  516. // to see if there are any overrun or framing errors.
  517. //
  518. //
  519. // NOTE: The serial device object's performance stats are
  520. // cleared when the protocol set fMediaBusy to
  521. // FALSE.
  522. //
  523. *(UINT *)InformationBuffer = pThisDev->fMediaBusy;
  524. if (pThisDev->fMediaBusy == FALSE)
  525. {
  526. if (ScheduleWorkItem(PASSIVE_QUERY_MEDIA_BUSY, pThisDev,
  527. QueryMediaBusyCallback, InformationBuffer,
  528. InformationBufferLength) != NDIS_STATUS_SUCCESS)
  529. {
  530. status = NDIS_STATUS_SUCCESS;
  531. }
  532. else
  533. {
  534. status = NDIS_STATUS_PENDING;
  535. }
  536. }
  537. else
  538. {
  539. *(UINT *)InformationBuffer = (UINT)pThisDev->fMediaBusy;
  540. status = NDIS_STATUS_SUCCESS;
  541. }
  542. break;
  543. case OID_IRDA_EXTRA_RCV_BOFS:
  544. DEBUGMSG(DBG_OUT, (" IrsirQueryInformation(OID_IRDA_EXTRA_RCV_BOFS)\n"));
  545. //
  546. // Pass back the number of _extra_ BOFs to be prepended
  547. // to packets sent to this unit at 115.2 baud, the
  548. // maximum Slow IR speed. This will be scaled for other
  549. // speed according to the table in the
  550. // 'Infrared Extensions to NDIS' spec.
  551. //
  552. *(UINT *)InformationBuffer =
  553. pThisDev->dongleCaps.extraBOFsRequired;
  554. break;
  555. case OID_IRDA_MAX_RECEIVE_WINDOW_SIZE:
  556. *(PUINT)InformationBuffer = MAX_RX_PACKETS;
  557. break;
  558. case OID_IRDA_MAX_SEND_WINDOW_SIZE:
  559. *(PUINT)InformationBuffer = MAX_TX_PACKETS;
  560. break;
  561. //
  562. // We don't support these
  563. //
  564. case OID_IRDA_RATE_SNIFF:
  565. DEBUGMSG(DBG_WARN, (" IrsirQueryInformation(OID_IRDA_RATE_SNIFF) - UNSUPPORTED\n"));
  566. status = NDIS_STATUS_NOT_SUPPORTED;
  567. break;
  568. case OID_IRDA_UNICAST_LIST:
  569. DEBUGMSG(DBG_WARN, (" IrsirQueryInformation(OID_IRDA_UNICAST_LIST) - UNSUPPORTED\n"));
  570. status = NDIS_STATUS_NOT_SUPPORTED;
  571. break;
  572. case OID_IRDA_MAX_UNICAST_LIST_SIZE:
  573. DEBUGMSG(DBG_WARN, (" IrsirQueryInformation(OID_IRDA_MAX_UNICAST_LIST_SIZE) - UNSUPPORTED\n"));
  574. status = NDIS_STATUS_NOT_SUPPORTED;
  575. break;
  576. // PNP OIDs
  577. case OID_PNP_CAPABILITIES:
  578. case OID_PNP_ENABLE_WAKE_UP:
  579. case OID_PNP_SET_POWER:
  580. case OID_PNP_QUERY_POWER:
  581. DEBUGMSG(DBG_WARN, ("IRSIR: PNP OID %x BufLen:%d\n", Oid, InformationBufferLength));
  582. break;
  583. default:
  584. DEBUGMSG(DBG_WARN, (" IrsirQueryInformation(%d=0x%x), invalid OID\n", Oid, Oid));
  585. status = NDIS_STATUS_INVALID_OID;
  586. break;
  587. }
  588. }
  589. else
  590. {
  591. *BytesNeeded = infoSizeNeeded - InformationBufferLength;
  592. *BytesWritten = 0;
  593. status = NDIS_STATUS_INVALID_LENGTH;
  594. }
  595. DEBUGMSG(DBG_FUNC, ("-IrsirQueryInformation\n"));
  596. return status;
  597. }
  598. /*****************************************************************************
  599. *
  600. * Function: IrsirSetInformation
  601. *
  602. * Synopsis: IrsirSetInformation allows other layers of the network software
  603. * (e.g., a transport driver) to control the miniport driver
  604. * by changing information that the miniport driver maintains
  605. * in its OIDs, such as the packet filters or multicast addresses.
  606. *
  607. * Arguments: MiniportAdapterContext - miniport context area (PIR_DEVICE)
  608. * Oid - system defined OID_Xxx
  609. * InformationBuffer - buffer containing data for the set Oid
  610. * InformationBufferLength - specifies size of InformationBuffer
  611. * BytesRead - bytes read from InformationBuffer
  612. * BytesNeeded - addition bytes required if
  613. * InformationBufferLength is less than
  614. * what the Oid requires to read
  615. *
  616. * Returns: NDIS_STATUS_SUCCESS - success
  617. * NDIS_STATUS_PENDING - will complete asynchronously and
  618. * call NdisMSetInformationComplete
  619. * NDIS_STATUS_INVALID_OID - don't recognize the Oid
  620. * NDIS_STATUS_INVALID_LENGTH- InformationBufferLength does not
  621. * match length for the Oid
  622. * NDIS_STATUS_INVALID_DATA - supplied data was invalid for the
  623. * given Oid
  624. * NDIS_STATUS_NOT_ACCEPTED - failure
  625. * NDIS_STATUS_NOT_SUPPORTED - do not support an optional Oid
  626. * NDIS_STATUS_RESOURCES - failed allocation of resources
  627. *
  628. * Algorithm:
  629. *
  630. * History: dd-mm-yyyy Author Comment
  631. * 10/1/1996 sholden author
  632. *
  633. * Notes:
  634. *
  635. *
  636. *****************************************************************************/
  637. NDIS_STATUS
  638. IrsirSetInformation(
  639. IN NDIS_HANDLE MiniportAdapterContext,
  640. IN NDIS_OID Oid,
  641. IN PVOID InformationBuffer,
  642. IN ULONG InformationBufferLength,
  643. OUT PULONG BytesRead,
  644. OUT PULONG BytesNeeded
  645. )
  646. {
  647. NDIS_STATUS status;
  648. PIR_DEVICE pThisDev;
  649. SERIALPERF_STATS PerfStats;
  650. int i;
  651. DEBUGMSG(DBG_FUNC, ("+IrsirSetInformation\n"));
  652. status = NDIS_STATUS_SUCCESS;
  653. pThisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
  654. if (InformationBufferLength >= sizeof(UINT))
  655. {
  656. //
  657. // Set default results.
  658. //
  659. UINT info = *(UINT *)InformationBuffer;
  660. *BytesRead = sizeof(UINT);
  661. *BytesNeeded = 0;
  662. switch (Oid)
  663. {
  664. //
  665. // Generic OIDs.
  666. //
  667. case OID_GEN_CURRENT_PACKET_FILTER:
  668. DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_GEN_CURRENT_PACKET_FILTER, %xh)\n", info));
  669. //
  670. // We ignore the packet filter itself.
  671. //
  672. // Note: The protocol may use a NULL filter, in which case
  673. // we will not get this OID; so don't wait on
  674. // OID_GEN_CURRENT_PACKET_FILTER to start receiving
  675. // frames.
  676. //
  677. pThisDev->fGotFilterIndication = TRUE;
  678. break;
  679. case OID_GEN_CURRENT_LOOKAHEAD:
  680. DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_GEN_CURRENT_LOOKAHEAD, %xh)\n", info));
  681. //
  682. // We always indicate entire receive frames all at once,
  683. // so just ignore this.
  684. //
  685. break;
  686. case OID_GEN_PROTOCOL_OPTIONS:
  687. DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_GEN_PROTOCOL_OPTIONS, %xh)\n", info));
  688. //
  689. // Ignore.
  690. //
  691. break;
  692. //
  693. // Infrared OIDs.
  694. //
  695. case OID_IRDA_LINK_SPEED:
  696. DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_IRDA_LINK_SPEED, %xh)\n", info));
  697. if (pThisDev->currentSpeed == info)
  698. {
  699. //
  700. // We are already set to the requested speed.
  701. //
  702. status = NDIS_STATUS_SUCCESS;
  703. DEBUGMSG(DBG_OUT, (" Link speed already set.\n"));
  704. break;
  705. }
  706. status = NDIS_STATUS_INVALID_DATA;
  707. for (i = 0; i < NUM_BAUDRATES; i++)
  708. {
  709. if (supportedBaudRateTable[i].bitsPerSec == info)
  710. {
  711. //
  712. // Keep a pointer to the link speed which has
  713. // been requested.
  714. //
  715. pThisDev->linkSpeedInfo = &supportedBaudRateTable[i];
  716. status = NDIS_STATUS_SUCCESS;
  717. break;
  718. }
  719. }
  720. if (status == NDIS_STATUS_SUCCESS)
  721. {
  722. DEBUGMSG(DBG_OUT, (" Link speed set pending!\n"));
  723. //
  724. // The requested speed is supported.
  725. //
  726. if (pThisDev->pSerialDevObj==NULL)
  727. {
  728. pThisDev->currentSpeed = info;
  729. status = NDIS_STATUS_SUCCESS;
  730. break;
  731. }
  732. //
  733. // Set fPendingSetSpeed = TRUE.
  734. //
  735. // The receive completion/timeout routine checks the
  736. // fPendingSetSpeed flag, waits for all sends to complete
  737. // and then performs the SetSpeed.
  738. //
  739. pThisDev->fPendingSetSpeed = TRUE;
  740. #if IRSIR_EVENT_DRIVEN
  741. if (ScheduleWorkItem(PASSIVE_SET_SPEED, pThisDev,
  742. SetSpeedCallback, NULL, 0) != NDIS_STATUS_SUCCESS)
  743. {
  744. status = NDIS_STATUS_SUCCESS;
  745. }
  746. else
  747. {
  748. status = NDIS_STATUS_PENDING;
  749. }
  750. #else
  751. //
  752. // We always return STATUS_PENDING to NDIS.
  753. //
  754. // After the SetSpeed is complete, the receive completion
  755. // routine will call NdisMIndicateSetComplete.
  756. //
  757. status = NDIS_STATUS_PENDING;
  758. #endif
  759. }
  760. else
  761. {
  762. //
  763. // status = NDIS_STATUS_INVALID_DATA
  764. //
  765. DEBUGMSG(DBG_OUT, (" Invalid link speed\n"));
  766. *BytesRead = 0;
  767. *BytesNeeded = 0;
  768. }
  769. break;
  770. case OID_IRDA_MEDIA_BUSY:
  771. DEBUGMSG(DBG_OUT, (" IrsirSetInformation(OID_IRDA_MEDIA_BUSY, %xh)\n", info));
  772. pThisDev->fMediaBusy = (BOOLEAN)info;
  773. if (pThisDev->pSerialDevObj==NULL ||
  774. ScheduleWorkItem(PASSIVE_CLEAR_MEDIA_BUSY,
  775. pThisDev, ClearMediaBusyCallback, NULL, 0)!=NDIS_STATUS_SUCCESS)
  776. {
  777. status = NDIS_STATUS_SUCCESS;
  778. }
  779. else
  780. {
  781. status = NDIS_STATUS_PENDING;
  782. }
  783. break;
  784. case OID_PNP_CAPABILITIES:
  785. case OID_PNP_ENABLE_WAKE_UP:
  786. case OID_PNP_SET_POWER:
  787. case OID_PNP_QUERY_POWER:
  788. DEBUGMSG(DBG_WARN, ("IRSIR: PNP OID %x BufLen:%d\n", Oid, InformationBufferLength));
  789. break;
  790. case OID_IRDA_RATE_SNIFF:
  791. case OID_IRDA_UNICAST_LIST:
  792. //
  793. // We don't support these
  794. //
  795. DEBUGMSG(DBG_ERROR, (" IrsirSetInformation(OID=%d=0x%x, value=%xh) - unsupported OID\n", Oid, Oid, info));
  796. *BytesRead = 0;
  797. *BytesNeeded = 0;
  798. status = NDIS_STATUS_NOT_SUPPORTED;
  799. break;
  800. case OID_IRDA_SUPPORTED_SPEEDS:
  801. case OID_IRDA_MAX_UNICAST_LIST_SIZE:
  802. case OID_IRDA_TURNAROUND_TIME:
  803. //
  804. // These are query-only parameters (invalid).
  805. //
  806. default:
  807. DEBUGMSG(DBG_ERROR, (" IrsirSetInformation(OID=%d=0x%x, value=%xh) - invalid OID\n", Oid, Oid, info));
  808. *BytesRead = 0;
  809. *BytesNeeded = 0;
  810. status = NDIS_STATUS_INVALID_OID;
  811. break;
  812. }
  813. }
  814. else
  815. {
  816. //
  817. // The given data buffer is not large enough for the information
  818. // to set.
  819. //
  820. *BytesRead = 0;
  821. *BytesNeeded = sizeof(UINT);
  822. status = NDIS_STATUS_INVALID_LENGTH;
  823. }
  824. DEBUGMSG(DBG_FUNC, ("-IrsirSetInformation\n"));
  825. return status;
  826. }