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.

619 lines
16 KiB

  1. /**************************************************************************************************************************
  2. * IRMISC.C SigmaTel STIR4200 misc 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: 09/16/2000
  10. * Version 1.03
  11. * Edited: 09/25/2000
  12. * Version 1.10
  13. * Edited: 12/07/2000
  14. * Version 1.12
  15. * Edited: 01/09/2001
  16. * Version 1.13
  17. * Edited: 01/16/2001
  18. * Version 1.14
  19. *
  20. *
  21. **************************************************************************************************************************/
  22. #define DOBREAKS // enable debug breaks
  23. #include <ndis.h>
  24. #include <ntddndis.h> // defines OID's
  25. #include <usbdi.h>
  26. #include <usbdlib.h>
  27. #include "debug.h"
  28. #include "ircommon.h"
  29. #include "irndis.h"
  30. /*****************************************************************************
  31. *
  32. * Function: IrUsb_CreateDeviceExt
  33. *
  34. * Synopsis: Creates a IR device extension
  35. *
  36. * Arguments: DeviceExt - pointer to DeviceExt pointer to return created device extension.
  37. *
  38. * Returns: STATUS_SUCCESS if successful
  39. * STATUS_UNSUCCESSFUL otherwise
  40. *
  41. * Notes:
  42. *
  43. *****************************************************************************/
  44. NTSTATUS
  45. IrUsb_CreateDeviceExt(
  46. IN OUT PIR_DEVICE *DeviceExt
  47. )
  48. {
  49. NTSTATUS ntStatus = STATUS_SUCCESS;
  50. PIR_DEVICE pThisDev = NULL;
  51. DEBUGMSG(DBG_FUNC,("+IrUsb_CreateDeviceExt() \n"));
  52. pThisDev = NewDevice();
  53. if( !pThisDev )
  54. {
  55. ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  56. goto done;
  57. }
  58. *DeviceExt = pThisDev;
  59. done:
  60. DEBUGMSG(DBG_FUNC,("-IrUsb_CreateDeviceExt() \n"));
  61. return ntStatus;
  62. }
  63. /*****************************************************************************
  64. *
  65. * Function: IrUsb_AddDevice
  66. *
  67. * Synopsis: This routine is called to create and initialize our Functional Device Object (FDO).
  68. * For monolithic drivers, this is done in DriverEntry(), but Plug and Play devices
  69. * wait for a PnP event
  70. *
  71. * Arguments: DeviceExt - receives ptr to new dev obj
  72. *
  73. * Returns: STATUS_SUCCESS if successful,
  74. * STATUS_UNSUCCESSFUL otherwise
  75. *
  76. * Notes:
  77. *
  78. *****************************************************************************/
  79. NTSTATUS
  80. IrUsb_AddDevice(
  81. IN OUT PIR_DEVICE *DeviceExt
  82. )
  83. {
  84. NTSTATUS ntStatus;
  85. DEBUGMSG( DBG_FUNC,("+IrUsb_AddDevice()\n"));
  86. *DeviceExt = NULL;
  87. ntStatus = IrUsb_CreateDeviceExt( DeviceExt );
  88. DEBUGMSG( DBG_FUNC,("-IrUsb_AddDevice() (%x)\n", ntStatus));
  89. return ntStatus;
  90. }
  91. /*****************************************************************************
  92. *
  93. * Function: IrUsb_GetDongleCaps
  94. *
  95. * Synopsis: We need to manually set the data in the class specific descriptor, since
  96. * our device does not support the automatic-read feature
  97. *
  98. * Arguments: pThisDev - pointer to IR device
  99. *
  100. * Returns: STATUS_SUCCESS if successful
  101. * STATUS_UNSUCCESSFUL otherwise
  102. *
  103. * Notes:
  104. *
  105. *****************************************************************************/
  106. NTSTATUS
  107. IrUsb_GetDongleCaps(
  108. IN OUT PIR_DEVICE pThisDev
  109. )
  110. {
  111. IRUSB_CLASS_SPECIFIC_DESCRIPTOR *pDesc = &(pThisDev->ClassDesc);
  112. NTSTATUS ntStatus = STATUS_SUCCESS;
  113. NDIS_HANDLE ConfigurationHandle;
  114. //
  115. // Make sure the cose is only executed at init time
  116. //
  117. if( pDesc->ClassConfigured )
  118. {
  119. return STATUS_SUCCESS;
  120. }
  121. pDesc->ClassConfigured = TRUE;
  122. //
  123. // Some is hardwired, some are read from the registry
  124. //
  125. NdisOpenConfiguration(
  126. &ntStatus,
  127. &ConfigurationHandle,
  128. pThisDev->WrapperConfigurationContext
  129. );
  130. //
  131. // Turnaroud time (read from the registry)
  132. //
  133. if( NT_SUCCESS(ntStatus) )
  134. {
  135. NDIS_STRING Keyword = NDIS_STRING_CONST("MinTurnTime");
  136. PNDIS_CONFIGURATION_PARAMETER pParameterValue;
  137. NdisReadConfiguration(
  138. &ntStatus,
  139. &pParameterValue,
  140. ConfigurationHandle,
  141. &Keyword,
  142. NdisParameterInteger
  143. );
  144. if( NT_SUCCESS(ntStatus) )
  145. {
  146. switch( pParameterValue->ParameterData.IntegerData )
  147. {
  148. case 500:
  149. pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_0p5ms;
  150. break;
  151. case 1000:
  152. pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_1ms;
  153. break;
  154. case 5000:
  155. pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_5ms;
  156. break;
  157. case 10000:
  158. pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_10ms;
  159. break;
  160. default:
  161. pDesc->bmMinTurnaroundTime = BM_TURNAROUND_TIME_0ms;
  162. break;
  163. }
  164. }
  165. //
  166. // Speed mask (read from the registry)
  167. //
  168. if( NT_SUCCESS(ntStatus) )
  169. {
  170. NDIS_STRING Keyword = NDIS_STRING_CONST("SpeedEnable");
  171. PNDIS_CONFIGURATION_PARAMETER pParameterValue;
  172. NdisReadConfiguration(
  173. &ntStatus,
  174. &pParameterValue,
  175. ConfigurationHandle,
  176. &Keyword,
  177. NdisParameterInteger
  178. );
  179. if( NT_SUCCESS(ntStatus) )
  180. {
  181. switch( pParameterValue->ParameterData.IntegerData )
  182. {
  183. case SPEED_2400:
  184. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_2400;
  185. break;
  186. case SPEED_9600:
  187. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_9600;
  188. break;
  189. case SPEED_19200:
  190. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_19200;
  191. break;
  192. case SPEED_38400:
  193. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_38400;
  194. break;
  195. case SPEED_57600:
  196. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_57600;
  197. break;
  198. case SPEED_115200:
  199. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_115200;
  200. break;
  201. case SPEED_576000:
  202. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_576K;
  203. break;
  204. case SPEED_1152000:
  205. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_1152K;
  206. break;
  207. case SPEED_4000000:
  208. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_4M;
  209. break;
  210. default:
  211. pThisDev->BaudRateMask = NDIS_IRDA_SPEED_MASK_4M;
  212. break;
  213. }
  214. }
  215. }
  216. //
  217. // Read the tranceiver type
  218. //
  219. if( NT_SUCCESS(ntStatus) )
  220. {
  221. NDIS_STRING Keyword = NDIS_STRING_CONST("TransceiverType");
  222. PNDIS_CONFIGURATION_PARAMETER pParameterValue;
  223. NdisReadConfiguration(
  224. &ntStatus,
  225. &pParameterValue,
  226. ConfigurationHandle,
  227. &Keyword,
  228. NdisParameterInteger
  229. );
  230. if( NT_SUCCESS(ntStatus) )
  231. {
  232. switch( pParameterValue->ParameterData.IntegerData )
  233. {
  234. case TRANSCEIVER_INFINEON:
  235. pThisDev->TransceiverType = TRANSCEIVER_INFINEON;
  236. break;
  237. case TRANSCEIVER_VISHAY:
  238. pThisDev->TransceiverType = TRANSCEIVER_VISHAY;
  239. break;
  240. case TRANSCEIVER_4000:
  241. pThisDev->TransceiverType = TRANSCEIVER_4000;
  242. break;
  243. case TRANSCEIVER_4012:
  244. default:
  245. pThisDev->TransceiverType = TRANSCEIVER_4012;
  246. break;
  247. }
  248. }
  249. else
  250. {
  251. //
  252. // Force a default anyway
  253. //
  254. pThisDev->TransceiverType = TRANSCEIVER_4012;
  255. ntStatus = STATUS_SUCCESS;
  256. }
  257. }
  258. //
  259. // And the receive window
  260. //
  261. if( NT_SUCCESS(ntStatus) )
  262. {
  263. if( pThisDev->ChipRevision == CHIP_REVISION_7 )
  264. {
  265. NDIS_STRING Keyword = NDIS_STRING_CONST("ReceiveWindow");
  266. PNDIS_CONFIGURATION_PARAMETER pParameterValue;
  267. NdisReadConfiguration(
  268. &ntStatus,
  269. &pParameterValue,
  270. ConfigurationHandle,
  271. &Keyword,
  272. NdisParameterInteger
  273. );
  274. if( NT_SUCCESS(ntStatus) )
  275. {
  276. switch( pParameterValue->ParameterData.IntegerData )
  277. {
  278. case 2:
  279. pDesc->bmWindowSize = BM_WINDOW_SIZE_2;
  280. break;
  281. case 1:
  282. default:
  283. pDesc->bmWindowSize = BM_WINDOW_SIZE_1;
  284. break;
  285. }
  286. }
  287. else
  288. {
  289. //
  290. // Force a default anyway
  291. //
  292. pDesc->bmWindowSize = BM_WINDOW_SIZE_1;
  293. ntStatus = STATUS_SUCCESS;
  294. }
  295. }
  296. #if defined(SUPPORT_LA8) && !defined(LEGACY_NDIS5)
  297. else if( pThisDev->ChipRevision == CHIP_REVISION_8 )
  298. {
  299. pDesc->bmWindowSize = BM_WINDOW_SIZE_2;
  300. }
  301. #endif
  302. else
  303. {
  304. pDesc->bmWindowSize = BM_WINDOW_SIZE_1;
  305. }
  306. }
  307. //
  308. // temporary stuff Fix!
  309. //
  310. /*if( NT_SUCCESS(ntStatus) )
  311. {
  312. NDIS_STRING Keyword = NDIS_STRING_CONST("SirDpll");
  313. PNDIS_CONFIGURATION_PARAMETER pParameterValue;
  314. NTSTATUS DumStatus;
  315. NdisReadConfiguration(
  316. &DumStatus,
  317. &pParameterValue,
  318. ConfigurationHandle,
  319. &Keyword,
  320. NdisParameterInteger
  321. );
  322. pThisDev->SirDpll = pParameterValue->ParameterData.IntegerData;
  323. }
  324. if( NT_SUCCESS(ntStatus) )
  325. {
  326. NDIS_STRING Keyword = NDIS_STRING_CONST("FirDpll");
  327. PNDIS_CONFIGURATION_PARAMETER pParameterValue;
  328. NTSTATUS DumStatus;
  329. NdisReadConfiguration(
  330. &DumStatus,
  331. &pParameterValue,
  332. ConfigurationHandle,
  333. &Keyword,
  334. NdisParameterInteger
  335. );
  336. pThisDev->FirDpll = pParameterValue->ParameterData.IntegerData;
  337. }
  338. if( NT_SUCCESS(ntStatus) )
  339. {
  340. NDIS_STRING Keyword = NDIS_STRING_CONST("SirSensitivity");
  341. PNDIS_CONFIGURATION_PARAMETER pParameterValue;
  342. NTSTATUS DumStatus;
  343. NdisReadConfiguration(
  344. &DumStatus,
  345. &pParameterValue,
  346. ConfigurationHandle,
  347. &Keyword,
  348. NdisParameterInteger
  349. );
  350. pThisDev->SirSensitivity = pParameterValue->ParameterData.IntegerData;
  351. }
  352. if( NT_SUCCESS(ntStatus) )
  353. {
  354. NDIS_STRING Keyword = NDIS_STRING_CONST("FirSensitivity");
  355. PNDIS_CONFIGURATION_PARAMETER pParameterValue;
  356. NTSTATUS DumStatus;
  357. NdisReadConfiguration(
  358. &DumStatus,
  359. &pParameterValue,
  360. ConfigurationHandle,
  361. &Keyword,
  362. NdisParameterInteger
  363. );
  364. pThisDev->FirSensitivity = pParameterValue->ParameterData.IntegerData;
  365. }*/
  366. NdisCloseConfiguration( ConfigurationHandle );
  367. }
  368. if( NT_SUCCESS(ntStatus) )
  369. {
  370. // Maximum data size
  371. pDesc->bmDataSize = BM_DATA_SIZE_2048;
  372. // Speed
  373. pDesc->wBaudRate = NDIS_IRDA_SPEED_MASK_4M;
  374. #if defined(WORKAROUND_BROKEN_MIR)
  375. pDesc->wBaudRate &= (~NDIS_IRDA_SPEED_1152K & ~NDIS_IRDA_SPEED_576K);
  376. #endif
  377. // Extra BOFs
  378. pDesc->bmExtraBofs = BM_EXTRA_BOFS_24;
  379. }
  380. return ntStatus;
  381. }
  382. /*****************************************************************************
  383. *
  384. * Function: IrUsb_SetDongleCaps
  385. *
  386. * Synopsis: Set the DONGLE_CAPABILITIES struct in our device from the information
  387. * we have already gotten from the USB Class-Specific descriptor.
  388. * Some data items are usable directly as formatted in the Class-Specific descriptor,
  389. * but some need to be translated to a different format for OID_xxx use;
  390. * The donglecaps struct is thus used to hold the info in a form
  391. * usable directly by OID_xxx 's.
  392. *
  393. * Arguments: pThisDev - pointer to IR device
  394. *
  395. * Returns: None
  396. *
  397. * Notes:
  398. *
  399. *****************************************************************************/
  400. VOID
  401. IrUsb_SetDongleCaps(
  402. IN OUT PIR_DEVICE pThisDev
  403. )
  404. {
  405. DONGLE_CAPABILITIES *pCaps = &(pThisDev->dongleCaps);
  406. IRUSB_CLASS_SPECIFIC_DESCRIPTOR *pDesc = &(pThisDev->ClassDesc);
  407. DEBUGMSG( DBG_FUNC,("+IrUsb_SetDongleCaps\n"));
  408. DEBUGMSG( DBG_FUNC, (" IrUsb_SetDongleCaps() RAW ClassDesc BUFFER:\n"));
  409. IRUSB_DUMP( DBG_FUNC,( (PUCHAR) pDesc, 12 ) );
  410. //
  411. // Deal with the turnaround time
  412. //
  413. switch( pDesc->bmMinTurnaroundTime )
  414. {
  415. case BM_TURNAROUND_TIME_0ms:
  416. pCaps->turnAroundTime_usec = 0;
  417. break;
  418. case BM_TURNAROUND_TIME_0p01ms:
  419. pCaps->turnAroundTime_usec = 10; //device tells us millisec; we store as microsec
  420. break;
  421. case BM_TURNAROUND_TIME_0p05ms:
  422. pCaps->turnAroundTime_usec = 50;
  423. break;
  424. case BM_TURNAROUND_TIME_0p1ms:
  425. pCaps->turnAroundTime_usec = 100;
  426. break;
  427. case BM_TURNAROUND_TIME_0p5ms:
  428. pCaps->turnAroundTime_usec = 500;
  429. break;
  430. case BM_TURNAROUND_TIME_1ms:
  431. pCaps->turnAroundTime_usec = 1000;
  432. break;
  433. case BM_TURNAROUND_TIME_5ms:
  434. pCaps->turnAroundTime_usec = 5000;
  435. break;
  436. case BM_TURNAROUND_TIME_10ms:
  437. pCaps->turnAroundTime_usec = 10000;
  438. break;
  439. default:
  440. IRUSB_ASSERT( 0 ); // we should have covered all the cases here
  441. pCaps->turnAroundTime_usec = 1000;
  442. }
  443. //
  444. // We probably support many window sizes and will have multiple of these bits set;
  445. // Just save the biggest we support for now to tell ndis
  446. //
  447. if( pDesc->bmWindowSize & BM_WINDOW_SIZE_7 )
  448. pCaps->windowSize = 7;
  449. else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_6 )
  450. pCaps->windowSize = 6;
  451. else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_5 )
  452. pCaps->windowSize = 5;
  453. else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_4 )
  454. pCaps->windowSize = 4;
  455. else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_3 )
  456. pCaps->windowSize = 3;
  457. else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_2 )
  458. pCaps->windowSize = 2;
  459. else if( pDesc->bmWindowSize & BM_WINDOW_SIZE_1 )
  460. pCaps->windowSize = 1;
  461. else
  462. {
  463. IRUSB_ASSERT( 0 ); // we should have covered all the cases here
  464. pCaps->windowSize = 1;
  465. }
  466. //
  467. // Extra BOFS
  468. //
  469. switch( (USHORT)pDesc->bmExtraBofs )
  470. {
  471. case BM_EXTRA_BOFS_0:
  472. pCaps->extraBOFS = 0;
  473. break;
  474. case BM_EXTRA_BOFS_1:
  475. pCaps->extraBOFS = 1;
  476. break;
  477. case BM_EXTRA_BOFS_2:
  478. pCaps->extraBOFS = 2;
  479. break;
  480. case BM_EXTRA_BOFS_3:
  481. pCaps->extraBOFS = 3;
  482. break;
  483. case BM_EXTRA_BOFS_6:
  484. pCaps->extraBOFS = 6;
  485. break;
  486. case BM_EXTRA_BOFS_12:
  487. pCaps->extraBOFS = 12;
  488. break;
  489. case BM_EXTRA_BOFS_24:
  490. pCaps->extraBOFS = 24;
  491. break;
  492. case BM_EXTRA_BOFS_48:
  493. pCaps->extraBOFS = 48;
  494. break;
  495. default:
  496. IRUSB_ASSERT( 0 ); // we should have covered all the cases here
  497. pCaps->extraBOFS = 0;
  498. }
  499. //
  500. // We probably support many data sizes and will have multiple of these bits set;
  501. // Just save biggest we support for now to tell ndis
  502. //
  503. if( pDesc->bmDataSize & BM_DATA_SIZE_2048 )
  504. pCaps->dataSize = 2048;
  505. else if( pDesc->bmDataSize & BM_DATA_SIZE_1024 )
  506. pCaps->dataSize = 1024;
  507. else if( pDesc->bmDataSize & BM_DATA_SIZE_512 )
  508. pCaps->dataSize = 512;
  509. else if( pDesc->bmDataSize & BM_DATA_SIZE_256 )
  510. pCaps->dataSize = 256;
  511. else if( pDesc->bmDataSize & BM_DATA_SIZE_128 )
  512. pCaps->dataSize = 128;
  513. else if( pDesc->bmDataSize & BM_DATA_SIZE_64 )
  514. pCaps->dataSize = 64;
  515. else
  516. {
  517. IRUSB_ASSERT( 0 ); // we should have covered all the cases here
  518. pCaps->dataSize = 2048;
  519. }
  520. pDesc->wBaudRate &= pThisDev->BaudRateMask; // mask defaults to 0xffff; may be set in registry
  521. //
  522. // max frame size is 2051; max irda dataSize should be 2048
  523. //
  524. IRUSB_ASSERT( MAX_TOTAL_SIZE_WITH_ALL_HEADERS > pCaps->dataSize);
  525. DEBUGMSG( DBG_FUNC,(" IrUsb_SetDongleCaps pCaps->turnAroundTime_usec = dec %d\n",pCaps->turnAroundTime_usec));
  526. DEBUGMSG( DBG_FUNC,(" extraBOFS = dec %d\n",pCaps->extraBOFS));
  527. DEBUGMSG( DBG_FUNC,(" dataSize = dec %d\n",pCaps->dataSize));
  528. DEBUGMSG( DBG_FUNC,(" windowSize = dec %d\n",pCaps->windowSize));
  529. DEBUGMSG( DBG_FUNC,(" MAX_TOTAL_SIZE_WITH_ALL_HEADERS == dec %d\n",MAX_TOTAL_SIZE_WITH_ALL_HEADERS));
  530. DEBUGMSG( DBG_FUNC,(" pDesc->bmDataSize = 0x%02x\n",pDesc->bmDataSize));
  531. DEBUGMSG( DBG_FUNC,(" pDesc->bmWindowSize = 0x%02x\n",pDesc->bmWindowSize));
  532. DEBUGMSG( DBG_FUNC,(" pDesc->bmMinTurnaroundTime = 0x%02x\n",pDesc->bmMinTurnaroundTime));
  533. DEBUGMSG( DBG_FUNC,(" pDesc->wBaudRate = 0x%04x\n",pDesc->wBaudRate));
  534. DEBUGMSG( DBG_FUNC,(" pDesc->bmExtraBofs = 0x%02x\n",pDesc->bmExtraBofs));
  535. DEBUGMSG( DBG_FUNC,("-IrUsb_SetDongleCaps\n"));
  536. }