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.

1006 lines
37 KiB

  1. /**************************************************************************************************************************
  2. * REQUEST.C SigmaTel STIR4200 OID query/set module
  3. **************************************************************************************************************************
  4. * (C) Unpublished Copyright of Sigmatel, Inc. All Rights Reserved.
  5. *
  6. *
  7. * Created: 04/06/2000
  8. * Version 0.9
  9. * Edited: 04/24/2000
  10. * Version 0.91
  11. * Edited: 04/27/2000
  12. * Version 0.92
  13. * Edited: 05/03/2000
  14. * Version 0.93
  15. * Edited: 05/12/2000
  16. * Version 0.94
  17. * Edited: 05/19/2000
  18. * Version 0.95
  19. * Edited: 06/13/2000
  20. * Version 0.96
  21. * Edited: 08/22/2000
  22. * Version 1.02
  23. * Edited: 09/25/2000
  24. * Version 1.10
  25. * Edited: 12/29/2000
  26. * Version 1.13
  27. *
  28. *
  29. **************************************************************************************************************************/
  30. #define DOBREAKS // enable debug breaks
  31. #include <ndis.h>
  32. #include <ntddndis.h> // defines OID's
  33. #include <usbdi.h>
  34. #include <usbdlib.h>
  35. #include "debug.h"
  36. #include "ircommon.h"
  37. #include "irndis.h"
  38. #include "diags.h"
  39. //
  40. // These are the OIDs we support
  41. //
  42. UINT supportedOIDs[] =
  43. {
  44. //
  45. // General required OIDs.
  46. //
  47. OID_GEN_SUPPORTED_LIST,
  48. OID_GEN_HARDWARE_STATUS,
  49. OID_GEN_MEDIA_SUPPORTED,
  50. OID_GEN_MEDIA_IN_USE,
  51. OID_GEN_MAXIMUM_LOOKAHEAD,
  52. OID_GEN_MAXIMUM_FRAME_SIZE,
  53. OID_GEN_LINK_SPEED,
  54. OID_GEN_TRANSMIT_BUFFER_SPACE,
  55. OID_GEN_RECEIVE_BUFFER_SPACE,
  56. OID_GEN_TRANSMIT_BLOCK_SIZE,
  57. OID_GEN_RECEIVE_BLOCK_SIZE,
  58. OID_GEN_VENDOR_ID,
  59. OID_GEN_VENDOR_DESCRIPTION,
  60. OID_GEN_CURRENT_PACKET_FILTER,
  61. OID_GEN_CURRENT_LOOKAHEAD,
  62. OID_GEN_DRIVER_VERSION,
  63. OID_GEN_MAXIMUM_TOTAL_SIZE,
  64. OID_GEN_PROTOCOL_OPTIONS,
  65. OID_GEN_MAC_OPTIONS,
  66. OID_GEN_MEDIA_CONNECT_STATUS,
  67. OID_GEN_MAXIMUM_SEND_PACKETS,
  68. OID_GEN_VENDOR_DRIVER_VERSION,
  69. //
  70. // Required statistical OIDs.
  71. //
  72. OID_GEN_XMIT_OK,
  73. OID_GEN_RCV_OK,
  74. OID_GEN_XMIT_ERROR,
  75. OID_GEN_RCV_ERROR,
  76. OID_GEN_RCV_NO_BUFFER,
  77. //
  78. // Infrared-specific OIDs.
  79. //
  80. OID_IRDA_RECEIVING,
  81. OID_IRDA_TURNAROUND_TIME,
  82. OID_IRDA_SUPPORTED_SPEEDS,
  83. OID_IRDA_LINK_SPEED,
  84. OID_IRDA_MEDIA_BUSY,
  85. OID_IRDA_EXTRA_RCV_BOFS,
  86. OID_IRDA_MAX_RECEIVE_WINDOW_SIZE,
  87. OID_IRDA_MAX_SEND_WINDOW_SIZE,
  88. OID_PNP_CAPABILITIES,
  89. OID_PNP_SET_POWER,
  90. OID_PNP_QUERY_POWER
  91. //OID_PNP_ENABLE_WAKE_UP
  92. //OID_PNP_ADD_WAKE_UP_PATTERN
  93. //OID_PNP_REMOVE_WAKE_UP_PATTERN
  94. //OID_PNP_WAKE_UP_PATTERN_LIST
  95. //OID_PNP_WAKE_UP_OK
  96. //OID_PNP_WAKE_UP_ERROR
  97. };
  98. /*****************************************************************************
  99. *
  100. * Function: StIrUsbQueryInformation
  101. *
  102. * Synopsis: Queries the capabilities and status of the miniport driver.
  103. *
  104. * Arguments: MiniportAdapterContext - miniport context area (PIR_DEVICE)
  105. * Oid - system defined OID_Xxx
  106. * InformationBuffer - where to return Oid specific info
  107. * InformationBufferLength - specifies size of InformationBuffer
  108. * BytesWritten - bytes written to InformationBuffer
  109. * BytesNeeded - addition bytes required if
  110. * InformationBufferLength is less than
  111. * what the Oid requires to write
  112. *
  113. * Returns: NDIS_STATUS_SUCCESS - success
  114. * NDIS_STATUS_PENDING - will complete asynchronously and
  115. * call NdisMQueryInformationComplete
  116. * NDIS_STATUS_INVALID_OID - don't recognize the Oid
  117. * NDIS_STATUS_INVALID_LENGTH- InformationBufferLength does not
  118. * match length for the Oid
  119. * NDIS_STATUS_NOT_ACCEPTED - failure
  120. * NDIS_STATUS_NOT_SUPPORTED - do not support an optional Oid
  121. * NDIS_STATUS_RESOURCES - failed allocation of resources
  122. *
  123. * Notes:
  124. * See list of Supported OIDs at the top of this module in the supportedOIDs[] array
  125. *
  126. *
  127. *****************************************************************************/
  128. NDIS_STATUS
  129. StIrUsbQueryInformation(
  130. IN NDIS_HANDLE MiniportAdapterContext,
  131. IN NDIS_OID Oid,
  132. IN PVOID InformationBuffer,
  133. IN ULONG InformationBufferLength,
  134. OUT PULONG BytesWritten,
  135. OUT PULONG BytesNeeded
  136. )
  137. {
  138. PIR_DEVICE pThisDev;
  139. NDIS_STATUS status;
  140. UINT speeds;
  141. UINT i;
  142. UINT infoSizeNeeded;
  143. PUINT pInfoPtr;
  144. PNDIS_PNP_CAPABILITIES pNdisPnpCapabilities;
  145. static char vendorDesc[] = "SigmaTel Usb-IrDA Dongle";
  146. DEBUGMSG(DBG_FUNC, ("+StIrUsbQueryInformation\n"));
  147. pThisDev = CONTEXT_TO_DEV( MiniportAdapterContext );
  148. IRUSB_ASSERT( NULL != pThisDev );
  149. IRUSB_ASSERT( NULL != BytesWritten );
  150. IRUSB_ASSERT( NULL != BytesNeeded );
  151. status = NDIS_STATUS_SUCCESS;
  152. KeQuerySystemTime( &pThisDev->LastQueryTime ); //used by check for hang handler
  153. pThisDev->fQuerypending = TRUE;
  154. if( (NULL == InformationBuffer) && InformationBufferLength )
  155. {
  156. //
  157. // Should be impossible but it happened on an MP system!
  158. //
  159. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation() NULL info buffer passed!, InformationBufferLength = dec %d\n",InformationBufferLength));
  160. status = NDIS_STATUS_NOT_ACCEPTED;
  161. *BytesNeeded =0;
  162. *BytesWritten = 0;
  163. goto done;
  164. }
  165. //
  166. // Figure out buffer size needed.
  167. // Most OIDs just return a single UINT, but there are exceptions.
  168. //
  169. switch( Oid )
  170. {
  171. case OID_GEN_SUPPORTED_LIST:
  172. infoSizeNeeded = sizeof(supportedOIDs);
  173. break;
  174. case OID_PNP_CAPABILITIES:
  175. infoSizeNeeded = sizeof(NDIS_PNP_CAPABILITIES);
  176. break;
  177. case OID_GEN_DRIVER_VERSION:
  178. infoSizeNeeded = sizeof(USHORT);
  179. break;
  180. case OID_GEN_VENDOR_DESCRIPTION:
  181. infoSizeNeeded = sizeof(vendorDesc);
  182. break;
  183. case OID_IRDA_SUPPORTED_SPEEDS:
  184. speeds = pThisDev->ClassDesc.wBaudRate;
  185. for (infoSizeNeeded = 0; speeds; infoSizeNeeded += sizeof(UINT))
  186. {
  187. //
  188. // This instruction clears the lowest set bit in speeds.
  189. // Trust me.
  190. //
  191. speeds &= (speeds - 1);
  192. }
  193. break;
  194. default:
  195. infoSizeNeeded = sizeof(UINT);
  196. break;
  197. }
  198. //
  199. // If the protocol provided a large enough buffer, we can go ahead
  200. // and complete the query.
  201. //
  202. if( InformationBufferLength >= infoSizeNeeded )
  203. {
  204. //
  205. // Set default results.
  206. //
  207. *BytesWritten = infoSizeNeeded;
  208. *BytesNeeded = 0;
  209. switch( Oid )
  210. {
  211. //
  212. // Generic OIDs.
  213. //
  214. case OID_GEN_SUPPORTED_LIST:
  215. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_SUPPORTED_LIST)\n"));
  216. /*
  217. Specifies an array of OIDs for objects that the underlying
  218. driver or its device supports. Objects include general, media-specific,
  219. and implementation-specific objects.
  220. The underlying driver should order the OID list it returns
  221. in increasing numeric order. NDIS forwards a subset of the returned
  222. list to protocols that make this query. That is, NDIS filters
  223. any supported statistics OIDs out of the list since protocols
  224. never make statistics queries subsequentlly.
  225. */
  226. NdisMoveMemory(
  227. InformationBuffer,
  228. (PVOID)supportedOIDs,
  229. sizeof(supportedOIDs)
  230. );
  231. break;
  232. case OID_GEN_HARDWARE_STATUS:
  233. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_HARDWARE_STATUS)\n"));
  234. //
  235. // If we can be called with a context, then we are
  236. // initialized and ready.
  237. //
  238. *(UINT *)InformationBuffer = NdisHardwareStatusReady;
  239. break;
  240. case OID_GEN_MEDIA_SUPPORTED:
  241. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_MEDIA_SUPPORTED)\n"));
  242. *(UINT *)InformationBuffer = NdisMediumIrda;
  243. break;
  244. case OID_GEN_MEDIA_IN_USE:
  245. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_MEDIA_IN_USE)\n"));
  246. *(UINT *)InformationBuffer = NdisMediumIrda;
  247. break;
  248. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  249. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_TRANSMIT_BUFFER_SPACE)\n"));
  250. /*
  251. The amount of memory, in bytes, on the device available
  252. for buffering transmit data.
  253. */
  254. *(UINT *)InformationBuffer = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
  255. break;
  256. case OID_GEN_RECEIVE_BUFFER_SPACE:
  257. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_RECEIVE_BUFFER_SPACE)\n"));
  258. /*
  259. The amount of memory on the device available
  260. for buffering receive data.
  261. */
  262. *(UINT *)InformationBuffer = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
  263. break;
  264. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  265. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_TRANSMIT_BLOCK_SIZE)\n"));
  266. /*
  267. The minimum number of bytes that a single net packet
  268. occupies in the transmit buffer space of the device.
  269. For example, on some devices the transmit space is
  270. divided into 256-byte pieces so such a device's
  271. transmit block size would be 256. To calculate
  272. the total transmit buffer space on such a device,
  273. its driver multiplies the number of transmit
  274. buffers on the device by its transmit block size.
  275. For other devices, the transmit block size is
  276. identical to its maximum packet size.
  277. */
  278. *(UINT *)InformationBuffer = pThisDev->dongleCaps.dataSize + USB_IRDA_TOTAL_NON_DATA_SIZE;
  279. break;
  280. case OID_GEN_RECEIVE_BLOCK_SIZE:
  281. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_RECEIVE_BLOCK_SIZE)\n"));
  282. /*
  283. The amount of storage, in bytes, that a single packet
  284. occupies in the receive buffer space of the device
  285. */
  286. *(UINT *)InformationBuffer = pThisDev->dongleCaps.dataSize + USB_IRDA_TOTAL_NON_DATA_SIZE;
  287. break;
  288. case OID_GEN_MAXIMUM_LOOKAHEAD:
  289. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)\n"));
  290. /*
  291. The maximum number of bytes the device can always provide as lookahead data.
  292. If the underlying driver supports multipacket receive indications,
  293. bound protocols are given full net packets on every indication.
  294. Consequently, this value is identical to that
  295. returned for OID_GEN_RECEIVE_BLOCK_SIZE.
  296. */
  297. *(UINT *)InformationBuffer = pThisDev->dongleCaps.dataSize + USB_IRDA_TOTAL_NON_DATA_SIZE;
  298. break;
  299. case OID_GEN_CURRENT_LOOKAHEAD:
  300. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_CURRENT_LOOKAHEAD)\n"));
  301. /*
  302. The number of bytes of received packet data,
  303. excluding the header, that will be indicated
  304. to the protocol driver. For a query,
  305. NDIS returns the largest lookahead size from
  306. among all the bindings. A protocol driver can
  307. set a suggested value for the number of bytes
  308. to be used in its binding; however,
  309. the underlying device driver is never required
  310. to limit its indications to the value set.
  311. If the underlying driver supports multipacket
  312. receive indications, bound protocols are given
  313. full net packets on every indication. Consequently,
  314. this value is identical to that returned for OID_GEN_RECEIVE_BLOCK_SIZE.
  315. */
  316. *(UINT *)InformationBuffer = pThisDev->dongleCaps.dataSize + USB_IRDA_TOTAL_NON_DATA_SIZE;
  317. break;
  318. case OID_GEN_MAXIMUM_FRAME_SIZE:
  319. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_MAXIMUM_FRAME_SIZE)\n"));
  320. /*
  321. The maximum network packet size in bytes
  322. the device supports, not including a header.
  323. For a binding emulating another medium type,
  324. the device driver must define the maximum frame
  325. size in such a way that it will not transform
  326. a protocol-supplied net packet of this size
  327. to a net packet too large for the true network medium.
  328. */
  329. *(UINT *)InformationBuffer = pThisDev->dongleCaps.dataSize;
  330. break;
  331. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  332. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_MAXIMUM_TOTAL_SIZE)\n"));
  333. /*
  334. The maximum total packet length, in bytes,
  335. the device supports, including the header.
  336. This value is medium-dependent. The returned
  337. length specifies the largest packet a protocol
  338. driver can pass to NdisSend or NdisSendPackets.
  339. For a binding emulating another media type,
  340. the device driver must define the maximum total
  341. packet length in such a way that it will not
  342. transform a protocol-supplied net packet of
  343. this size to a net packet too large for the true network medium.
  344. */
  345. *(UINT *)InformationBuffer = pThisDev->dongleCaps.dataSize; //+ USB_IRDA_TOTAL_NON_DATA_SIZE;
  346. break;
  347. case OID_IRDA_MAX_RECEIVE_WINDOW_SIZE:
  348. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_IRDA_MAX_RECEIVE_WINDOW_SIZE) \n"));
  349. // Gotten from the device's USB Class-Specific Descriptor
  350. *(PUINT)InformationBuffer = pThisDev->dongleCaps.windowSize;
  351. break;
  352. case OID_IRDA_MAX_SEND_WINDOW_SIZE:
  353. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_IRDA_MAX_SEND_WINDOW_SIZE) \n"));
  354. // Gotten from the device's USB Class-Specific Descriptor
  355. *(PUINT)InformationBuffer = pThisDev->dongleCaps.windowSize;
  356. break;
  357. case OID_GEN_VENDOR_ID:
  358. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_VENDOR_ID)\n"));
  359. // we get this from our config descriptor
  360. *(UINT *)InformationBuffer = pThisDev->IdVendor;
  361. break;
  362. case OID_GEN_VENDOR_DESCRIPTION:
  363. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_VENDOR_DESCRIPTION)\n"));
  364. NdisMoveMemory(
  365. InformationBuffer,
  366. (PVOID)vendorDesc,
  367. sizeof(vendorDesc)
  368. );
  369. break;
  370. case OID_GEN_LINK_SPEED:
  371. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_LINK_SPEED)\n"));
  372. //
  373. // Return MAXIMUM POSSIBLE speed for this device in units
  374. // of 100 bits/sec.
  375. //
  376. *(UINT *)InformationBuffer = 0;
  377. speeds = pThisDev->ClassDesc.wBaudRate;
  378. *BytesWritten = 0;
  379. for ( i = 0; i<NUM_BAUDRATES; i++ )
  380. {
  381. if ((supportedBaudRateTable[i].NdisCode & speeds) &&
  382. ((supportedBaudRateTable[i].BitsPerSec)/100 > *(UINT *)InformationBuffer))
  383. {
  384. *(UINT *)InformationBuffer = supportedBaudRateTable[i].BitsPerSec/100;
  385. *BytesWritten = sizeof(UINT);
  386. }
  387. }
  388. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_LINK_SPEED) %d\n",*(UINT *)InformationBuffer));
  389. break;
  390. case OID_GEN_CURRENT_PACKET_FILTER:
  391. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_CURRENT_PACKET_FILTER)\n"));
  392. *(UINT *)InformationBuffer = NDIS_PACKET_TYPE_PROMISCUOUS;
  393. break;
  394. case OID_GEN_DRIVER_VERSION:
  395. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_DRIVER_VERSION)\n"));
  396. *(USHORT *)InformationBuffer = ((NDIS_MAJOR_VERSION << 8) | NDIS_MINOR_VERSION);
  397. break;
  398. case OID_GEN_PROTOCOL_OPTIONS:
  399. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_PROTOCOL_OPTIONS)\n"));
  400. DEBUGMSG(DBG_ERR, ("This is a set-only OID\n"));
  401. *BytesWritten = 0;
  402. status = NDIS_STATUS_NOT_SUPPORTED;
  403. break;
  404. case OID_GEN_MAC_OPTIONS:
  405. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_MAC_OPTIONS)\n"));
  406. *(UINT *)InformationBuffer = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND;
  407. break;
  408. case OID_GEN_MEDIA_CONNECT_STATUS:
  409. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_MEDIA_CONNECT_STATUS)\n"));
  410. //
  411. // Since we are not physically connected to a LAN, we
  412. // cannot determine whether or not we are connected;
  413. // so always indicate that we are.
  414. //
  415. *(UINT *)InformationBuffer = NdisMediaStateConnected;
  416. break;
  417. case OID_GEN_MAXIMUM_SEND_PACKETS:
  418. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_MAXIMUM_SEND_PACKETS)\n"));
  419. //
  420. //
  421. // The maximum number of send packets the
  422. // MiniportSendPackets function can accept.
  423. //
  424. *(UINT *)InformationBuffer = NUM_SEND_CONTEXTS-3;
  425. break;
  426. case OID_GEN_VENDOR_DRIVER_VERSION:
  427. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_VENDOR_DRIVER_VERSION)\n"));
  428. *(UINT *)InformationBuffer = ((DRIVER_MAJOR_VERSION << 16) | DRIVER_MINOR_VERSION);
  429. break;
  430. //
  431. // Required statistical OIDs.
  432. //
  433. case OID_GEN_XMIT_OK:
  434. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_XMIT_OK)\n"));
  435. *(UINT *)InformationBuffer = (UINT)pThisDev->packetsSent;
  436. break;
  437. case OID_GEN_RCV_OK:
  438. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_RCV_OK)\n"));
  439. *(UINT *)InformationBuffer = (UINT)pThisDev->packetsReceived;
  440. break;
  441. case OID_GEN_XMIT_ERROR:
  442. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_XMIT_ERROR)\n"));
  443. *(UINT *)InformationBuffer = (UINT)(pThisDev->packetsSentDropped +
  444. pThisDev->packetsSentRejected + pThisDev->packetsSentInvalid );
  445. break;
  446. case OID_GEN_RCV_ERROR:
  447. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_RCV_ERROR)\n"));
  448. *(UINT *)InformationBuffer = (UINT)(pThisDev->packetsReceivedDropped +
  449. pThisDev->packetsReceivedChecksum + pThisDev->packetsReceivedRunt +
  450. pThisDev->packetsReceivedOverflow);
  451. break;
  452. case OID_GEN_RCV_NO_BUFFER:
  453. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_GEN_RCV_NO_BUFFER)\n"));
  454. *(UINT *)InformationBuffer = (UINT)pThisDev->packetsReceivedNoBuffer;
  455. break;
  456. //
  457. // Infrared OIDs.
  458. //
  459. case OID_IRDA_LINK_SPEED:
  460. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_IRDA_LINK_SPEED)\n"));
  461. *(UINT *)InformationBuffer = (UINT)pThisDev->currentSpeed;
  462. break;
  463. case OID_IRDA_RECEIVING:
  464. #if !defined(ONLY_ERROR_MESSAGES)
  465. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_IRDA_RECEIVING, %xh)\n",pThisDev->fCurrentlyReceiving));
  466. #endif
  467. *(UINT *)InformationBuffer = (UINT)pThisDev->fCurrentlyReceiving;
  468. break;
  469. case OID_IRDA_TURNAROUND_TIME:
  470. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_IRDA_TURNAROUND_TIME)\n"));
  471. //
  472. // Time remote station must wait after receiving data from us
  473. // before we can receive
  474. //
  475. *(UINT *)InformationBuffer = pThisDev->dongleCaps.turnAroundTime_usec;
  476. break;
  477. case OID_IRDA_SUPPORTED_SPEEDS:
  478. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_IRDA_SUPPORTED_SPEEDS)\n"));
  479. speeds = pThisDev->ClassDesc.wBaudRate;
  480. *BytesWritten = 0;
  481. for( i = 0, pInfoPtr = (PUINT)InformationBuffer;
  482. (i < NUM_BAUDRATES) && speeds && (InformationBufferLength >= sizeof(UINT));
  483. i++ )
  484. {
  485. if( supportedBaudRateTable[i].NdisCode & speeds )
  486. {
  487. *pInfoPtr++ = supportedBaudRateTable[i].BitsPerSec;
  488. InformationBufferLength -= sizeof(UINT);
  489. *BytesWritten += sizeof(UINT);
  490. speeds &= ~supportedBaudRateTable[i].NdisCode;
  491. DEBUGMSG(DBG_FUNC, (" - supporting speed %d bps\n", supportedBaudRateTable[i].BitsPerSec));
  492. }
  493. }
  494. if( speeds )
  495. {
  496. //
  497. // This shouldn't happen, since we checked the
  498. // InformationBuffer size earlier.
  499. //
  500. DEBUGMSG(DBG_ERR, (" Something's wrong; previous check for buf size failed somehow\n"));
  501. for( *BytesNeeded = 0; speeds; *BytesNeeded += sizeof(UINT) )
  502. {
  503. //
  504. // This instruction clears the lowest set bit in speeds.
  505. // Trust me.
  506. //
  507. speeds &= (speeds - 1);
  508. }
  509. status = NDIS_STATUS_INVALID_LENGTH;
  510. }
  511. else
  512. {
  513. status = NDIS_STATUS_SUCCESS;
  514. }
  515. break;
  516. case OID_IRDA_MEDIA_BUSY:
  517. #if !defined(ONLY_ERROR_MESSAGES)
  518. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_IRDA_MEDIA_BUSY, %xh)\n", pThisDev->fMediaBusy));
  519. #endif
  520. /*
  521. According to W2000 ddk doc:
  522. The IrDA protocol driver sets this OID to zero to request the miniport to
  523. start monitoring for a media busy condition. The IrDA protocol
  524. can then query this OID to determine whether the media is busy.
  525. If the media is not busy, the miniport returns a zero for this
  526. OID when queried. If the media is busy,that is, if the miniport
  527. has detected some traffic since the IrDA protocol driver last
  528. set OID_IRDA_MEDIA_BUSY to zero the miniport returns a non-zero
  529. value for this OID when queried. On detecting the media busy
  530. condition. the miniport must also call NdisMIndicateStatus to
  531. indicate NDIS_STATUS_MEDIA_BUSY. When the media is busy,
  532. the IrDA protocol driver will not send packets to the miniport
  533. for transmission. After the miniport has detected a busy state,
  534. it does not have to monitor for a media busy condition until
  535. the IrDA protocol driver again sets OID_IRDA_MEDIA_BUSY to zero.
  536. According to USB IrDA Bridge Device Definition Doc sec 5.4.1.2:
  537. The bmStatus field indicators shall be set by the Device as follows:
  538. Media_Busy
  539. Media_Busy shall indicate zero (0) if the Device:
  540. . has not received a Check Media Busy class-specific request
  541. . has detected no traffic on the infrared media since receiving a Check Media Busy
  542. . class-specific request
  543. . Has returned a header with Media_Busy set to one (1) since receiving a Check
  544. Media Busy class-specific request.
  545. Media_Busy shall indicate one (1) if the Device has detected traffic on the infrared
  546. media since receiving a Check Media Busy class-specific request. Note that
  547. Media_Busy shall indicate one (1) in exactly one header following receipt of each
  548. Check Media Busy class-specific request.
  549. According to USB IrDA Bridge Device Definition Doc sec 6.2.2:
  550. Check Media Busy
  551. This class-specific request instructs the Device to look for a media busy condition. If infrared
  552. traffic of any kind is detected by this Device, the Device shall set the Media_Busy field in the
  553. bmStatus field in the next Data-In packet header sent to the host. In the case where a Check
  554. Media Busy command has been received, a media busy condition detected, and no IrLAP frame
  555. traffic is ready to transmit to the host, the Device shall set the Media_Busy field and send it in a
  556. Data-In packet with no IrLAP frame following the header.
  557. bmRequestType bRequest wValue wIndex wLength Data
  558. 00100001B 3 Zero Interface Zero [None]
  559. */
  560. #if DBG
  561. if ( pThisDev->fMediaBusy )
  562. pThisDev->NumYesQueryMediaBusyOids++;
  563. else
  564. pThisDev->NumNoQueryMediaBusyOids++;
  565. #endif
  566. *(UINT *)InformationBuffer = pThisDev->fMediaBusy;
  567. status = NDIS_STATUS_SUCCESS;
  568. break;
  569. case OID_IRDA_EXTRA_RCV_BOFS:
  570. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_IRDA_EXTRA_RCV_BOFS)\n"));
  571. //
  572. // Pass back the number of _extra_ BOFs to be prepended
  573. // to packets sent to this unit at 115.2 baud, the
  574. // maximum Slow IR speed.
  575. // Gotten from the device's USB Class-Specific Descriptor
  576. //
  577. *(UINT *)InformationBuffer = pThisDev->dongleCaps.extraBOFS;
  578. break;
  579. // PNP OIDs
  580. case OID_PNP_CAPABILITIES:
  581. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_PNP_CAPABILITIES) OID %x BufLen:%d\n", Oid, InformationBufferLength));
  582. NdisZeroMemory(
  583. InformationBuffer,
  584. sizeof(NDIS_PNP_CAPABILITIES)
  585. );
  586. //
  587. // Prepare formatting with the info
  588. //
  589. pNdisPnpCapabilities = (PNDIS_PNP_CAPABILITIES)InformationBuffer;
  590. pNdisPnpCapabilities->WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
  591. pNdisPnpCapabilities->WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
  592. pNdisPnpCapabilities->WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
  593. break;
  594. case OID_PNP_QUERY_POWER:
  595. //
  596. // If we are asked to power down prepare to do it
  597. //
  598. switch( (NDIS_DEVICE_POWER_STATE)*(UINT *)InformationBuffer )
  599. {
  600. case NdisDeviceStateD0:
  601. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_PNP_QUERY_POWER) NdisDeviceStateD0\n"));
  602. break;
  603. case NdisDeviceStateD1:
  604. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_PNP_QUERY_POWER) NdisDeviceStateD1\n"));
  605. //break;
  606. case NdisDeviceStateD2:
  607. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_PNP_QUERY_POWER) NdisDeviceStateD2\n"));
  608. //break;
  609. case NdisDeviceStateD3:
  610. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(OID_PNP_QUERY_POWER) NdisDeviceStateD3\n"));
  611. //
  612. // The processing must be essentially shut down
  613. //
  614. InterlockedExchange( (PLONG)&pThisDev->fProcessing, FALSE );
  615. ScheduleWorkItem( pThisDev, SuspendIrDevice, NULL, 0 );
  616. //
  617. // This will be the new value of the DPLL register (when we come back up)
  618. //
  619. pThisDev->StIrTranceiver.DpllTuneReg = STIR4200_DPLL_DEFAULT;
  620. status = NDIS_STATUS_PENDING;
  621. break;
  622. }
  623. break;
  624. default:
  625. DEBUGMSG(DBG_ERR, (" StIrUsbQueryInformation(%d=0x%x), invalid OID\n", Oid, Oid));
  626. status = NDIS_STATUS_NOT_SUPPORTED;
  627. break;
  628. }
  629. }
  630. else
  631. {
  632. *BytesNeeded = infoSizeNeeded - InformationBufferLength;
  633. *BytesWritten = 0;
  634. status = NDIS_STATUS_INVALID_LENGTH;
  635. }
  636. done:
  637. if( NDIS_STATUS_PENDING != status )
  638. {
  639. // zero-out the time so check for hang handler knows nothing pending
  640. pThisDev->LastQueryTime.QuadPart = 0;
  641. pThisDev->fQuerypending = FALSE;
  642. }
  643. DEBUGMSG(DBG_FUNC, ("-StIrUsbQueryInformation\n"));
  644. return status;
  645. }
  646. /*****************************************************************************
  647. *
  648. * Function: StIrUsbSetInformation
  649. *
  650. * Synopsis: StIrUsbSetInformation allows other layers of the network software
  651. * (e.g., a transport driver) to control the miniport driver
  652. * by changing information that the miniport driver maintains
  653. * in its OIDs, such as the packet filters or multicast addresses.
  654. *
  655. * Arguments: MiniportAdapterContext - miniport context area (PIR_DEVICE)
  656. * Oid - system defined OID_Xxx
  657. * InformationBuffer - buffer containing data for the set Oid
  658. * InformationBufferLength - specifies size of InformationBuffer
  659. * BytesRead - bytes read from InformationBuffer
  660. * BytesNeeded - addition bytes required if
  661. * InformationBufferLength is less than
  662. * what the Oid requires to read
  663. *
  664. * Returns: NDIS_STATUS_SUCCESS - success
  665. * NDIS_STATUS_PENDING - will complete asynchronously and
  666. * call NdisMSetInformationComplete
  667. * NDIS_STATUS_INVALID_OID - don't recognize the Oid
  668. * NDIS_STATUS_INVALID_LENGTH- InformationBufferLength does not
  669. * match length for the Oid
  670. * NDIS_STATUS_INVALID_DATA - supplied data was invalid for the
  671. * given Oid
  672. * NDIS_STATUS_NOT_ACCEPTED - failure
  673. * NDIS_STATUS_NOT_SUPPORTED - do not support an optional Oid
  674. * NDIS_STATUS_RESOURCES - failed allocation of resources
  675. *
  676. * Notes:
  677. *
  678. *
  679. *****************************************************************************/
  680. NDIS_STATUS
  681. StIrUsbSetInformation(
  682. IN NDIS_HANDLE MiniportAdapterContext,
  683. IN NDIS_OID Oid,
  684. IN PVOID InformationBuffer,
  685. IN ULONG InformationBufferLength,
  686. OUT PULONG BytesRead,
  687. OUT PULONG BytesNeeded
  688. )
  689. {
  690. NDIS_STATUS status;
  691. PIR_DEVICE pThisDev;
  692. int i;
  693. DEBUGMSG(DBG_FUNC, ("+StIrUsbSetInformation\n"));
  694. status = NDIS_STATUS_SUCCESS;
  695. pThisDev = CONTEXT_TO_DEV( MiniportAdapterContext );
  696. IRUSB_ASSERT( NULL != pThisDev );
  697. IRUSB_ASSERT( NULL != BytesRead );
  698. IRUSB_ASSERT( NULL != BytesNeeded );
  699. KeQuerySystemTime( &pThisDev->LastSetTime ); //used by check for hang handler
  700. pThisDev->fSetpending = TRUE;
  701. if( (NULL == InformationBuffer) && InformationBufferLength )
  702. {
  703. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation() NULL info buffer passed!,InformationBufferLength = dec %d\n",InformationBufferLength));
  704. status = NDIS_STATUS_NOT_ACCEPTED;
  705. *BytesNeeded =0;
  706. *BytesRead = 0;
  707. goto done;
  708. }
  709. if( InformationBufferLength >= sizeof(UINT) )
  710. {
  711. //
  712. // Set default results.
  713. //
  714. UINT info = 0;
  715. if( NULL != InformationBuffer )
  716. {
  717. info = *(UINT *)InformationBuffer;
  718. }
  719. *BytesRead = sizeof(UINT);
  720. *BytesNeeded = 0;
  721. switch( Oid )
  722. {
  723. //
  724. // Generic OIDs.
  725. //
  726. case OID_GEN_CURRENT_PACKET_FILTER:
  727. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_GEN_CURRENT_PACKET_FILTER, %xh)\n", info));
  728. //
  729. // We ignore the packet filter itself.
  730. //
  731. // Note: The protocol may use a NULL filter, in which case
  732. // we will not get this OID; so don't wait on
  733. // OID_GEN_CURRENT_PACKET_FILTER to start receiving
  734. // frames.
  735. //
  736. pThisDev->fGotFilterIndication = TRUE;
  737. break;
  738. case OID_GEN_CURRENT_LOOKAHEAD:
  739. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_GEN_CURRENT_LOOKAHEAD, %xh)\n", info));
  740. //
  741. // We always indicate entire receive frames all at once,
  742. // so just ignore this.
  743. //
  744. break;
  745. case OID_GEN_PROTOCOL_OPTIONS:
  746. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_GEN_PROTOCOL_OPTIONS, %xh)\n", info));
  747. //
  748. // Ignore.
  749. //
  750. break;
  751. //
  752. // Infrared OIDs.
  753. //
  754. case OID_IRDA_LINK_SPEED:
  755. //
  756. // Don't do it if we are in diagnostic mode
  757. //
  758. #if defined(DIAGS)
  759. if( pThisDev->DiagsActive )
  760. {
  761. DEBUGMSG(DBG_ERR, (" Rejecting due to diagnostic mode\n"));
  762. status = NDIS_STATUS_SUCCESS;
  763. break;
  764. }
  765. #endif
  766. if( pThisDev->currentSpeed == info )
  767. {
  768. //
  769. // We are already set to the requested speed.
  770. //
  771. DEBUGONCE(DBG_FUNC, (" Link speed already set.\n"));
  772. status = NDIS_STATUS_SUCCESS;
  773. break;
  774. }
  775. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_IRDA_LINK_SPEED, 0x%x, decimal %d)\n",info, info));
  776. status = NDIS_STATUS_INVALID_DATA;
  777. for( i = 0; i < NUM_BAUDRATES; i++ )
  778. {
  779. if( supportedBaudRateTable[i].BitsPerSec == info )
  780. {
  781. //
  782. // Keep a pointer to the link speed which has
  783. // been requested.
  784. //
  785. pThisDev->linkSpeedInfo = &supportedBaudRateTable[i];
  786. status = NDIS_STATUS_PENDING;
  787. break; //for
  788. }
  789. }
  790. //
  791. // Don't set if there is an error
  792. //
  793. if( NDIS_STATUS_PENDING != status )
  794. {
  795. status = NDIS_STATUS_INVALID_DATA;
  796. DEBUGMSG(DBG_ERR, (" Invalid link speed\n"));
  797. *BytesRead = 0;
  798. *BytesNeeded = 0;
  799. break;
  800. }
  801. //
  802. // Set the new speed
  803. //
  804. IrUsb_PrepareSetSpeed( pThisDev );
  805. break;
  806. case OID_IRDA_MEDIA_BUSY:
  807. #if !defined(ONLY_ERROR_MESSAGES)
  808. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_IRDA_MEDIA_BUSY, %xh)\n", info));
  809. #endif
  810. //
  811. // See comments in the 'query' code above;
  812. //
  813. #if DBG
  814. pThisDev->NumSetMediaBusyOids++;
  815. #endif
  816. // should always be setting 0
  817. DEBUGCOND( DBG_ERR, TRUE == info, (" StIrUsbSetInformation(OID_IRDA_MEDIA_BUSY, %xh)\n", info));
  818. InterlockedExchange( &pThisDev->fMediaBusy, FALSE );
  819. InterlockedExchange( &pThisDev->fIndicatedMediaBusy, FALSE );
  820. status = NDIS_STATUS_SUCCESS;
  821. break;
  822. case OID_PNP_SET_POWER:
  823. //
  824. // Perform the operations required to stop/resume
  825. //
  826. switch( (NDIS_DEVICE_POWER_STATE)info )
  827. {
  828. case NdisDeviceStateD0:
  829. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_PNP_SET_POWER) NdisDeviceStateD0\n"));
  830. //
  831. // Processing back up (and a new speed setting)
  832. //
  833. ScheduleWorkItem( pThisDev, ResumeIrDevice, NULL, 0 );
  834. break;
  835. case NdisDeviceStateD1:
  836. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_PNP_SET_POWER) NdisDeviceStateD1\n"));
  837. //break;
  838. case NdisDeviceStateD2:
  839. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_PNP_SET_POWER) NdisDeviceStateD2\n"));
  840. //break;
  841. case NdisDeviceStateD3:
  842. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID_PNP_SET_POWER) NdisDeviceStateD3\n"));
  843. //
  844. // Handle the case where query wasn't sent
  845. //
  846. if( pThisDev->fProcessing )
  847. {
  848. InterlockedExchange( (PLONG)&pThisDev->fProcessing, FALSE );
  849. ScheduleWorkItem( pThisDev, SuspendIrDevice, NULL, 0 );
  850. //
  851. // This will be the new value of the DPLL register (when we come back up)
  852. //
  853. pThisDev->StIrTranceiver.DpllTuneReg = STIR4200_DPLL_DEFAULT;
  854. }
  855. break;
  856. }
  857. break;
  858. default:
  859. DEBUGMSG(DBG_ERR, (" StIrUsbSetInformation(OID=%d=0x%x, value=%xh) - invalid OID\n", Oid, Oid, info));
  860. *BytesRead = 0;
  861. *BytesNeeded = 0;
  862. status = NDIS_STATUS_INVALID_OID;
  863. break;
  864. }
  865. }
  866. else
  867. {
  868. //
  869. // The given data buffer is not large enough for the information
  870. // to set.
  871. //
  872. *BytesRead = 0;
  873. *BytesNeeded = sizeof(UINT);
  874. status = NDIS_STATUS_INVALID_LENGTH;
  875. }
  876. done:
  877. if( NDIS_STATUS_PENDING != status )
  878. {
  879. //
  880. // zero-out the time so check for hang handler knows nothing pending
  881. //
  882. pThisDev->LastSetTime.QuadPart = 0;
  883. pThisDev->fSetpending = FALSE;
  884. }
  885. DEBUGMSG(DBG_FUNC, ("-StIrUsbSetInformation\n"));
  886. return status;
  887. }
  888.