Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1606 lines
42 KiB

  1. /**************************************************************************************************************************
  2. * IRUSB.C SigmaTel STIR4200 main module (contains main NDIS entry points)
  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: 05/24/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: 10/13/2000
  26. * Version 1.11
  27. * Edited: 11/13/2000
  28. * Version 1.12
  29. * Edited: 12/29/2000
  30. * Version 1.13
  31. *
  32. *
  33. **************************************************************************************************************************/
  34. #define DOBREAKS // enable debug breaks
  35. #include <ndis.h>
  36. #include <ntddndis.h> // defines OID's
  37. #include <usbdi.h>
  38. #include <usbdlib.h>
  39. #include "debug.h"
  40. #include "ircommon.h"
  41. #include "irusb.h"
  42. #include "irndis.h"
  43. #include "diags.h"
  44. #include "stirioctl.h"
  45. //
  46. // Diagnostic global variables
  47. //
  48. #ifndef WIN9X
  49. //#if defined(DIAGS)
  50. NDIS_HANDLE hSavedWrapper;
  51. PIR_DEVICE pGlobalDev;
  52. //#endif
  53. #endif
  54. //
  55. // Mark the DriverEntry function to run once during initialization.
  56. //
  57. NDIS_STATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath );
  58. #pragma NDIS_INIT_FUNCTION( DriverEntry )
  59. /*****************************************************************************
  60. *
  61. * Function: DriverEntry
  62. *
  63. * Synopsis: register driver entry functions with NDIS
  64. *
  65. * Arguments: DriverObject - the driver object being initialized
  66. * RegistryPath - registry path of the driver
  67. *
  68. * Returns: value returned by NdisMRegisterMiniport
  69. *
  70. * Algorithm:
  71. *
  72. *
  73. * Notes:
  74. *
  75. * This routine runs at IRQL PASSIVE_LEVEL.
  76. *
  77. *****************************************************************************/
  78. NDIS_STATUS
  79. DriverEntry(
  80. IN PDRIVER_OBJECT pDriverObject,
  81. IN PUNICODE_STRING pRegistryPath
  82. )
  83. {
  84. NDIS_STATUS status = NDIS_STATUS_SUCCESS;
  85. NDIS50_MINIPORT_CHARACTERISTICS characteristics;
  86. NDIS_HANDLE hWrapper;
  87. DEBUGMSG(DBG_FUNC, ("+DriverEntry(IrUsb)\n"));
  88. DEBUGMSG( DBG_FUNC ,(" Entering IRUSB DriverEntry(), pRegistryPath=\n %ws\n", pRegistryPath->Buffer ));
  89. NdisMInitializeWrapper(
  90. &hWrapper,
  91. pDriverObject,
  92. pRegistryPath,
  93. NULL
  94. );
  95. #ifndef WIN9X
  96. //#if defined(DIAGS)
  97. hSavedWrapper = hWrapper;
  98. //#endif
  99. #endif
  100. DEBUGMSG(DBG_FUNC, (" DriverEntry(IrUsb) called NdisMInitializeWrapper()\n"));
  101. NdisZeroMemory(
  102. &characteristics,
  103. sizeof(NDIS50_MINIPORT_CHARACTERISTICS)
  104. );
  105. characteristics.MajorNdisVersion = (UCHAR)NDIS_MAJOR_VERSION;
  106. characteristics.MinorNdisVersion = (UCHAR)NDIS_MINOR_VERSION;
  107. characteristics.Reserved = 0;
  108. characteristics.HaltHandler = StIrUsbHalt;
  109. characteristics.InitializeHandler = StIrUsbInitialize;
  110. characteristics.QueryInformationHandler = StIrUsbQueryInformation;
  111. characteristics.SetInformationHandler = StIrUsbSetInformation;
  112. characteristics.ResetHandler = StIrUsbReset;
  113. //
  114. // For now we will allow NDIS to send only one packet at a time.
  115. //
  116. characteristics.SendHandler = StIrUsbSend;
  117. characteristics.SendPacketsHandler = StIrUsbSendPackets;
  118. //
  119. // We don't use NdisMIndicateXxxReceive function, so we will
  120. // need a ReturnPacketHandler to retrieve our packet resources.
  121. //
  122. characteristics.ReturnPacketHandler = StIrUsbReturnPacket;
  123. characteristics.TransferDataHandler = NULL;
  124. //
  125. // NDIS never calls the ReconfigureHandler.
  126. //
  127. characteristics.ReconfigureHandler = NULL;
  128. // MS Security bug #540168 - remove unused CheckForHangHandler
  129. characteristics.CheckForHangHandler = NULL;
  130. //
  131. // This miniport driver does not handle interrupts.
  132. //
  133. characteristics.HandleInterruptHandler = NULL;
  134. characteristics.ISRHandler = NULL;
  135. characteristics.DisableInterruptHandler = NULL;
  136. characteristics.EnableInterruptHandler = NULL;
  137. //
  138. // This miniport does not control a busmaster DMA with
  139. // NdisMAllocateShareMemoryAsysnc, AllocateCompleteHandler won't be
  140. // called from NDIS.
  141. //
  142. characteristics.AllocateCompleteHandler = NULL;
  143. DEBUGMSG(DBG_FUNC, (" DriverEntry(IrUsb) initted locks and events\n"));
  144. DEBUGMSG(DBG_FUNC, (" DriverEntry(IrUsb) about to NdisMRegisterMiniport()\n"));
  145. status = NdisMRegisterMiniport(
  146. hWrapper,
  147. &characteristics,
  148. sizeof(NDIS50_MINIPORT_CHARACTERISTICS)
  149. );
  150. DEBUGMSG(DBG_FUNC, (" DriverEntry(IrUsb) after NdisMRegisterMiniport() status 0x%x\n", status));
  151. DEBUGMSG(DBG_WARN, ("-DriverEntry(IrUsb) status = 0x%x\n", status));
  152. return status;
  153. }
  154. /*****************************************************************************
  155. *
  156. * Function: StIrUsbInitialize
  157. *
  158. * Synopsis: Initializes the device (usbd.sys) and allocates all resources
  159. * required to carry out 'network' io operations.
  160. *
  161. * Arguments: OpenErrorStatus - allows StIrUsbInitialize to return additional
  162. * status code NDIS_STATUS_xxx if returning
  163. * NDIS_STATUS_OPEN_FAILED
  164. * SelectedMediumIndex - specifies to NDIS the medium type the
  165. * driver uses
  166. * MediumArray - array of NdisMediumXXX the driver can choose
  167. * MediumArraySize
  168. * MiniportAdapterHandle - handle identifying miniport's NIC
  169. * WrapperConfigurationContext - used with Ndis config and init
  170. * routines
  171. *
  172. * Returns: NDIS_STATUS_SUCCESS if properly configure and resources allocated
  173. * NDIS_STATUS_FAILURE, otherwise
  174. *
  175. * more specific failures:
  176. * NDIS_STATUS_UNSUPPORTED_MEDIA - driver can't support any medium
  177. * NDIS_STATUS_ADAPTER_NOT_FOUND - NdisOpenConfiguration or
  178. * NdisReadConfiguration failed
  179. * NDIS_STATUS_OPEN_FAILED - failed to open serial.sys
  180. * NDIS_STATUS_NOT_ACCEPTED - serial.sys does not accept the
  181. * configuration
  182. * NDIS_STATUS_RESOURCES - could not claim sufficient
  183. * resources
  184. *
  185. *
  186. * Notes: NDIS will not submit requests until this is complete.
  187. *
  188. * This routine runs at IRQL PASSIVE_LEVEL.
  189. *
  190. *****************************************************************************/
  191. NDIS_STATUS
  192. StIrUsbInitialize(
  193. OUT PNDIS_STATUS OpenErrorStatus,
  194. OUT PUINT SelectedMediumIndex,
  195. IN PNDIS_MEDIUM MediumArray,
  196. IN UINT MediumArraySize,
  197. IN NDIS_HANDLE NdisAdapterHandle,
  198. IN NDIS_HANDLE WrapperConfigurationContext
  199. )
  200. {
  201. UINT i;
  202. PIR_DEVICE pThisDev = NULL;
  203. NDIS_STATUS status = NDIS_STATUS_SUCCESS;
  204. NTSTATUS ntStatus = STATUS_SUCCESS;
  205. PDEVICE_OBJECT pPhysicalDeviceObject = NULL;
  206. PDEVICE_OBJECT pNextDeviceObject = NULL;
  207. #ifndef WIN9X
  208. //#if defined(DIAGS)
  209. UNICODE_STRING SymbolicLinkName;
  210. UNICODE_STRING DeviceName;
  211. PDEVICE_OBJECT pDeviceObject;
  212. PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1];
  213. //#endif
  214. #endif
  215. DEBUGMSG(DBG_WARN, ("+StIrUsbInitialize\n"));
  216. //
  217. // Search for the irda medium in the medium array.
  218. //
  219. for( i = 0; i < MediumArraySize; i++ )
  220. {
  221. if( MediumArray[i] == NdisMediumIrda )
  222. {
  223. break;
  224. }
  225. }
  226. if( i < MediumArraySize )
  227. {
  228. *SelectedMediumIndex = i;
  229. }
  230. else
  231. {
  232. //
  233. // Irda medium not found.
  234. //
  235. DEBUGMSG(DBG_ERROR, (" Failure: NdisMediumIrda not found!\n"));
  236. status = NDIS_STATUS_UNSUPPORTED_MEDIA;
  237. //
  238. // Log the error
  239. //
  240. NdisWriteErrorLogEntry(
  241. NdisAdapterHandle,
  242. NDIS_STATUS_UNSUPPORTED_MEDIA,
  243. 1,
  244. status
  245. );
  246. goto done;
  247. }
  248. //
  249. // This will connect to a specific bus
  250. //
  251. NdisMGetDeviceProperty(
  252. NdisAdapterHandle,
  253. &pPhysicalDeviceObject,
  254. NULL,
  255. &pNextDeviceObject,
  256. NULL,
  257. NULL
  258. );
  259. IRUSB_ASSERT( pPhysicalDeviceObject );
  260. IRUSB_ASSERT( pNextDeviceObject );
  261. DEBUGMSG(
  262. DBG_OUT,
  263. ("NdisMGetDeviceProperty PDO 0x%x,Next DO 0x%x\n",
  264. pPhysicalDeviceObject, pNextDeviceObject)
  265. );
  266. //
  267. // Allocate a functional device object.
  268. //
  269. ntStatus = IrUsb_AddDevice( &pThisDev );
  270. IRUSB_ASSERT( pThisDev );
  271. if( (ntStatus != STATUS_SUCCESS) || (pThisDev == NULL) )
  272. {
  273. //
  274. // Log the error
  275. //
  276. NdisWriteErrorLogEntry(
  277. NdisAdapterHandle,
  278. NDIS_STATUS_RESOURCES,
  279. 1,
  280. ntStatus
  281. );
  282. DEBUGMSG(DBG_ERROR, (" IrUsb_AddDevice() FAILED.\n"));
  283. status = NDIS_STATUS_RESOURCES;
  284. goto done;
  285. }
  286. pThisDev->pUsbDevObj = pNextDeviceObject;
  287. pThisDev->pPhysDevObj = pPhysicalDeviceObject;
  288. //
  289. // Initialize device object and resources.
  290. // All the queues and buffer/packets etc. are allocated here.
  291. //
  292. status = InitializeDevice( pThisDev );
  293. if( status != NDIS_STATUS_SUCCESS )
  294. {
  295. //
  296. // Log the error
  297. //
  298. NdisWriteErrorLogEntry(
  299. NdisAdapterHandle,
  300. NDIS_STATUS_RESOURCES,
  301. 1,
  302. status
  303. );
  304. DEBUGMSG(DBG_ERROR, (" InitializeDevice failed. Returned 0x%.8x\n", status));
  305. status = NDIS_STATUS_RESOURCES;
  306. goto done;
  307. }
  308. //
  309. // Record the NdisAdapterHandle.
  310. //
  311. pThisDev->hNdisAdapter = NdisAdapterHandle;
  312. //
  313. // NdisMSetAttributes will associate our adapter handle with the wrapper's
  314. // adapter handle. The wrapper will then always use our handle
  315. // when calling us. We use a pointer to the device object as the context.
  316. //
  317. NdisMSetAttributesEx(
  318. NdisAdapterHandle,
  319. (NDIS_HANDLE)pThisDev,
  320. 0,
  321. NDIS_ATTRIBUTE_DESERIALIZE,
  322. NdisInterfaceInternal
  323. );
  324. //
  325. // Now we're ready to do our own startup processing.
  326. // USB client drivers such as us set up URBs (USB Request Packets) to send requests
  327. // to the host controller driver (HCD). The URB structure defines a format for all
  328. // possible commands that can be sent to a USB device.
  329. // Here, we request the device descriptor and store it,
  330. // and configure the device.
  331. // In USB, no special HW processing is required to 'open' or 'close' the pipes
  332. //
  333. pThisDev->WrapperConfigurationContext = WrapperConfigurationContext;
  334. ntStatus = IrUsb_StartDevice( pThisDev );
  335. if( ntStatus != STATUS_SUCCESS )
  336. {
  337. //
  338. // Log the error
  339. //
  340. NdisWriteErrorLogEntry(
  341. pThisDev->hNdisAdapter,
  342. NDIS_STATUS_ADAPTER_NOT_FOUND,
  343. 1,
  344. ntStatus
  345. );
  346. DEBUGMSG(DBG_ERROR, (" IrUsb_StartDevice FAILED. Returned 0x%.8x\n", ntStatus));
  347. status = NDIS_STATUS_ADAPTER_NOT_FOUND;
  348. goto done;
  349. }
  350. //
  351. // Create an irp and begin our receives.
  352. // NOTE: All other receive processing will be done in the read completion
  353. // routine and PollingThread started therein.
  354. //
  355. status = InitializeProcessing( pThisDev, TRUE );
  356. if( status != NDIS_STATUS_SUCCESS )
  357. {
  358. //
  359. // Log the error
  360. //
  361. NdisWriteErrorLogEntry(
  362. pThisDev->hNdisAdapter,
  363. NDIS_STATUS_RESOURCES,
  364. 1,
  365. status
  366. );
  367. DEBUGMSG(DBG_ERROR, (" InitializeProcessing failed. Returned 0x%.8x\n", status));
  368. status = NDIS_STATUS_RESOURCES;
  369. goto done;
  370. }
  371. //
  372. // Initialize the diagnostic portion.
  373. // Also supports the CustomerData ioctl.
  374. //
  375. #ifndef WIN9X
  376. //#if defined(DIAGS)
  377. NdisZeroMemory( MajorFunction, sizeof(PDRIVER_DISPATCH)*(IRP_MJ_MAXIMUM_FUNCTION+1) );
  378. RtlInitUnicodeString( &SymbolicLinkName, L"\\DosDevices\\Stirusb" );
  379. RtlInitUnicodeString( &DeviceName, L"\\Device\\Stirusb" );
  380. MajorFunction[IRP_MJ_CREATE] = StIrUsbCreate;
  381. MajorFunction[IRP_MJ_CLOSE] = StIrUsbClose;
  382. MajorFunction[IRP_MJ_DEVICE_CONTROL] = StIrUsbDispatch;
  383. NdisMRegisterDevice(
  384. hSavedWrapper,
  385. &DeviceName,
  386. &SymbolicLinkName,
  387. MajorFunction,
  388. &pDeviceObject,
  389. &pThisDev->NdisDeviceHandle
  390. );
  391. pGlobalDev = pThisDev;
  392. //#endif
  393. #endif
  394. done:
  395. if( status != NDIS_STATUS_SUCCESS )
  396. {
  397. if( pThisDev != NULL )
  398. {
  399. DeinitializeDevice( pThisDev );
  400. FreeDevice( pThisDev );
  401. }
  402. }
  403. if( status!=NDIS_STATUS_SUCCESS )
  404. {
  405. DEBUGMSG(DBG_ERR, (" IrUsb: StIrUsbInitialize failed %x\n", status));
  406. }
  407. else
  408. {
  409. DEBUGMSG(DBG_ERR, (" IrUsb: StIrUsbInitialize SUCCESS %x\n", status));
  410. }
  411. DEBUGMSG(DBG_FUNC, ("-StIrUsbInitialize\n"));
  412. return status;
  413. }
  414. /*****************************************************************************
  415. *
  416. * Function: StIrUsbHalt
  417. *
  418. * Synopsis: Deallocates resources when the NIC is removed and halts the
  419. * device.
  420. *
  421. * Arguments: Context - pointer to the ir device object
  422. *
  423. * Returns: None
  424. *
  425. * Algorithm: Mirror image of StIrUsbInitialize...undoes everything initialize
  426. * did.
  427. * Notes:
  428. *
  429. * This routine runs at IRQL PASSIVE_LEVEL.
  430. *
  431. * BUGBUG: Could StIrUsbReset fail and then StIrUsbHalt be called. If so, we need
  432. * to chech validity of all the pointers, etc. before trying to
  433. * deallocate.
  434. *
  435. *****************************************************************************/
  436. VOID
  437. StIrUsbHalt(
  438. IN NDIS_HANDLE Context
  439. )
  440. {
  441. PIR_DEVICE pThisDev;
  442. NTSTATUS ntstatus;
  443. DEBUGMSG(DBG_WARN, ("+StIrUsbHalt\n")); // change to FUNC later?
  444. pThisDev = CONTEXT_TO_DEV( Context );
  445. //
  446. // MS Security bug #540137
  447. // Note: fPendingHalt is checked by the polling thread to see if we are shutting down,
  448. // so there is a need for this variable. The following check to see if halt is
  449. // is called more than once has been changed to DBG only.
  450. //
  451. #if DBG
  452. if( TRUE == pThisDev->fPendingHalt )
  453. {
  454. DEBUGMSG(DBG_ERR, (" StIrUsbHalt called with halt already pending\n"));
  455. IRUSB_ASSERT( 0 );
  456. goto done;
  457. }
  458. #endif
  459. //
  460. // Let the send completion and receive completion routine know that there
  461. // is a pending reset.
  462. //
  463. pThisDev->fPendingHalt = TRUE;
  464. IrUsb_CommonShutdown( pThisDev, TRUE ); //shutdown logic common to halt and reset; see below
  465. //
  466. // We had better not have left any pending read, write, or control IRPS hanging out there!
  467. //
  468. IRUSB_ASSERT( 0 == pThisDev->PendingIrpCount );
  469. if ( 0 != pThisDev->PendingIrpCount )
  470. {
  471. DEBUGMSG(DBG_ERR, (" StIrUsbHalt WE LEFT %d PENDING IRPS!!!!!\n", pThisDev->PendingIrpCount));
  472. }
  473. IRUSB_ASSERT( FALSE == pThisDev->fSetpending );
  474. IRUSB_ASSERT( FALSE == pThisDev->fQuerypending );
  475. //
  476. // Destroy diags
  477. //
  478. #ifndef WIN9X
  479. //#if defined(DIAGS)
  480. NdisMDeregisterDevice( pThisDev->NdisDeviceHandle );
  481. //#endif
  482. #endif
  483. //
  484. // Free our own IR device object.
  485. //
  486. FreeDevice( pThisDev );
  487. #if DBG
  488. done:
  489. #endif
  490. DEBUGMSG(DBG_ERR, (" StIrUsbHalt HALT complete\n"));
  491. DEBUGMSG(DBG_WARN, ("-StIrUsbHalt\n")); // change to FUNC later?
  492. }
  493. /*****************************************************************************
  494. *
  495. * Function: IrUsb_CommonShutdown
  496. *
  497. * Synopsis: Deallocates resources when the NIC is removed and halts the
  498. * device. This is stuff common to IrUsbHalt and IrUsbReset and is called by both
  499. *
  500. * Arguments: pThisDev - pointer to IR device
  501. * KillPassiveThread - determines whether we need to kill the passive thread
  502. *
  503. * Returns: None
  504. *
  505. * Algorithm: Mirror image of IrUsbInitialize...undoes everything initialize
  506. * did.
  507. *
  508. * Notes:
  509. *
  510. * This routine runs at IRQL PASSIVE_LEVEL.
  511. *
  512. *
  513. *****************************************************************************/
  514. VOID
  515. IrUsb_CommonShutdown(
  516. IN OUT PIR_DEVICE pThisDev,
  517. BOOLEAN KillPassiveThread
  518. )
  519. {
  520. DEBUGMSG(DBG_WARN, ("+IrUsb_CommonShutdown\n")); //chg to FUNC later?
  521. //
  522. // Stop processing and sleep 50 milliseconds.
  523. //
  524. InterlockedExchange( (PLONG)&pThisDev->fProcessing, FALSE );
  525. NdisMSleep( 50000 );
  526. //
  527. // Kill the passive thread
  528. //
  529. if( KillPassiveThread )
  530. {
  531. DEBUGMSG(DBG_WARN, (" IrUsb_CommonShutdown About to Kill PassiveLevelThread\n"));
  532. pThisDev->fKillPassiveLevelThread = TRUE;
  533. KeSetEvent(&pThisDev->EventPassiveThread, 0, FALSE);
  534. while( pThisDev->hPassiveThread != NULL )
  535. {
  536. //
  537. // Sleep 50 milliseconds.
  538. //
  539. NdisMSleep( 50000 );
  540. }
  541. DEBUGMSG(DBG_WARN, (" passive thread killed\n"));
  542. }
  543. //
  544. // Kill the polling thread
  545. //
  546. DEBUGMSG(DBG_WARN, (" IrUsb_CommonShutdown About to kill Polling thread\n"));
  547. pThisDev->fKillPollingThread = TRUE;
  548. while( pThisDev->hPollingThread != NULL )
  549. {
  550. //
  551. // Sleep 50 milliseconds.
  552. //
  553. NdisMSleep( 50000 );
  554. }
  555. IRUSB_ASSERT( pThisDev->packetsHeldByProtocol == 0 );
  556. DEBUGMSG( DBG_WARN, (" Polling thread killed\n") );
  557. //
  558. // Sleep 50 milliseconds so pending io might finish normally
  559. //
  560. NdisMSleep( 50000 );
  561. //
  562. // MS Security recommendation - not safe to cancel pending IRPs
  563. //
  564. //
  565. // Deinitialize our own ir device object.
  566. //
  567. DeinitializeDevice( pThisDev );
  568. pThisDev->fDeviceStarted = FALSE;
  569. DEBUGMSG(DBG_WARN, ("-IrUsb_CommonShutdown\n")); //chg to FUNC later?
  570. }
  571. /*****************************************************************************
  572. *
  573. * Function: StIrUsbReset
  574. *
  575. * Synopsis: Resets the drivers software state.
  576. *
  577. * Arguments: AddressingReset - return arg. If set to TRUE, NDIS will call
  578. * MiniportSetInformation to restore addressing
  579. * information to the current values.
  580. * Context - pointer to ir device object
  581. *
  582. * Returns: NDIS_STATUS_PENDING
  583. *
  584. *
  585. * Notes:
  586. *
  587. *
  588. *****************************************************************************/
  589. NDIS_STATUS
  590. StIrUsbReset(
  591. OUT PBOOLEAN AddressingReset,
  592. IN NDIS_HANDLE MiniportAdapterContext
  593. )
  594. {
  595. PIR_DEVICE pThisDev;
  596. NDIS_STATUS status = NDIS_STATUS_PENDING;
  597. DEBUGMSG(DBG_WARN, ("+StIrUsbReset\n")); // CHANGE TO FUNC?
  598. pThisDev = CONTEXT_TO_DEV( MiniportAdapterContext );
  599. if( TRUE == pThisDev->fPendingReset )
  600. {
  601. DEBUGMSG(DBG_ERROR, (" StIrUsbReset called with reset already pending\n"));
  602. status = NDIS_STATUS_RESET_IN_PROGRESS ;
  603. goto done;
  604. }
  605. //
  606. // Let the send completion and receive completion routine know that there
  607. // is a pending reset.
  608. //
  609. pThisDev->fPendingReset = TRUE;
  610. InterlockedExchange( (PLONG)&pThisDev->fProcessing, FALSE );
  611. *AddressingReset = TRUE;
  612. if( FALSE == ScheduleWorkItem( pThisDev, ResetIrDevice, NULL, 0) )
  613. {
  614. status = NDIS_STATUS_FAILURE;
  615. }
  616. done:
  617. DEBUGMSG(DBG_WARN, ("-StIrUsbReset\n")); // change to FUNC later?
  618. return status;
  619. }
  620. /*****************************************************************************
  621. *
  622. * Function: SuspendIrDevice
  623. *
  624. * Synopsis: Callback for a going into suspend mode
  625. *
  626. * Arguments: pWorkItem - pointer to the reset work item
  627. *
  628. * Returns: NTSTATUS
  629. *
  630. * Notes:
  631. *
  632. *****************************************************************************/
  633. NTSTATUS
  634. SuspendIrDevice(
  635. IN PIR_WORK_ITEM pWorkItem
  636. )
  637. {
  638. PIR_DEVICE pThisDev = (PIR_DEVICE)pWorkItem->pIrDevice;
  639. NTSTATUS Status = STATUS_SUCCESS;
  640. //
  641. // We no longer need the work item
  642. //
  643. FreeWorkItem( pWorkItem );
  644. //
  645. // A little time to complete pending IRPs
  646. //
  647. NdisMSleep( 100*1000 );
  648. // MS Security recommendation - not safe to cancel pending IRPs
  649. //
  650. // Prepare the part
  651. //
  652. #if defined(SUPPORT_LA8)
  653. if( pThisDev->ChipRevision >= CHIP_REVISION_8 )
  654. {
  655. Status = St4200EnableOscillatorPowerDown( pThisDev );
  656. if( Status == STATUS_SUCCESS )
  657. {
  658. Status = St4200TurnOnSuspend( pThisDev );
  659. }
  660. }
  661. #endif
  662. //
  663. // Tell the OS
  664. //
  665. if( pThisDev->fQuerypending )
  666. MyNdisMQueryInformationComplete( pThisDev, Status );
  667. return Status;
  668. }
  669. /*****************************************************************************
  670. *
  671. * Function: ResumeIrDevice
  672. *
  673. * Synopsis: Callback for a going out of suspend mode
  674. *
  675. * Arguments: pWorkItem - pointer to the reset work item
  676. *
  677. * Returns: None
  678. *
  679. * Notes:
  680. *
  681. *****************************************************************************/
  682. NTSTATUS
  683. ResumeIrDevice(
  684. IN PIR_WORK_ITEM pWorkItem
  685. )
  686. {
  687. PIR_DEVICE pThisDev = (PIR_DEVICE)pWorkItem->pIrDevice;
  688. NTSTATUS Status = STATUS_SUCCESS;
  689. //
  690. // We no longer need the work item
  691. //
  692. FreeWorkItem( pWorkItem );
  693. //
  694. // Get the device back up and running
  695. //
  696. #if defined(SUPPORT_LA8)
  697. if( pThisDev->ChipRevision >= CHIP_REVISION_8 )
  698. {
  699. Status = St4200TurnOffSuspend( pThisDev );
  700. }
  701. #endif
  702. if (Status == STATUS_SUCCESS)
  703. St4200SetSpeed( pThisDev );
  704. InterlockedExchange( (PLONG)&pThisDev->currentSpeed, pThisDev->linkSpeedInfo->BitsPerSec );
  705. InterlockedExchange( (PLONG)&pThisDev->fProcessing, TRUE );
  706. return Status;
  707. }
  708. /*****************************************************************************
  709. *
  710. * Function: RestoreIrDevice
  711. *
  712. * Synopsis: Callback for a on-the-fly reset
  713. *
  714. * Arguments: pWorkItem - pointer to the reset work item
  715. *
  716. * Returns: NTSTATUS
  717. *
  718. * Notes:
  719. *
  720. *****************************************************************************/
  721. NTSTATUS
  722. RestoreIrDevice(
  723. IN PIR_WORK_ITEM pWorkItem
  724. )
  725. {
  726. NTSTATUS Status = STATUS_SUCCESS;
  727. PIR_DEVICE pThisDev = (PIR_DEVICE)pWorkItem->pIrDevice;
  728. UINT CurrentSpeed, i;
  729. DEBUGMSG(DBG_WARN, ("+RestoreIrDevice\n"));
  730. DEBUGMSG(DBG_ERROR, (" RestoreIrDevice USB hang, resetting\n"));
  731. //
  732. // We no longer need the work item
  733. //
  734. FreeWorkItem( pWorkItem );
  735. //
  736. // Give a little time to complete
  737. //
  738. NdisMSleep( 100*1000 );
  739. //
  740. // Force a reset on the USB bus
  741. //
  742. Status = IrUsb_ResetUSBD( pThisDev, FALSE );
  743. if( Status != STATUS_SUCCESS )
  744. {
  745. //IrUsb_ResetUSBD( pThisDev, TRUE );
  746. pThisDev->fDeviceStarted = FALSE;
  747. InterlockedExchange( (PLONG)&pThisDev->fProcessing, FALSE );
  748. DEBUGMSG(DBG_ERROR, (" RestoreIrDevice() IrUsb_ResetUSBD failed. Returned 0x%.8x\n", Status));
  749. goto done;
  750. }
  751. //
  752. // Save the current speed
  753. //
  754. CurrentSpeed = pThisDev->currentSpeed;
  755. //
  756. // Shutdown the device
  757. //
  758. DEBUGMSG(DBG_WARN, (" RestoreIrDevice() about to call IrUsb_CommonShutdown()\n")); // change to FUNC later?
  759. IrUsb_CommonShutdown( pThisDev, FALSE ); //shutdown logic common to halt and reset; see above
  760. DEBUGMSG(DBG_WARN, (" RestoreIrDevice() after IrUsb_CommonShutdown()\n")); // change to FUNC later?
  761. //
  762. // Destroy and create again the USB portion of the device
  763. //
  764. DEBUGMSG(DBG_WARN, (" RestoreIrDevice() about to refresh USB info\n")); // change to FUNC later?
  765. FreeUsbInfo( pThisDev );
  766. if( !AllocUsbInfo( pThisDev ) )
  767. {
  768. DEBUGMSG(DBG_ERROR, (" RestoreIrDevice() AllocUsbInfo failed\n"));
  769. goto done;
  770. }
  771. DEBUGMSG(DBG_WARN, (" RestoreIrDevice() after refreshing USB info\n")); // change to FUNC later?
  772. //
  773. // Reinitialize the device
  774. //
  775. DEBUGMSG(DBG_WARN, (" RestoreIrDevice() about to call InitializeDevice()\n")); // change to FUNC later?
  776. Status = InitializeDevice( pThisDev );
  777. if( Status != STATUS_SUCCESS )
  778. {
  779. DEBUGMSG(DBG_ERROR, (" RestoreIrDevice() InitializeDevice failed. Returned 0x%.8x\n", Status));
  780. goto done;
  781. }
  782. DEBUGMSG(DBG_WARN, (" RestoreIrDevice() InitializeProcessing() SUCCESS, about to call InitializeReceive()\n")); // change to FUNC later?
  783. //
  784. // Restart it
  785. //
  786. Status = IrUsb_StartDevice( pThisDev );
  787. if( Status != STATUS_SUCCESS )
  788. {
  789. DEBUGMSG(DBG_ERROR, (" RestoreIrDevice() IrUsb_StartDevice failed. Returned 0x%.8x\n", Status));
  790. goto done;
  791. }
  792. //
  793. // Keep a pointer to the link speed which was previously set
  794. //
  795. for( i = 0; i < NUM_BAUDRATES; i++ )
  796. {
  797. if( supportedBaudRateTable[i].BitsPerSec == CurrentSpeed )
  798. {
  799. pThisDev->linkSpeedInfo = &supportedBaudRateTable[i];
  800. break; //for
  801. }
  802. }
  803. //
  804. // restore the old speed
  805. //
  806. DEBUGMSG( DBG_ERR, (" Restoring speed to: %d\n", pThisDev->linkSpeedInfo->BitsPerSec));
  807. Status = St4200SetSpeed( pThisDev );
  808. if( Status != STATUS_SUCCESS )
  809. {
  810. DEBUGMSG(DBG_ERROR, (" RestoreIrDevice() St4200SetSpeed failed. Returned 0x%.8x\n", Status));
  811. goto done;
  812. }
  813. InterlockedExchange( (PLONG)&pThisDev->currentSpeed, CurrentSpeed );
  814. //
  815. // Initialize receive loop.
  816. //
  817. Status = InitializeProcessing( pThisDev, FALSE );
  818. if( Status != STATUS_SUCCESS )
  819. {
  820. DEBUGMSG(DBG_ERROR, (" RestoreIrDevice() InitializeProcessing failed. Returned 0x%.8x\n", Status));
  821. goto done;
  822. }
  823. done:
  824. DEBUGCOND(DBG_ERROR, (Status != NDIS_STATUS_SUCCESS), (" RestoreIrDevice failed = 0x%.8x\n", Status));
  825. return Status;
  826. }
  827. /*****************************************************************************
  828. *
  829. * Function: ResetIrDevice
  830. *
  831. * Synopsis: Callback for StIrUsbReset
  832. *
  833. * Arguments: pWorkItem - pointer to the reset work item
  834. *
  835. * Returns: NTSTATUS
  836. *
  837. * Notes:
  838. *
  839. * The following elements of the ir device object outlast the reset:
  840. *
  841. * pUsbDevObj
  842. * hNdisAdapter
  843. *
  844. *****************************************************************************/
  845. NTSTATUS
  846. ResetIrDevice(
  847. IN PIR_WORK_ITEM pWorkItem
  848. )
  849. {
  850. NTSTATUS Status = STATUS_SUCCESS;
  851. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  852. PIR_DEVICE pThisDev = (PIR_DEVICE)pWorkItem->pIrDevice;
  853. DEBUGMSG(DBG_WARN, ("+ResetIrDevice\n")); // change to FUNC later?
  854. //
  855. // We no longer need the work item
  856. //
  857. FreeWorkItem( pWorkItem );
  858. //
  859. // A little time to complete pending IRPs
  860. //
  861. NdisMSleep( 100*1000 );
  862. // MS Security recommendation - not safe to cancel pending IRPs
  863. //
  864. // reset the part
  865. //
  866. Status = IrUsb_ResetUSBD( pThisDev, FALSE );
  867. if( Status != STATUS_SUCCESS )
  868. {
  869. pThisDev->fDeviceStarted = FALSE;
  870. //
  871. // Log the error
  872. //
  873. NdisWriteErrorLogEntry(
  874. pThisDev->hNdisAdapter,
  875. NDIS_STATUS_ADAPTER_NOT_FOUND,
  876. 1,
  877. Status
  878. );
  879. DEBUGMSG(DBG_ERROR, (" ResetIrDevice() IrUsb_ResetUSBD failed. Returned 0x%.8x\n", Status));
  880. NdisStatus = NDIS_STATUS_ADAPTER_NOT_FOUND;
  881. goto done;
  882. }
  883. //
  884. // Shutdown the device
  885. //
  886. DEBUGMSG(DBG_WARN, (" ResetIrDevice() about to call IrUsb_CommonShutdown()\n")); // change to FUNC later?
  887. IrUsb_CommonShutdown( pThisDev, FALSE ); //shutdown logic common to halt and reset; see above
  888. DEBUGMSG(DBG_WARN, (" ResetIrDevice() after IrUsb_CommonShutdown()\n")); // change to FUNC later?
  889. //
  890. // Destroy and create again the USB portion of the device
  891. //
  892. DEBUGMSG(DBG_WARN, (" ResetIrDevice() about to refresh USB info\n")); // change to FUNC later?
  893. FreeUsbInfo( pThisDev );
  894. if( !AllocUsbInfo( pThisDev ) )
  895. {
  896. //
  897. // Log the error
  898. //
  899. NdisWriteErrorLogEntry(
  900. pThisDev->hNdisAdapter,
  901. NDIS_STATUS_RESOURCES,
  902. 1,
  903. Status
  904. );
  905. DEBUGMSG(DBG_ERROR, (" ResetIrDevice() AllocUsbInfo failed\n"));
  906. NdisStatus = NDIS_STATUS_FAILURE;
  907. goto done;
  908. }
  909. DEBUGMSG(DBG_WARN, (" ResetIrDevice() after refreshing USB info\n")); // change to FUNC later?
  910. //
  911. // Reinitialize the device
  912. //
  913. DEBUGMSG(DBG_WARN, (" ResetIrDevice() about to call InitializeDevice()\n")); // change to FUNC later?
  914. Status = InitializeDevice( pThisDev );
  915. if( Status != NDIS_STATUS_SUCCESS )
  916. {
  917. //
  918. // Log the error
  919. //
  920. NdisWriteErrorLogEntry(
  921. pThisDev->hNdisAdapter,
  922. NDIS_STATUS_RESOURCES,
  923. 1,
  924. Status
  925. );
  926. DEBUGMSG(DBG_ERROR, (" ResetIrDevice() InitializeDevice failed. Returned 0x%.8x\n", Status));
  927. NdisStatus = NDIS_STATUS_FAILURE;
  928. goto done;
  929. }
  930. DEBUGMSG(DBG_WARN, (" ResetIrDevice() InitializeProcessing() SUCCESS, about to call InitializeReceive()\n")); // change to FUNC later?
  931. //
  932. // Restart it
  933. //
  934. Status = IrUsb_StartDevice( pThisDev );
  935. if( Status != STATUS_SUCCESS )
  936. {
  937. //
  938. // Log the error
  939. //
  940. NdisWriteErrorLogEntry(
  941. pThisDev->hNdisAdapter,
  942. NDIS_STATUS_ADAPTER_NOT_FOUND,
  943. 1,
  944. Status
  945. );
  946. DEBUGMSG(DBG_ERROR, (" ResetIrDevice() IrUsb_StartDevice failed. Returned 0x%.8x\n", Status));
  947. NdisStatus = NDIS_STATUS_ADAPTER_NOT_FOUND;
  948. goto done;
  949. }
  950. //
  951. // Initialize receive loop.
  952. //
  953. Status = InitializeProcessing( pThisDev, FALSE );
  954. if( Status != STATUS_SUCCESS )
  955. {
  956. //
  957. // Log the error
  958. //
  959. NdisWriteErrorLogEntry(
  960. pThisDev->hNdisAdapter,
  961. NDIS_STATUS_RESOURCES,
  962. 1,
  963. Status
  964. );
  965. DEBUGMSG(DBG_ERROR, (" ResetIrDevice() InitializeProcessing failed. Returned 0x%.8x\n", Status));
  966. NdisStatus = NDIS_STATUS_FAILURE;
  967. goto done;
  968. }
  969. done:
  970. DEBUGCOND(DBG_ERROR, (Status != NDIS_STATUS_SUCCESS), (" ResetIrDevice failed = 0x%.8x\n", Status));
  971. //
  972. // Deal with possible errors
  973. //
  974. if( NdisStatus != NDIS_STATUS_SUCCESS )
  975. {
  976. NdisStatus = NDIS_STATUS_HARD_ERRORS;
  977. }
  978. NdisMResetComplete(
  979. pThisDev->hNdisAdapter,
  980. NdisStatus,
  981. TRUE
  982. );
  983. DEBUGMSG(DBG_WARN, ("-ResetIrDevice\n")); // change to FUNC later?
  984. return Status;
  985. }
  986. /*****************************************************************************
  987. *
  988. * Function: GetPacketInfo
  989. *
  990. * Synopsis: Gets the IR specific information for an input packet
  991. *
  992. * Arguments: pPacket - pointer to packet
  993. *
  994. * Returns: PNDIS_IRDA_PACKET_INFO structure for the packet
  995. *
  996. * Notes:
  997. *
  998. *****************************************************************************/
  999. PNDIS_IRDA_PACKET_INFO
  1000. GetPacketInfo(
  1001. IN PNDIS_PACKET pPacket
  1002. )
  1003. {
  1004. PMEDIA_SPECIFIC_INFORMATION pMediaInfo;
  1005. UINT Size;
  1006. NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO( pPacket, &pMediaInfo, &Size );
  1007. if( Size )
  1008. return (PNDIS_IRDA_PACKET_INFO)pMediaInfo->ClassInformation;
  1009. else
  1010. return NULL;
  1011. }
  1012. /*****************************************************************************
  1013. *
  1014. * Function: MyNdisMSetInformationComplete
  1015. *
  1016. * Synopsis: Call NdisMSetInformationComplete()
  1017. *
  1018. * Arguments: pThisDev - pointer to IR device
  1019. * Status - status to signal
  1020. *
  1021. * Returns: None
  1022. *
  1023. * Notes:
  1024. *
  1025. *****************************************************************************/
  1026. VOID
  1027. MyNdisMSetInformationComplete(
  1028. IN PIR_DEVICE pThisDev,
  1029. IN NDIS_STATUS Status
  1030. )
  1031. {
  1032. DEBUGMSG( DBG_FUNC,("+MyNdisMSetInformationComplete\n"));
  1033. NdisMSetInformationComplete( (NDIS_HANDLE)pThisDev->hNdisAdapter, Status );
  1034. pThisDev->LastSetTime.QuadPart = 0;
  1035. pThisDev->fSetpending = FALSE;
  1036. DEBUGMSG( DBG_FUNC,("-MyNdisMSetInformationComplete\n"));
  1037. }
  1038. /*****************************************************************************
  1039. *
  1040. * Function: MyNdisMQueryInformationComplete
  1041. *
  1042. * Synopsis: Call NdisMQueryInformationComplete()
  1043. *
  1044. * Arguments: pThisDev - pointer to IR device
  1045. * Status - status to signal
  1046. *
  1047. * Returns: None
  1048. *
  1049. * Notes:
  1050. *
  1051. *****************************************************************************/
  1052. VOID
  1053. MyNdisMQueryInformationComplete(
  1054. IN PIR_DEVICE pThisDev,
  1055. IN NDIS_STATUS Status
  1056. )
  1057. {
  1058. DEBUGMSG( DBG_FUNC,("+MyNdisMQueryInformationComplete\n"));
  1059. NdisMQueryInformationComplete( (NDIS_HANDLE)pThisDev->hNdisAdapter, Status );
  1060. pThisDev->LastQueryTime.QuadPart = 0;
  1061. pThisDev->fQuerypending = FALSE;
  1062. DEBUGMSG( DBG_FUNC,("-MyNdisMQueryInformationComplete\n"));
  1063. }
  1064. /*****************************************************************************
  1065. *
  1066. * Function: IndicateMediaBusy
  1067. *
  1068. * Synopsis: Call NdisMIndicateStatus()
  1069. *
  1070. * Arguments: pThisDev - pointer to IR device
  1071. *
  1072. * Returns: None
  1073. *
  1074. * Notes:
  1075. *
  1076. *****************************************************************************/
  1077. VOID
  1078. IndicateMediaBusy(
  1079. IN PIR_DEVICE pThisDev
  1080. )
  1081. {
  1082. DEBUGMSG( DBG_FUNC,("+IndicateMediaBusy\n"));
  1083. NdisMIndicateStatus(
  1084. pThisDev->hNdisAdapter,
  1085. NDIS_STATUS_MEDIA_BUSY,
  1086. NULL,
  1087. 0
  1088. );
  1089. NdisMIndicateStatusComplete(
  1090. pThisDev->hNdisAdapter
  1091. );
  1092. #if DBG
  1093. pThisDev->NumMediaBusyIndications ++;
  1094. #endif
  1095. #if !defined(ONLY_ERROR_MESSAGES)
  1096. DEBUGMSG(DBG_ERR, (" IndicateMediaBusy()\n"));
  1097. #endif
  1098. DEBUGMSG( DBG_FUNC,("-IndicateMediaBusy\n"));
  1099. }
  1100. /*****************************************************************************
  1101. *
  1102. * Function: StIrUsbSendPackets
  1103. *
  1104. * Synopsis: Send a packet to the USB driver and add the sent irp and io context to
  1105. * To the pending send queue; this que is really just needed for possible later error cancellation
  1106. *
  1107. *
  1108. * Arguments: MiniportAdapterContext - pointer to current ir device object
  1109. * PacketArray - pointer to array of packets to send
  1110. * NumberOfPackets - number of packets in the array
  1111. *
  1112. * Returns: VOID
  1113. *
  1114. * Notes: This routine does nothing but calling StIrUsbSend
  1115. *
  1116. *
  1117. *****************************************************************************/
  1118. VOID
  1119. StIrUsbSendPackets(
  1120. IN NDIS_HANDLE MiniportAdapterContext,
  1121. IN PPNDIS_PACKET PacketArray,
  1122. IN UINT NumberOfPackets
  1123. )
  1124. {
  1125. ULONG i;
  1126. //
  1127. // This is a great opportunity to be lazy.
  1128. // Just call StIrUsbSend with each packet
  1129. // in sequence and set the result in the
  1130. // packet array object.
  1131. //
  1132. for( i=0; i<NumberOfPackets; i++ )
  1133. {
  1134. StIrUsbSend( MiniportAdapterContext, PacketArray[i], 0 );
  1135. }
  1136. }
  1137. /*****************************************************************************
  1138. *
  1139. * Function: StIrUsbSend
  1140. *
  1141. * Synopsis: Send a packet to the USB driver and add the sent irp and io context to
  1142. * To the pending send queue; this que is really just needed for possible later error cancellation
  1143. *
  1144. *
  1145. * Arguments: MiniportAdapterContext - pointer to current ir device object
  1146. * pPacketToSend - pointer to packet to send
  1147. * Flags - any flags set by protocol
  1148. *
  1149. * Returns: NDIS_STATUS_PENDING - This is generally what we should
  1150. * return. We will call NdisMSendComplete
  1151. * when the USB driver completes the
  1152. * send.
  1153. *
  1154. * Unsupported returns:
  1155. * NDIS_STATUS_SUCCESS - We should never return this since
  1156. * results will always be pending from
  1157. * the USB driver.
  1158. * NDIS_STATUS_RESOURCES - This indicates to the protocol that the
  1159. * device currently has no resources to complete
  1160. * the request. The protocol will resend
  1161. * the request when it receives either
  1162. * NdisMSendResourcesAvailable or
  1163. * NdisMSendComplete from the device.
  1164. *
  1165. * Notes: This routine delegates all the real work to SendPacketPreprocess in send.c
  1166. *
  1167. *
  1168. *****************************************************************************/
  1169. NDIS_STATUS
  1170. StIrUsbSend(
  1171. IN NDIS_HANDLE MiniportAdapterContext,
  1172. IN PNDIS_PACKET pPacketToSend,
  1173. IN UINT Flags
  1174. )
  1175. {
  1176. PIR_DEVICE pThisDev = (PIR_DEVICE)MiniportAdapterContext;
  1177. NDIS_STATUS Status;
  1178. DEBUGMSG( DBG_FUNC,("+StIrUsbSend()\n"));
  1179. //
  1180. // Make sure we are in the proper status, i.e. we are processing
  1181. // and no diagnostics are active
  1182. //
  1183. #if defined(DIAGS)
  1184. if( !pThisDev->fProcessing || pThisDev->DiagsPendingActivation )
  1185. #else
  1186. if( !pThisDev->fProcessing )
  1187. #endif
  1188. {
  1189. Status = NDIS_STATUS_FAILURE;
  1190. goto done;
  1191. }
  1192. //
  1193. // Send the packet to the hardware
  1194. //
  1195. NDIS_SET_PACKET_STATUS( pPacketToSend, NDIS_STATUS_PENDING );
  1196. Status = SendPacketPreprocess(
  1197. pThisDev,
  1198. pPacketToSend
  1199. );
  1200. done:
  1201. //
  1202. // If the operation didn't pend we have to complete
  1203. // We are really bouncing the packets...
  1204. //
  1205. if( Status != NDIS_STATUS_PENDING )
  1206. {
  1207. NdisMSendComplete(
  1208. pThisDev->hNdisAdapter,
  1209. pPacketToSend,
  1210. NDIS_STATUS_SUCCESS
  1211. );
  1212. }
  1213. DEBUGMSG( DBG_FUNC,("-StIrUsbSend()\n"));
  1214. return Status;
  1215. }
  1216. // Diagnostic entry points
  1217. #ifndef WIN9X
  1218. //#if defined(DIAGS)
  1219. /*****************************************************************************
  1220. *
  1221. * Function: StIrUsbDispatch
  1222. *
  1223. * Synopsis: Processes the diagnostic Irps
  1224. *
  1225. * Arguments: DeviceObject - pointer to the device object
  1226. * Irp - pointer to the Irp
  1227. *
  1228. * Returns: NT status code
  1229. *
  1230. * Notes:
  1231. *
  1232. *****************************************************************************/
  1233. NTSTATUS
  1234. StIrUsbDispatch(
  1235. IN PDEVICE_OBJECT DeviceObject,
  1236. IN PIRP Irp
  1237. )
  1238. {
  1239. PIR_DEVICE pThisDev = pGlobalDev;
  1240. PIO_STACK_LOCATION irpSp;
  1241. ULONG FunctionCode;
  1242. NTSTATUS status;
  1243. PVOID pBuffer;
  1244. ULONG BufferLength;
  1245. USHORT DiagsCode;
  1246. DEBUGMSG( DBG_FUNC,("+StIrUsbDispatch()\n"));
  1247. //
  1248. // Get the Irp
  1249. //
  1250. irpSp = IoGetCurrentIrpStackLocation( Irp );
  1251. //
  1252. // Get the data
  1253. //
  1254. FunctionCode = irpSp->Parameters.DeviceIoControl.IoControlCode;
  1255. pBuffer = Irp->AssociatedIrp.SystemBuffer;
  1256. //
  1257. // Process the diagnostic operation
  1258. //
  1259. switch( FunctionCode )
  1260. {
  1261. #ifdef DIAGS
  1262. case IOCTL_PROTOCOL_DIAGS:
  1263. DiagsCode = *(PUSHORT)pBuffer;
  1264. BufferLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  1265. switch( DiagsCode )
  1266. {
  1267. case DIAGS_ENABLE:
  1268. status = Diags_Enable( pThisDev );
  1269. break;
  1270. case DIAGS_DISABLE:
  1271. status = Diags_Disable( pThisDev );
  1272. break;
  1273. case DIAGS_READ_REGISTERS:
  1274. status = Diags_ReadRegisters( pThisDev, pBuffer, BufferLength );
  1275. if( status == STATUS_SUCCESS )
  1276. {
  1277. Irp->IoStatus.Information = sizeof(DIAGS_READ_REGISTERS_IOCTL);
  1278. }
  1279. break;
  1280. case DIAGS_WRITE_REGISTER:
  1281. status = Diags_WriteRegister( pThisDev, pBuffer, BufferLength );
  1282. break;
  1283. case DIAGS_BULK_OUT:
  1284. status = Diags_PrepareBulk( pThisDev, pBuffer, BufferLength, TRUE );
  1285. break;
  1286. case DIAGS_BULK_IN:
  1287. status = Diags_PrepareBulk( pThisDev, pBuffer, BufferLength, FALSE );
  1288. if( status == STATUS_SUCCESS )
  1289. {
  1290. PDIAGS_BULK_IOCTL pIOCTL = pThisDev->pIOCTL;
  1291. Irp->IoStatus.Information = sizeof(DIAGS_BULK_IOCTL)+pIOCTL->DataSize-1;
  1292. }
  1293. break;
  1294. case DIAGS_SEND:
  1295. status = Diags_PrepareSend( pThisDev, pBuffer, BufferLength );
  1296. break;
  1297. case DIAGS_RECEIVE:
  1298. status = Diags_Receive( pThisDev, pBuffer, BufferLength );
  1299. if( status == STATUS_SUCCESS )
  1300. {
  1301. PDIAGS_RECEIVE_IOCTL pIOCTL = pThisDev->pIOCTL;
  1302. Irp->IoStatus.Information = sizeof(DIAGS_RECEIVE_IOCTL)+pIOCTL->DataSize-1;
  1303. }
  1304. break;
  1305. case DIAGS_GET_SPEED:
  1306. status = Diags_GetSpeed( pThisDev, pBuffer, BufferLength );
  1307. if( status == STATUS_SUCCESS )
  1308. {
  1309. Irp->IoStatus.Information = sizeof(DIAGS_SPEED_IOCTL);
  1310. }
  1311. break;
  1312. case DIAGS_SET_SPEED:
  1313. status = Diags_SetSpeed( pThisDev, pBuffer, BufferLength );
  1314. break;
  1315. default:
  1316. status = STATUS_NOT_SUPPORTED;
  1317. break;
  1318. }
  1319. break;
  1320. #endif //DIAGS
  1321. case IOCTL_STIR_CUSTOMER_DATA:
  1322. //
  1323. // Return customer data returned from the chip on power-up.
  1324. //
  1325. BufferLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  1326. if (BufferLength < sizeof(STIR_CUSTOMER_DATA))
  1327. {
  1328. status = STATUS_INVALID_PARAMETER;
  1329. break;
  1330. }
  1331. RtlCopyMemory(pBuffer, &(pThisDev->pCustomerData[2]), sizeof(STIR_CUSTOMER_DATA));
  1332. status = STATUS_SUCCESS;
  1333. Irp->IoStatus.Information = sizeof(STIR_CUSTOMER_DATA);
  1334. break;
  1335. default:
  1336. status = STATUS_NOT_SUPPORTED;
  1337. break;
  1338. }
  1339. //
  1340. // Complete and return
  1341. //
  1342. Irp->IoStatus.Status = status;
  1343. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1344. DEBUGMSG( DBG_FUNC,("-StIrUsbDispatch()\n"));
  1345. return status;
  1346. }
  1347. /*****************************************************************************
  1348. *
  1349. * Function: StIrUsbCreate
  1350. *
  1351. * Synopsis: Creates a new diagnostic object (it does nothing)
  1352. *
  1353. * Arguments: DeviceObject - pointer to the device object
  1354. * Irp - pointer to the Irp
  1355. *
  1356. * Returns: NT status code
  1357. *
  1358. * Notes:
  1359. *
  1360. *****************************************************************************/
  1361. NTSTATUS
  1362. StIrUsbCreate(
  1363. IN PDEVICE_OBJECT DeviceObject,
  1364. IN PIRP Irp
  1365. )
  1366. {
  1367. PIR_DEVICE pThisDev = pGlobalDev;
  1368. //
  1369. // Initialize list for holding pending read requests
  1370. //
  1371. #ifdef DIAGS
  1372. KeInitializeSpinLock( &pThisDev->DiagsReceiveLock );
  1373. InitializeListHead( &pThisDev->DiagsReceiveQueue );
  1374. #endif // DIAGS
  1375. Irp->IoStatus.Status = STATUS_SUCCESS;
  1376. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1377. return STATUS_SUCCESS;
  1378. }
  1379. /*****************************************************************************
  1380. *
  1381. * Function: StIrUsbClose
  1382. *
  1383. * Synopsis: Destroys a new diagnostic object (it does nothing)
  1384. *
  1385. * Arguments: DeviceObject - pointer to the device object
  1386. * Irp - pointer to the Irp
  1387. *
  1388. * Returns: NT status code
  1389. *
  1390. * Notes:
  1391. *
  1392. *****************************************************************************/
  1393. NTSTATUS
  1394. StIrUsbClose(
  1395. IN PDEVICE_OBJECT DeviceObject,
  1396. IN PIRP Irp
  1397. )
  1398. {
  1399. Irp->IoStatus.Status = STATUS_SUCCESS;
  1400. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1401. return STATUS_SUCCESS;
  1402. }
  1403. //#endif
  1404. #endif