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.

3629 lines
98 KiB

  1. //
  2. // Copyright (c) 1998-1999, Microsoft Corporation, all rights reserved
  3. //
  4. // irp.c
  5. //
  6. // IEEE1394 mini-port/call-manager driver
  7. //
  8. // Routines that issue the numerous Irbs to the 1394 Bus driver
  9. //
  10. // 04/01/1999 ADube Created,
  11. //
  12. #include "precomp.h"
  13. //
  14. // This file will contain all the functions that issue Irps with the various Irbs to the
  15. // 1394 bus. All Irbs except the actual send/recv irbs will be implemented here
  16. //
  17. //
  18. // The functions will follow this general algorithm
  19. // nicGetIrb
  20. // nicInitialize....Irb
  21. // nicPrintDebugSpew
  22. // nicGetIrp
  23. // nicSubmit_Irp_Synch
  24. // return Status
  25. //
  26. //-----------------------------------------------------------------------------
  27. // A Simple template that can be used to send Irps syncronously
  28. //-----------------------------------------------------------------------------
  29. /*
  30. Comments Template
  31. /*++
  32. Routine Description:
  33. Arguments:
  34. Return Value:
  35. --*/
  36. /*
  37. // Function Description:
  38. //
  39. //
  40. //
  41. //
  42. //
  43. // Arguments
  44. //
  45. //
  46. //
  47. // Return Value:
  48. //
  49. //
  50. //
  51. //
  52. Function template
  53. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  54. PIRB pIrb = NULL;
  55. PIRP pIrp = NULL;
  56. TRACE( TL_T, TM_Irp, ( "==>nicGe....ect, pAdapter %x", pAdapter ) );
  57. ASSERT (pNodeAddress != NULL);
  58. do
  59. {
  60. NdisStatus = nicGetIrb (&pIrb);
  61. if (NdisStatus != NDIS_STATUS_SUCCESS)
  62. {
  63. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrb FAILED" ) );
  64. break;
  65. }
  66. ASSERT ( pIrb != NULL);
  67. nicInit....Irb (..)
  68. NdisStatus = nicGetIrp ( pRemoteNodePdoCb, &pIrp);
  69. if (NdisStatus != NDIS_STATUS_SUCCESS)
  70. {
  71. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrp FAILED" ) );
  72. break;
  73. }
  74. ASSERT (pIrp != NULL);
  75. NdisStatus = nicSubmitIrp_Synch ( pAdapter->pLocalHostPdoCb,
  76. pIrp,
  77. pIrb );
  78. if (NdisStatus != NDIS_STATUS_SUCCESS)
  79. {
  80. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  81. break;
  82. }
  83. Copy returned data to nic1394's data structures
  84. } while (FALSE);
  85. //
  86. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  87. // functions return immediately
  88. //
  89. nicFreeIrb (pIrb);
  90. nicFreeIrp (pIrp);
  91. TRACE( TL_T, TM_Irp, ( "<==nicGet139..., pAdapter %x", pAdapter ) );
  92. return NdisStatus;
  93. */
  94. //-----------------------------------------------------------------------------
  95. // Routines begin here
  96. //-----------------------------------------------------------------------------
  97. NDIS_STATUS
  98. nicAllocateAddressRange_Synch (
  99. IN PADAPTERCB pAdapter,
  100. IN PMDL pMdl,
  101. IN ULONG fulFlags,
  102. IN ULONG nLength,
  103. IN ULONG MaxSegmentSize,
  104. IN ULONG fulAccessType,
  105. IN ULONG fulNotificationOptions,
  106. IN PVOID Callback,
  107. IN PVOID Context,
  108. IN ADDRESS_OFFSET Required1394Offset,
  109. IN PSLIST_HEADER FifoSListHead,
  110. IN PKSPIN_LOCK FifoSpinLock,
  111. OUT PULONG pAddressesReturned,
  112. IN OUT PADDRESS_RANGE p1394AddressRange,
  113. OUT PHANDLE phAddressRange
  114. )
  115. // Function Description:
  116. // Takes the parameter and just passes it down to the bus driver
  117. // Arguments
  118. //
  119. // Return Value:
  120. //
  121. {
  122. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  123. PIRB pIrb = NULL;
  124. PIRP pIrp = NULL;
  125. TRACE( TL_T, TM_Irp, ( "==>nicAllocateAddressRange_Synch, pAdapter %x, Offset %x", pAdapter, Required1394Offset ) );
  126. TRACE (TL_V, TM_Irp, (" pMdl %x, fulFlags %x, nLength %x, MaxSegmentSize %x, fulAcessType %x",
  127. pMdl, fulFlags, nLength, MaxSegmentSize, fulAccessType ) );
  128. TRACE (TL_V, TM_Irp, (" fulNotification %x, Callback %x, Context %x, ReqOffset.High %x, ReqOffset.Low %x" ,
  129. fulNotificationOptions, Callback, Context, Required1394Offset.Off_High, Required1394Offset.Off_Low ) );
  130. TRACE (TL_V, TM_Irp, (" FifoSListHead %x, FifoSpinLock %x, p1394AddressRange %x" ,FifoSListHead, FifoSpinLock, p1394AddressRange ) )
  131. do
  132. {
  133. NdisStatus = nicGetIrb (&pIrb);
  134. if (NdisStatus != NDIS_STATUS_SUCCESS)
  135. {
  136. TRACE( TL_A, TM_Irp, ( "nicAllocateAddressRange_Synch , nicGetIrb FAILED" ) );
  137. break;
  138. }
  139. ASSERT ( pIrb != NULL);
  140. NdisStatus = nicGetIrp (pAdapter->pNextDeviceObject, &pIrp);
  141. if (NdisStatus != NDIS_STATUS_SUCCESS)
  142. {
  143. TRACE( TL_A, TM_Irp, ( "nicAllocateAddressRange_Synch , nicGetIrp FAILED" ) );
  144. break;
  145. }
  146. ASSERT (pIrp != NULL);
  147. pIrb->FunctionNumber = REQUEST_ALLOCATE_ADDRESS_RANGE;
  148. pIrb->Flags = 0;
  149. pIrb->u.AllocateAddressRange.Mdl = pMdl; // Address to map to 1394 space
  150. pIrb->u.AllocateAddressRange.fulFlags = fulFlags; // Flags for this operation
  151. pIrb->u.AllocateAddressRange.nLength = nLength; // Length of 1394 space desired
  152. pIrb->u.AllocateAddressRange.MaxSegmentSize = MaxSegmentSize; // Maximum segment size for a single address element
  153. pIrb->u.AllocateAddressRange.fulAccessType = fulAccessType; // Desired access: R, W, L
  154. pIrb->u.AllocateAddressRange.fulNotificationOptions = fulNotificationOptions; // Notify options on Async access
  155. pIrb->u.AllocateAddressRange.Callback = Callback; // Pointer to callback routine
  156. pIrb->u.AllocateAddressRange.Context = Context; // Pointer to driver supplied data
  157. pIrb->u.AllocateAddressRange.Required1394Offset = Required1394Offset; // Offset that must be returned
  158. pIrb->u.AllocateAddressRange.FifoSListHead = FifoSListHead; // Pointer to SList FIFO head
  159. pIrb->u.AllocateAddressRange.FifoSpinLock = FifoSpinLock; // Pointer to SList Spin Lock
  160. pIrb->u.AllocateAddressRange.p1394AddressRange = p1394AddressRange; // Address Range Returned
  161. ASSERT ( pIrb->u.AllocateAddressRange.p1394AddressRange != NULL);
  162. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  163. pIrp,
  164. pIrb );
  165. if (NdisStatus != NDIS_STATUS_SUCCESS)
  166. {
  167. TRACE( TL_A, TM_Irp, ( "nicAllocateAddressRange_Synch , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  168. break;
  169. }
  170. //
  171. // Update the output values
  172. //
  173. *pAddressesReturned = pIrb->u.AllocateAddressRange.AddressesReturned; // Number of addresses returned
  174. p1394AddressRange = pIrb->u.AllocateAddressRange.p1394AddressRange; // Pointer to returned 1394 Address Ranges
  175. *phAddressRange = pIrb->u.AllocateAddressRange.hAddressRange; // Handle to address range
  176. TRACE (TL_V, TM_Irp, (" *pAddressesReturned %x, p1394AddressRange %x, phAddressRange %x," ,
  177. *pAddressesReturned, p1394AddressRange, *phAddressRange ) );
  178. } while (FALSE);
  179. //
  180. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  181. // functions return immediately
  182. //
  183. nicFreeIrb (pIrb);
  184. nicFreeIrp (pIrp);
  185. TRACE( TL_T, TM_Irp, ( "<==nicAllocateAddressRange_Synch, Status %x", NdisStatus) );
  186. return NdisStatus;
  187. }
  188. NDIS_STATUS
  189. nicGet1394AddressOfRemoteNode(
  190. IN PREMOTE_NODE pRemoteNode,
  191. IN OUT NODE_ADDRESS *pNodeAddress,
  192. IN ULONG fulFlags
  193. )
  194. // Function Description:
  195. // This function will get the 1394 Address from the device object.
  196. //
  197. // Arguments
  198. // PdoCb * Local Host's Pdo Control Block
  199. // NodeAddress * Node Address structre wher the address will be returned in
  200. // fulFlags - Could specify USE_LOCAL_HOST
  201. //
  202. // Return Value:
  203. // Success if the irp succeeeded
  204. // Failure: if the pdo is not active or the irp failed
  205. //
  206. {
  207. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  208. PIRB pIrb = NULL;
  209. PIRP pIrp = NULL;
  210. TRACE( TL_T, TM_Irp, ( "==>nicGet1394AddressOfRemoteNode, pRemoteNode %x, pNodeAdddress ", pRemoteNode, pNodeAddress) );
  211. ASSERT (pNodeAddress != NULL);
  212. do
  213. {
  214. NdisStatus = nicGetIrb (&pIrb);
  215. if (NdisStatus != NDIS_STATUS_SUCCESS)
  216. {
  217. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressOfRemoteNode, nicGetIrb FAILED" ) );
  218. break;
  219. }
  220. ASSERT ( pIrb != NULL);
  221. pIrb->FunctionNumber = REQUEST_GET_ADDR_FROM_DEVICE_OBJECT;
  222. pIrb->u.Get1394AddressFromDeviceObject.fulFlags = fulFlags;
  223. NdisStatus = nicGetIrp (pRemoteNode->pPdo, &pIrp);
  224. if (NdisStatus != NDIS_STATUS_SUCCESS)
  225. {
  226. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressOfRemoteNode, nicGetIrp FAILED" ) );
  227. break;
  228. }
  229. ASSERT (pIrp != NULL);
  230. NdisStatus = nicSubmitIrp_Synch (pRemoteNode,
  231. pIrp,
  232. pIrb );
  233. if (NdisStatus != NDIS_STATUS_SUCCESS)
  234. {
  235. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressOfRemoteNode, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  236. break;
  237. }
  238. (*pNodeAddress) = pIrb->u.Get1394AddressFromDeviceObject.NodeAddress;
  239. } while (FALSE);
  240. //
  241. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  242. // functions return immediately
  243. //
  244. nicFreeIrb(pIrb);
  245. nicFreeIrp(pIrp);
  246. TRACE( TL_T, TM_Irp, ( "<==nicGet1394AddressOfRemoteNode, Status %x, Address %x", NdisStatus, *pNodeAddress ) );
  247. return NdisStatus;
  248. }
  249. NDIS_STATUS
  250. nicGet1394AddressFromDeviceObject(
  251. IN PDEVICE_OBJECT pPdo,
  252. IN OUT NODE_ADDRESS *pNodeAddress,
  253. IN ULONG fulFlags
  254. )
  255. // Function Description:
  256. // This function will get the 1394 Address from the device object.
  257. //
  258. // Arguments
  259. // PdoCb * Local Host's Pdo Control Block
  260. // NodeAddress * Node Address structre wher the address will be returned in
  261. // fulFlags - Could specify USE_LOCAL_HOST
  262. //
  263. // Return Value:
  264. // Success if the irp succeeeded
  265. // Failure: if the pdo is not active or the irp failed
  266. //
  267. {
  268. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  269. PIRB pIrb = NULL;
  270. PIRP pIrp = NULL;
  271. TRACE( TL_T, TM_Irp, ( "==>nicGet1394AddressFromDeviceObject, pPdo %x, pNodeAdddress ",
  272. pPdo, pNodeAddress) );
  273. ASSERT (pNodeAddress != NULL);
  274. ASSERT (pPdo != NULL);
  275. do
  276. {
  277. NdisStatus = nicGetIrb (&pIrb);
  278. if (NdisStatus != NDIS_STATUS_SUCCESS)
  279. {
  280. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrb FAILED" ) );
  281. break;
  282. }
  283. ASSERT ( pIrb != NULL);
  284. pIrb->Flags = 0;
  285. pIrb->FunctionNumber = REQUEST_GET_ADDR_FROM_DEVICE_OBJECT;
  286. pIrb->u.Get1394AddressFromDeviceObject.fulFlags = fulFlags;
  287. NdisStatus = nicGetIrp (pPdo, &pIrp);
  288. if (NdisStatus != NDIS_STATUS_SUCCESS)
  289. {
  290. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrp FAILED" ) );
  291. break;
  292. }
  293. ASSERT (pIrp != NULL);
  294. NdisStatus = nicSubmitIrp_PDOSynch (pPdo,
  295. pIrp,
  296. pIrb );
  297. if (NdisStatus != NDIS_STATUS_SUCCESS)
  298. {
  299. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  300. break;
  301. }
  302. (*pNodeAddress) = pIrb->u.Get1394AddressFromDeviceObject.NodeAddress;
  303. } while (FALSE);
  304. //
  305. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  306. // functions return immediately
  307. //
  308. nicFreeIrb(pIrb);
  309. nicFreeIrp(pIrp);
  310. TRACE( TL_T, TM_Irp, ( "<==nicGet1394AddressFromDeviceObject, Status %x, Address %x", NdisStatus, *pNodeAddress ) );
  311. return NdisStatus;
  312. }
  313. NDIS_STATUS
  314. nicGetGenerationCount(
  315. IN PADAPTERCB pAdapter,
  316. IN OUT PULONG GenerationCount
  317. )
  318. // This function returns the generation count of the Device Object that PDO points to.
  319. //
  320. {
  321. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  322. PIRB pIrb = NULL;
  323. PIRP pIrp = NULL;
  324. PDEVICE_OBJECT pDeviceObject = pAdapter->pNextDeviceObject;
  325. TRACE( TL_T, TM_Irp, ( "==>nicGetGenerationCount, PDO %x, pVc %x", pDeviceObject ) );
  326. ASSERT( pDeviceObject != NULL);
  327. do
  328. {
  329. NdisStatus = nicGetIrb( &pIrb );
  330. if (NdisStatus != NDIS_STATUS_SUCCESS)
  331. {
  332. TRACE( TL_A, TM_Irp, ( "Failed to allocate an Irb in nicGetGenerationCout") );
  333. NdisStatus = NDIS_STATUS_RESOURCES;
  334. break;
  335. }
  336. NdisStatus = nicGetIrp (pDeviceObject, &pIrp);
  337. if (NdisStatus != NDIS_STATUS_SUCCESS)
  338. {
  339. TRACE( TL_A, TM_Irp, ( "Failed to allocate an Irp in nicGetGenerationCout") );
  340. NdisStatus = NDIS_STATUS_RESOURCES;
  341. break;
  342. }
  343. pIrb->FunctionNumber = REQUEST_GET_GENERATION_COUNT;
  344. pIrb->Flags = 0;
  345. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter, pIrp, pIrb);
  346. if (NdisStatus == NDIS_STATUS_SUCCESS)
  347. {
  348. *GenerationCount = pIrb->u.GetGenerationCount.GenerationCount;
  349. TRACE( TL_N, TM_Irp, ("GenerationCount = 0x%x\n", *GenerationCount) );
  350. }
  351. else
  352. {
  353. TRACE(TL_A, TM_Irp, ("SubmitIrpSync failed = 0x%x\n", NdisStatus));
  354. ASSERT (0);
  355. break;
  356. }
  357. } while(FALSE);
  358. //
  359. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  360. // functions return immediately
  361. //
  362. nicFreeIrb(pIrb);
  363. nicFreeIrp(pIrp);
  364. TRACE( TL_T, TM_Irp, ( "<==nicGetGenerationCount, PDO %x, Generation %x", pDeviceObject, *GenerationCount) );
  365. return NdisStatus;
  366. }
  367. NDIS_STATUS
  368. nicFreeAddressRange(
  369. IN PADAPTERCB pAdapter,
  370. IN ULONG nAddressesToFree,
  371. IN PADDRESS_RANGE p1394AddressRange,
  372. IN PHANDLE phAddressRange
  373. )
  374. // Function Description:
  375. // This is the generic call to free an address range. It is the callers responsibility to figure out
  376. // the reference counting on the RemoteNode
  377. // This is because in the RecvFIFO code path we allocate one address range on each remote node
  378. // whereas in the Broadcast channel register, we allocate one addreesss on ONE remote node only
  379. //
  380. // Arguments
  381. // pRemoteNode, - Remote Node used to submit the IRP
  382. // nAddressesToFree, - Number of addreses to free
  383. // p1394AddressRange, - pointer to the address range which was allocated
  384. // phAddressRange - Handle returned by the bus driver
  385. //
  386. // Return Value:
  387. // Success if the irp succeeeded
  388. // Failure: if the pdo is not active or the irp failed
  389. //
  390. {
  391. PIRP pIrp = NULL;
  392. PIRB pIrb = NULL;
  393. PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
  394. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  395. TRACE( TL_T, TM_Irp, ( "==>nicFreeAddressRange pAdapter %x", pAdapter ) );
  396. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  397. do
  398. {
  399. if (pPdo == NULL)
  400. {
  401. TRACE( TL_A, TM_Irp, ( "pPdo is NULL in nicFreeRecvFifoAddressRange" ) );
  402. NdisStatus = NDIS_STATUS_FAILURE;
  403. break;
  404. }
  405. NdisStatus = nicGetIrb(&pIrb);
  406. if (NdisStatus != NDIS_STATUS_SUCCESS)
  407. {
  408. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicFreeRecvFifoAddressRange" ) );
  409. break;
  410. }
  411. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  412. if (NdisStatus != NDIS_STATUS_SUCCESS)
  413. {
  414. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicFreeRecvFifoAddressRange" ) );
  415. break;
  416. }
  417. TRACE (TL_V, TM_Cm, (" NumAddresses %x, hAddressRange %x, Hi %x, Length %x, Lo %x",
  418. nAddressesToFree,
  419. phAddressRange,
  420. p1394AddressRange->AR_Off_High,
  421. p1394AddressRange->AR_Length,
  422. p1394AddressRange->AR_Off_Low ) );
  423. //
  424. //Initialize the datastructures in the Irb
  425. //
  426. pIrb->FunctionNumber = REQUEST_FREE_ADDRESS_RANGE;
  427. pIrb->Flags = 0;
  428. pIrb->u.FreeAddressRange.nAddressesToFree = nAddressesToFree;
  429. pIrb->u.FreeAddressRange.p1394AddressRange = p1394AddressRange;
  430. pIrb->u.FreeAddressRange.pAddressRange = phAddressRange;
  431. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
  432. pIrp,
  433. pIrb );
  434. } while (FALSE);
  435. //
  436. // Free the locally allocated memory
  437. //
  438. nicFreeIrb(pIrb);
  439. nicFreeIrp(pIrp);
  440. //
  441. // We do not care about the status, because we do not know what to do if it fails.
  442. // However, spew some debug out.
  443. //
  444. if (NdisStatus != NDIS_STATUS_SUCCESS)
  445. {
  446. TRACE( TL_N, TM_Irp, ( "nicFreeAddressRangeFAILED %x", NdisStatus) );
  447. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  448. }
  449. TRACE( TL_T, TM_Irp, ( "<==nicFreeAddressRangeStatus %x (always success)", NdisStatus) );
  450. NdisStatus = NDIS_STATUS_SUCCESS;
  451. return NdisStatus;
  452. }
  453. VOID
  454. nicFreeAddressRangeDebugSpew(
  455. IN PIRB pIrb
  456. )
  457. // This functions spews out the parameters in a Free Address Range Irb
  458. //
  459. //
  460. {
  461. TRACE( TL_V, TM_Irp, ( "==>nicFreeAddressRangeDebugSpew, pIrb = %x", pIrb) );
  462. ASSERT(pIrb != NULL);
  463. TRACE( TL_N, TM_Irp, ( "Num Addresses Returned %x ",pIrb->u.FreeAddressRange.nAddressesToFree ) );
  464. TRACE( TL_N, TM_Irp, ( "Address High %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Off_High ) );
  465. TRACE( TL_N, TM_Irp, ( "Address Low %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Off_Low ) );
  466. TRACE( TL_N, TM_Irp, ( "Address Length %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Length ) );
  467. TRACE( TL_N, TM_Irp, ( "Handle %x", pIrb->u.FreeAddressRange.pAddressRange ) );
  468. TRACE( TL_V, TM_Irp, ( "<==nicFreeAddressRangeDebugSpew " ) );
  469. }
  470. NDIS_STATUS
  471. nicFreeChannel(
  472. IN PADAPTERCB pAdapter,
  473. IN ULONG nChannel
  474. )
  475. // Function Description:
  476. // This function sends an Irp to the Bus driver to free a channel
  477. // Any remote Pdo can be used for the Irp. However for the sake of
  478. // bookkeeping use the same Pdo that the channel was allocated on (maybe)
  479. // Arguments
  480. // PdoCb The Pdo for the remote node to which the Irp is submitted
  481. // Channel Pointer The Channel, requested and the channel returned
  482. //
  483. // Return Value:
  484. // Success if the channel was allocated
  485. // Failure otherwise
  486. //
  487. {
  488. PIRP pIrp = NULL;
  489. PIRB pIrb = NULL;
  490. PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
  491. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  492. TRACE( TL_T, TM_Irp, ( "==>nicFreeChannel pAdapter %x, Channel %x", pAdapter, nChannel) );
  493. ASSERT (pAdapter!= NULL);
  494. ASSERT (pPdo != NULL);
  495. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  496. do
  497. {
  498. if (pPdo == NULL)
  499. {
  500. TRACE( TL_A, TM_Irp, ( "pPdo is NULL in nicFreeChannel" ) );
  501. NdisStatus = NDIS_STATUS_FAILURE;
  502. break;
  503. }
  504. NdisStatus = nicGetIrb(&pIrb);
  505. if (NdisStatus != NDIS_STATUS_SUCCESS)
  506. {
  507. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicFreeChannel" ) );
  508. break;
  509. }
  510. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  511. if (NdisStatus != NDIS_STATUS_SUCCESS)
  512. {
  513. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicFreeChannel" ) );
  514. break;
  515. }
  516. //
  517. //Initialize the datastructures in the Irb
  518. //
  519. pIrb->FunctionNumber = REQUEST_ISOCH_FREE_CHANNEL;
  520. pIrb->Flags = 0;
  521. pIrb->u.IsochFreeChannel.nChannel = nChannel;
  522. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
  523. pIrp,
  524. pIrb );
  525. //
  526. // Regardless update the mask, as the channel could have been freed by a bus reset
  527. //
  528. if (nChannel != BROADCAST_CHANNEL)
  529. {
  530. ADAPTER_ACQUIRE_LOCK (pAdapter);
  531. //
  532. // Clear the channel in the mask
  533. //
  534. pAdapter->ChannelsAllocatedByLocalHost &= (~( g_ullOne <<nChannel ));
  535. ADAPTER_RELEASE_LOCK (pAdapter);
  536. }
  537. } while (FALSE);
  538. //
  539. // Free the locally allocated memory
  540. //
  541. nicFreeIrb(pIrb);
  542. nicFreeIrp(pIrp);
  543. //
  544. // We do not care about the status, because we do not know what to do if it fails.
  545. // However, spew some debug out.
  546. //
  547. if (NdisStatus != NDIS_STATUS_SUCCESS)
  548. {
  549. TRACE( TL_N, TM_Irp, ( "nicFreeChannel FAILED %x", NdisStatus) );
  550. }
  551. TRACE( TL_T, TM_Irp, ( "<==nicFreeChannel Status %x ", NdisStatus) );
  552. return NdisStatus;
  553. }
  554. NDIS_STATUS
  555. nicAllocateChannel (
  556. IN PADAPTERCB pAdapter,
  557. IN ULONG Channel,
  558. OUT PULARGE_INTEGER pChannelsAvailable OPTIONAL
  559. )
  560. // Function Description:
  561. // This function sends an Irp to the Bus driver to allocate a channel
  562. // Any remote Pdo can be used for the Irp
  563. //
  564. // Arguments
  565. // PdoCb The Pdo for the remote node to which the Irp is submitted
  566. // Channel -The Channel, requested and the channel returned
  567. //
  568. // Return Value:
  569. // Success if the channel was allocated
  570. // Failure otherwise
  571. //
  572. {
  573. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  574. PIRB pIrb = NULL;
  575. PIRP pIrp = NULL;
  576. PDEVICE_OBJECT pDeviceObject = pAdapter->pNextDeviceObject;
  577. STORE_CURRENT_IRQL;
  578. TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateChannel, PdoCb, %x Channel %d", pAdapter, Channel ) );
  579. do
  580. {
  581. NdisStatus = nicGetIrb (&pIrb);
  582. if (NdisStatus != NDIS_STATUS_SUCCESS)
  583. {
  584. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicGetIrb FAILED" ) );
  585. break;
  586. }
  587. ASSERT ( pIrb != NULL);
  588. //
  589. //Initialize the datastructures in the Irb
  590. //
  591. pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_CHANNEL;
  592. pIrb->Flags = 0;
  593. pIrb->u.IsochAllocateChannel.nRequestedChannel = Channel;
  594. ASSERT (Channel < 64);
  595. NdisStatus = nicGetIrp ( pDeviceObject, &pIrp);
  596. if (NdisStatus != NDIS_STATUS_SUCCESS)
  597. {
  598. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicGetIrp FAILED" ) );
  599. break;
  600. }
  601. ASSERT (pIrp != NULL);
  602. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  603. pIrp,
  604. pIrb );
  605. if (NdisStatus != NDIS_STATUS_SUCCESS)
  606. {
  607. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  608. break;
  609. }
  610. if (pChannelsAvailable != NULL)
  611. {
  612. pChannelsAvailable->QuadPart = pIrb->u.IsochAllocateChannel.ChannelsAvailable.QuadPart;
  613. }
  614. TRACE( TL_N, TM_Irp, ( "Channel allocated %d", Channel ) );
  615. if (Channel != BROADCAST_CHANNEL)
  616. {
  617. ADAPTER_ACQUIRE_LOCK (pAdapter);
  618. //
  619. // Set the channel in the mask
  620. //
  621. pAdapter->ChannelsAllocatedByLocalHost |= ( g_ullOne <<Channel );
  622. ADAPTER_RELEASE_LOCK (pAdapter);
  623. }
  624. } while (FALSE);
  625. //
  626. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  627. // functions return immediately
  628. //
  629. nicFreeIrb (pIrb);
  630. nicFreeIrp (pIrp);
  631. MATCH_IRQL;
  632. TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateChannel, Channel %d, Status %x", Channel, NdisStatus ) );
  633. return NdisStatus;
  634. }
  635. NDIS_STATUS
  636. nicQueryChannelMap (
  637. IN PADAPTERCB pAdapter,
  638. OUT PULARGE_INTEGER pChannelsAvailable
  639. )
  640. // Function Description:
  641. // This function sends an Irp to the Bus driver to allocate a channel
  642. // Any remote Pdo can be used for the Irp
  643. //
  644. // Arguments
  645. // PdoCb The Pdo for the remote node to which the Irp is submitted
  646. // Channel -The Channel, requested and the channel returned
  647. //
  648. // Return Value:
  649. // Success if the channel was allocated
  650. // Failure otherwise
  651. //
  652. {
  653. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  654. PIRB pIrb = NULL;
  655. PIRP pIrp = NULL;
  656. PDEVICE_OBJECT pDeviceObject = pAdapter->pNextDeviceObject;
  657. STORE_CURRENT_IRQL;
  658. TRACE( TL_T, TM_Irp, ( "==>nicQueryChannelMap , PdoCb, %x ", pAdapter) );
  659. do
  660. {
  661. if (pChannelsAvailable == NULL)
  662. {
  663. ASSERT (pChannelsAvailable != NULL);
  664. NdisStatus = NDIS_STATUS_FAILURE;
  665. break;
  666. }
  667. NdisStatus = nicGetIrb (&pIrb);
  668. if (NdisStatus != NDIS_STATUS_SUCCESS)
  669. {
  670. TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicGetIrb FAILED" ) );
  671. break;
  672. }
  673. ASSERT ( pIrb != NULL);
  674. //
  675. //Initialize the datastructures in the Irb
  676. //
  677. pIrb->FunctionNumber = REQUEST_ISOCH_QUERY_RESOURCES ;
  678. pIrb->u.IsochQueryResources.fulSpeed = SPEED_FLAGS_100;
  679. pIrb->Flags = 0;
  680. NdisStatus = nicGetIrp ( pDeviceObject, &pIrp);
  681. if (NdisStatus != NDIS_STATUS_SUCCESS)
  682. {
  683. TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicGetIrp FAILED" ) );
  684. break;
  685. }
  686. ASSERT (pIrp != NULL);
  687. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  688. pIrp,
  689. pIrb );
  690. if (NdisStatus != NDIS_STATUS_SUCCESS)
  691. {
  692. TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  693. break;
  694. }
  695. //
  696. // We get the *available* channels, in network-byte order.
  697. // We have to byte reverse and flip the bits to get
  698. // it in the form we want.
  699. //
  700. // Looks like we really have to flip the *bits*, not just the bytes.
  701. //
  702. {
  703. LARGE_INTEGER in, out;
  704. PUCHAR puc;
  705. UINT u;
  706. in = pIrb->u.IsochQueryResources.ChannelsAvailable;
  707. out.LowPart = ~SWAPBYTES_ULONG (in.HighPart );
  708. out.HighPart = ~SWAPBYTES_ULONG (in.LowPart );
  709. // Now swap the bits in each byte.
  710. //
  711. puc = (PUCHAR) &out;
  712. for (u=sizeof(out); u; u--,puc++)
  713. {
  714. UCHAR uc,uc1;
  715. UINT u1;
  716. uc= *puc;
  717. uc1=0;
  718. for (u1=0;u1<8;u1++)
  719. {
  720. if (uc & (1<<u1))
  721. {
  722. uc1 |= (1 << (7-u1));
  723. }
  724. }
  725. *puc = uc1;
  726. }
  727. pChannelsAvailable->QuadPart = out.QuadPart;
  728. }
  729. } while (FALSE);
  730. //
  731. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  732. // functions return immediately
  733. //
  734. nicFreeIrb (pIrb);
  735. nicFreeIrp (pIrp);
  736. MATCH_IRQL;
  737. TRACE( TL_T, TM_Irp, ( "<==nicQueryChannelMap , , Status %x", NdisStatus ) );
  738. return NdisStatus;
  739. }
  740. NDIS_STATUS
  741. nicIsochAllocateBandwidth(
  742. IN PREMOTE_NODE pRemoteNodePdoCb,
  743. IN ULONG MaxBytesPerFrameRequested,
  744. IN ULONG SpeedRequested,
  745. OUT PHANDLE phBandwidth,
  746. OUT PULONG pBytesPerFrameAvailable,
  747. OUT PULONG pSpeedSelected
  748. )
  749. // Function Description:
  750. // This function allocates bandwith on the bus
  751. //
  752. // Arguments
  753. // PdoCb - Remote Nodes Pdo Block
  754. // MaxBytesPerFrame Requested -
  755. // SpeedRequested -
  756. // hBandwidth
  757. // pSpeedSelected
  758. // Bytes Per Frame Available
  759. //
  760. //
  761. // Return Value:
  762. // hBandwidth,
  763. // Speed and
  764. // BytesPerFrameAvailable
  765. //
  766. //
  767. //
  768. {
  769. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  770. PIRB pIrb = NULL;
  771. PIRP pIrp = NULL;
  772. TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateBandwidth, pRemoteNodePdoCb %x", pRemoteNodePdoCb) );
  773. do
  774. {
  775. NdisStatus = nicGetIrb (&pIrb);
  776. if (NdisStatus != NDIS_STATUS_SUCCESS)
  777. {
  778. BREAK( TM_Irp, ( "nicIsochAllocateBandwidth, nicGetIrb FAILED" ) );
  779. }
  780. ASSERT ( pIrb != NULL);
  781. pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_BANDWIDTH;
  782. pIrb->Flags = 0;
  783. pIrb->u.IsochAllocateBandwidth.nMaxBytesPerFrameRequested = MaxBytesPerFrameRequested;
  784. pIrb->u.IsochAllocateBandwidth.fulSpeed = SpeedRequested;
  785. ASSERT (pRemoteNodePdoCb->pPdo != NULL);
  786. NdisStatus = nicGetIrp (pRemoteNodePdoCb->pPdo, &pIrp);
  787. if (NdisStatus != NDIS_STATUS_SUCCESS)
  788. {
  789. BREAK( TM_Irp, ( "nicIsochAllocateBandwidth, nicGetIrp FAILED" ) );
  790. }
  791. ASSERT (pIrp != NULL);
  792. NdisStatus = nicSubmitIrp_Synch ( pRemoteNodePdoCb,
  793. pIrp,
  794. pIrb );
  795. if (NdisStatus != NDIS_STATUS_SUCCESS)
  796. {
  797. TRACE (TL_N, TM_Irp, ( "nicIsochAllocateBandwidth, nicSubmitIrp_Synch FAILED ") );
  798. break;
  799. }
  800. *phBandwidth = pIrb->u.IsochAllocateBandwidth.hBandwidth ;
  801. *pBytesPerFrameAvailable = pIrb->u.IsochAllocateBandwidth.BytesPerFrameAvailable;
  802. *pSpeedSelected = pIrb->u.IsochAllocateBandwidth.SpeedSelected;
  803. TRACE( TL_V, TM_Irp, ( "hBandwidth %x", *phBandwidth) );
  804. TRACE( TL_V, TM_Irp, ( "BytesPerFrameAvailable %x", *pBytesPerFrameAvailable) );
  805. TRACE( TL_V, TM_Irp, ( "SpeedSelected %x", *pSpeedSelected) );
  806. } while (FALSE);
  807. //
  808. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  809. // functions return immediately
  810. //
  811. nicFreeIrb (pIrb);
  812. nicFreeIrp (pIrp);
  813. TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateBandwidth NdisStatus %x", NdisStatus) );
  814. return NdisStatus;
  815. }
  816. NDIS_STATUS
  817. nicAsyncRead_Synch(
  818. PREMOTE_NODE pRemoteNode,
  819. IO_ADDRESS DestinationAddress,
  820. ULONG nNumberOfBytesToRead,
  821. ULONG nBlockSize,
  822. ULONG fulFlags,
  823. PMDL Mdl,
  824. ULONG ulGeneration,
  825. OUT NTSTATUS *pNtStatus
  826. )
  827. // Function Description:
  828. // This is an asyc read operation a remote node;s address space
  829. //
  830. //
  831. //
  832. //
  833. // Arguments
  834. //PREMOTE_NODE pRemoteNode // Remote Node which owns the Destination address
  835. // IO_ADDRESS DestinationAddress; // Address to read from
  836. // ULONG nNumberOfBytesToRead; // Bytes to read
  837. // ULONG nBlockSize; // Block size of read
  838. // ULONG fulFlags; // Flags pertinent to read
  839. // PMDL Mdl; // Destination buffer
  840. // ULONG ulGeneration; // Generation as known by driver
  841. //
  842. // Return Value:
  843. // Success - if successful
  844. // Invalid Generation
  845. //
  846. //
  847. {
  848. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  849. PIRB pIrb = NULL;
  850. PIRP pIrp = NULL;
  851. TRACE( TL_T, TM_Mp, ( "==>nicAsyncRead, Remote Node, %x ", pRemoteNode ) );
  852. TRACE( TL_V, TM_Mp, ( " fulFlags %x, Mdl %x, Generation %x, pNtStatus %x",
  853. fulFlags, Mdl, ulGeneration, pNtStatus ) );
  854. ASSERT(DestinationAddress.IA_Destination_Offset.Off_High == INITIAL_REGISTER_SPACE_HI);
  855. do
  856. {
  857. NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
  858. if (NdisStatus != NDIS_STATUS_SUCCESS)
  859. {
  860. BREAK ( TM_Irp, ( "nicAsyncRead, nicGetIrp FAILED" ) );
  861. break;
  862. }
  863. NdisStatus = nicGetIrb (&pIrb);
  864. if (NdisStatus != NDIS_STATUS_SUCCESS)
  865. {
  866. BREAK ( TM_Irp, ( "nicAsyncRead, nicGetIrb FAILED" ) );
  867. }
  868. ASSERT ( pIrb != NULL);
  869. ASSERT (pIrp != NULL);
  870. pIrb->FunctionNumber = REQUEST_ASYNC_READ;
  871. pIrb->Flags = 0;
  872. pIrb->u.AsyncRead.DestinationAddress = DestinationAddress;
  873. pIrb->u.AsyncRead.nNumberOfBytesToRead = nNumberOfBytesToRead ;
  874. pIrb->u.AsyncRead.nBlockSize = nBlockSize ;
  875. pIrb->u.AsyncRead.fulFlags = fulFlags;
  876. pIrb->u.AsyncRead.Mdl = Mdl;
  877. pIrb->u.AsyncRead.ulGeneration = ulGeneration;
  878. NdisStatus = nicSubmitIrp_Synch ( pRemoteNode,
  879. pIrp,
  880. pIrb );
  881. if (NdisStatus != NDIS_STATUS_SUCCESS)
  882. {
  883. TRACE ( TL_A, TM_Irp, ( "nicAsyncRead, nicSubmitIrp_Synch FAILED %xm pRemoteNode %x", NdisStatus, pRemoteNode) );
  884. break;
  885. }
  886. if (pNtStatus != NULL)
  887. {
  888. *pNtStatus = pIrp->IoStatus.Status;
  889. }
  890. } while (FALSE);
  891. TRACE( TL_T, TM_Mp, ( "<==nicAsyncRead, Status, %x ", NdisStatus) );
  892. nicFreeIrb(pIrb);
  893. nicFreeIrp(pIrp);
  894. return NdisStatus;
  895. }
  896. NDIS_STATUS
  897. nicAsyncWrite_Synch(
  898. PREMOTE_NODE pRemoteNode,
  899. IO_ADDRESS DestinationAddress, // Address to write to
  900. ULONG nNumberOfBytesToWrite, // Bytes to write
  901. ULONG nBlockSize, // Block size of write
  902. ULONG fulFlags, // Flags pertinent to write
  903. PMDL Mdl, // Destination buffer
  904. ULONG ulGeneration, // Generation as known by driver
  905. OUT NTSTATUS *pNtStatus // pointer to NTSTatus returned by the IRP
  906. )
  907. // Function Description:
  908. // This performs an asynchronous write operation in thje remote node's
  909. // address space
  910. //
  911. // Arguments
  912. //PREMOTE_NODE pRemoteNode // Remote Node which owns the Destination address
  913. //IO_ADDRESS DestinationAddress; // Address to write to
  914. //ULONG nNumberOfBytesToWrite; // Bytes to write
  915. //ULONG nBlockSize; // Block size of write
  916. //ULONG fulFlags; // Flags pertinent to write
  917. //PMDL Mdl; // Destination buffer
  918. //ULONG ulGeneration; // Generation as known by driver
  919. //
  920. // Return Value:
  921. // Success - if successful
  922. // Invalid Generation
  923. //
  924. //
  925. {
  926. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  927. PIRB pIrb = NULL;
  928. PIRP pIrp = NULL;
  929. TRACE( TL_T, TM_Mp, ( "==>nicAsyncWrite_Synch, Remote Node, %x ", pRemoteNode ) );
  930. TRACE( TL_V, TM_Mp, ( " Destination %x, nNumberOfBytesToWrite %x, nBlockSize %x",
  931. DestinationAddress, nNumberOfBytesToWrite, nBlockSize) );
  932. TRACE( TL_V, TM_Mp, ( " fulFlags %x, , Mdl %x, Generation %x, pNtStatus %x",
  933. fulFlags , Mdl, ulGeneration, pNtStatus ) );
  934. do
  935. {
  936. NdisStatus = nicGetIrb (&pIrb);
  937. if (NdisStatus != NDIS_STATUS_SUCCESS)
  938. {
  939. BREAK ( TM_Irp, ( "nicAsyncWrite_Synch, nicGetIrb FAILED" ) );
  940. }
  941. ASSERT ( pIrb != NULL);
  942. pIrb->FunctionNumber = REQUEST_ASYNC_WRITE;
  943. pIrb->Flags = 0;
  944. pIrb->u.AsyncWrite.DestinationAddress = DestinationAddress;
  945. pIrb->u.AsyncWrite.nNumberOfBytesToWrite = nNumberOfBytesToWrite;
  946. pIrb->u.AsyncWrite.nBlockSize = nBlockSize;
  947. pIrb->u.AsyncWrite.fulFlags = fulFlags;
  948. pIrb->u.AsyncWrite.Mdl = Mdl;
  949. pIrb->u.AsyncWrite.ulGeneration = ulGeneration;
  950. NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
  951. if (NdisStatus != NDIS_STATUS_SUCCESS)
  952. {
  953. BREAK ( TM_Irp, ( "nicAsyncWrite_Synch, nicGetIrp FAILED" ) );
  954. break;
  955. }
  956. ASSERT (pIrp != NULL);
  957. NdisStatus = nicSubmitIrp_Synch ( pRemoteNode,
  958. pIrp,
  959. pIrb );
  960. if (NdisStatus != NDIS_STATUS_SUCCESS)
  961. {
  962. TRACE ( TL_A, TM_Irp, ( "nicAsyncWrite_Synch, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  963. break;
  964. }
  965. if (pNtStatus != NULL)
  966. {
  967. *pNtStatus = pIrp->IoStatus.Status;
  968. }
  969. } while (FALSE);
  970. TRACE( TL_T, TM_Mp, ( "<==nicAsyncWrite_Synch, Success , %x Nt %x", NdisStatus, pIrp->IoStatus.Status) );
  971. nicFreeIrb (pIrb);
  972. nicFreeIrp (pIrp);
  973. return NdisStatus;
  974. }
  975. NDIS_STATUS
  976. nicIsochAllocateResources (
  977. IN PADAPTERCB pAdapter,
  978. IN ULONG fulSpeed, // Speed flags
  979. IN ULONG fulFlags, // Flags
  980. IN ULONG nChannel, // Channel to be used
  981. IN ULONG nMaxBytesPerFrame, // Expected size of Isoch frame
  982. IN ULONG nNumberOfBuffers, // Number of buffer(s) that will be attached
  983. IN ULONG nMaxBufferSize, // Max size of buffer(s)
  984. IN ULONG nQuadletsToStrip, // Number striped from start of every packet
  985. IN ULARGE_INTEGER uliChannelMask, // ChannelMask for Multiple channels
  986. IN OUT PHANDLE phResource // handle to Resource
  987. )
  988. // Function Description:
  989. // This function sends an allocate resources irp to the driver. The miniport must do this before it
  990. // attempts any channel operation
  991. // Arguments
  992. // Taken from documentation for the IsochAllocateResources
  993. // fulSpeed - should be the max speed the tx side is expected to stream
  994. // The payload size in nMaxBytesPerFram cannot exceed the max payload for
  995. // for this speed.
  996. // fulFlags - For receive, wtih the standard header stripped, the field should
  997. // be = (RESOURCE_USED_IN_LISTEN | RESOURCES_STRIP_ADDITIONAL_QUADLETS)
  998. // Also nQuadletsToStrip = 1
  999. // For no stripping set nQuadsTostrip to 0 and dont specify the stripping flag.
  1000. // nMaxBytesPerframe - If not stripping it should include the 8 bytes for header/trailer
  1001. // expected to be recieved for each packet.
  1002. // nNumberOfBuffer - see below
  1003. // nMaxBufferSize - This should be always such mode(nMaxBufferSize,nMaxBytesPerFrame) == 0
  1004. // (integer product of number of bytes per packet).
  1005. // nQuadletsTostrip - If stripping only one quadlet (standrd iso header) this is set to 1
  1006. // if zero, the isoch header will be included AND the trailer. So 8 bytes extra will be recieved
  1007. // hResource - see below
  1008. // Return Value:
  1009. // Success if the channel was allocated
  1010. // Failure otherwise
  1011. //
  1012. {
  1013. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1014. PIRB pIrb = NULL;
  1015. PIRP pIrp = NULL;
  1016. STORE_CURRENT_IRQL;
  1017. TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateResources ") );
  1018. ASSERT (fulSpeed != 0); // 0 is undefined in ISOCH_SP...
  1019. do
  1020. {
  1021. NdisStatus = nicGetIrb (&pIrb);
  1022. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1023. {
  1024. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicGetIrb FAILED" ) );
  1025. break;
  1026. }
  1027. ASSERT ( pIrb != NULL);
  1028. //
  1029. //Initialize the datastructures in the Irb
  1030. //
  1031. pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_RESOURCES;
  1032. pIrb->Flags = 0;
  1033. pIrb->u.IsochAllocateResources.fulSpeed = fulSpeed;
  1034. pIrb->u.IsochAllocateResources.fulFlags = fulFlags;
  1035. pIrb->u.IsochAllocateResources.nChannel = nChannel;
  1036. pIrb->u.IsochAllocateResources.nMaxBytesPerFrame = nMaxBytesPerFrame;
  1037. pIrb->u.IsochAllocateResources.nNumberOfBuffers = nNumberOfBuffers;
  1038. pIrb->u.IsochAllocateResources.nMaxBufferSize = nMaxBufferSize;
  1039. pIrb->u.IsochAllocateResources.nQuadletsToStrip = nQuadletsToStrip;
  1040. pIrb->u.IsochAllocateResources.ChannelMask = uliChannelMask;
  1041. nicIsochAllocateResourcesDebugSpew(pIrb);
  1042. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  1043. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1044. {
  1045. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicGetIrp FAILED" ) );
  1046. break;
  1047. }
  1048. ASSERT (pIrp != NULL);
  1049. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1050. pIrp,
  1051. pIrb );
  1052. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1053. {
  1054. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1055. break;
  1056. }
  1057. TRACE( TL_N, TM_Irp, ( "nicIsochAllocateResources Succeeded hResource %x", pIrb->u.IsochAllocateResources.hResource) );
  1058. *phResource = pIrb->u.IsochAllocateResources.hResource;
  1059. } while (FALSE);
  1060. //
  1061. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1062. // functions return immediately
  1063. //
  1064. nicFreeIrb (pIrb);
  1065. nicFreeIrp (pIrp);
  1066. TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateResources , Status %x, hResource %x", NdisStatus, *phResource ) );
  1067. MATCH_IRQL;
  1068. return NdisStatus;
  1069. }
  1070. VOID
  1071. nicIsochAllocateResourcesDebugSpew(
  1072. IN PIRB pIrb)
  1073. {
  1074. TRACE( TL_V, TM_Irp, ( " Speed %x", pIrb->u.IsochAllocateResources.fulSpeed ) );
  1075. TRACE( TL_V, TM_Irp, ( " flags %x", pIrb->u.IsochAllocateResources.fulFlags ) );
  1076. TRACE( TL_V, TM_Irp, ( " Channel %x", pIrb->u.IsochAllocateResources.nChannel ) );
  1077. TRACE( TL_V, TM_Irp, ( " nMaxBytesPerFrame %x", pIrb->u.IsochAllocateResources.nMaxBytesPerFrame ) );
  1078. TRACE( TL_V, TM_Irp, ( " nNumberOfBuffers %x", pIrb->u.IsochAllocateResources.nNumberOfBuffers ) );
  1079. TRACE( TL_V, TM_Irp, ( " nMaxBufferSize %x", pIrb->u.IsochAllocateResources.nMaxBufferSize ) );
  1080. TRACE( TL_V, TM_Irp, ( " nQuadletsToStrip %x", pIrb->u.IsochAllocateResources.nQuadletsToStrip ) );
  1081. TRACE( TL_V, TM_Irp, ( " pIrb->u.IsochAllocateResources.ChannelMask %I64x", pIrb->u.IsochAllocateResources.ChannelMask ) );
  1082. }
  1083. NDIS_STATUS
  1084. nicIsochFreeResources(
  1085. IN PADAPTERCB pAdapter,
  1086. IN HANDLE hResource
  1087. )
  1088. // Function Description:
  1089. // Arguments
  1090. //
  1091. // Return Value:
  1092. //
  1093. {
  1094. PIRP pIrp = NULL;
  1095. PIRB pIrb = NULL;
  1096. PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
  1097. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  1098. TRACE( TL_T, TM_Irp, ( "==>nicIsochFreeResources pAdapter %x, hResource %8x", pAdapter, hResource) );
  1099. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  1100. ASSERT (hResource != NULL);
  1101. do
  1102. {
  1103. NdisStatus = nicGetIrb(&pIrb);
  1104. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1105. {
  1106. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicIsochFreeResources" ) );
  1107. break;
  1108. }
  1109. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1110. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1111. {
  1112. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicIsochFreeResources" ) );
  1113. break;
  1114. }
  1115. //
  1116. //Initialize the datastructures in the Irb
  1117. //
  1118. pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
  1119. pIrb->Flags = 0;
  1120. pIrb->u.IsochFreeResources.hResource = hResource;
  1121. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
  1122. pIrp,
  1123. pIrb );
  1124. } while (FALSE);
  1125. //
  1126. // Free the locally allocated memory
  1127. //
  1128. nicFreeIrb(pIrb);
  1129. nicFreeIrp(pIrp);
  1130. //
  1131. // We do not care about the status, because we do not know what to do if it fails.
  1132. // However, spew some debug out.
  1133. //
  1134. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1135. {
  1136. TRACE( TL_N, TM_Irp, ( "nicIsochFreeResources FAILED %x", NdisStatus) );
  1137. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  1138. }
  1139. TRACE( TL_T, TM_Irp, ( "<==nicIsochFreeResources Status %x (always success)", NdisStatus) );
  1140. NdisStatus = NDIS_STATUS_SUCCESS;
  1141. return NdisStatus;
  1142. }
  1143. NDIS_STATUS
  1144. nicIsochModifyStreamProperties (
  1145. PADAPTERCB pAdapter,
  1146. NDIS_HANDLE hResource,
  1147. ULARGE_INTEGER ullChannelMap,
  1148. ULONG ulSpeed)
  1149. /*++
  1150. Routine Description:
  1151. Sets up the Irp and uses the VDO to do an IoCallDriver
  1152. Arguments:
  1153. Return Value:
  1154. --*/
  1155. {
  1156. PIRP pIrp = NULL;
  1157. PIRB pIrb = NULL;
  1158. PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
  1159. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  1160. TRACE( TL_T, TM_Irp, ( "==>nicIsochModifyStreamProperties pAdapter %x, hResource %x, Speed %x, ChannelMap %I64x",
  1161. pAdapter,
  1162. hResource,
  1163. ulSpeed,
  1164. ullChannelMap) );
  1165. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  1166. ASSERT (hResource != NULL);
  1167. do
  1168. {
  1169. NdisStatus = nicGetIrb(&pIrb);
  1170. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1171. {
  1172. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicIsochModifyStreamProperties " ) );
  1173. break;
  1174. }
  1175. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1176. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1177. {
  1178. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicIsochModifyStreamProperties " ) );
  1179. break;
  1180. }
  1181. //
  1182. //Initialize the datastructures in the Irb
  1183. //
  1184. pIrb->FunctionNumber = REQUEST_ISOCH_MODIFY_STREAM_PROPERTIES ;
  1185. pIrb->Flags = 0;
  1186. pIrb->u.IsochModifyStreamProperties.hResource = hResource;
  1187. pIrb->u.IsochModifyStreamProperties.ChannelMask = ullChannelMap;
  1188. pIrb->u.IsochModifyStreamProperties.fulSpeed = ulSpeed;
  1189. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
  1190. pIrp,
  1191. pIrb );
  1192. } while (FALSE);
  1193. //
  1194. // Free the locally allocated memory
  1195. //
  1196. nicFreeIrb(pIrb);
  1197. nicFreeIrp(pIrp);
  1198. //
  1199. // We do not care about the status, because we do not know what to do if it fails.
  1200. // However, spew some debug out.
  1201. //
  1202. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1203. {
  1204. TRACE( TL_N, TM_Irp, ( "nicIsochModifyStreamProperties FAILED %x", NdisStatus) );
  1205. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  1206. }
  1207. TRACE( TL_T, TM_Irp, ( "<==nicIsochModifyStreamProperties Status %x (always success)", NdisStatus) );
  1208. return NdisStatus;
  1209. }
  1210. NDIS_STATUS
  1211. nicBusReset (
  1212. IN PADAPTERCB pAdapter,
  1213. IN OUT ULONG fulFlags
  1214. )
  1215. // Function Description:
  1216. // This function sends an Irp to the Bus driver to reset the bus
  1217. // Any remote Pdo can be used for the Irp.
  1218. // A flag can be set to force the root to be reset
  1219. // Arguments
  1220. // PdoCb The Pdo for the remote node to which the Irp is submitted
  1221. //
  1222. // Return Value:
  1223. // Success if the Irp Succeeded
  1224. // Failure otherwise
  1225. //
  1226. {
  1227. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1228. PIRB pIrb = NULL;
  1229. PIRP pIrp = NULL;
  1230. PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
  1231. STORE_CURRENT_IRQL;
  1232. TRACE( TL_T, TM_Irp, ( "==>nicBusReset , PdoCb, %x Flags %x", pAdapter, fulFlags ) );
  1233. ASSERT (pPdo != NULL);
  1234. do
  1235. {
  1236. NdisStatus = nicGetIrb (&pIrb);
  1237. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1238. {
  1239. TRACE( TL_A, TM_Irp, ( "nicBusReset , nicGetIrb FAILED" ) );
  1240. break;
  1241. }
  1242. ASSERT ( pIrb != NULL);
  1243. //
  1244. //Initialize the datastructures in the Irb
  1245. //
  1246. pIrb->FunctionNumber = REQUEST_BUS_RESET;
  1247. pIrb->Flags = 0;
  1248. pIrb->u.BusReset.fulFlags = fulFlags;
  1249. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1250. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1251. {
  1252. TRACE( TL_A, TM_Irp, ( "nicBusReset, nicGetIrp FAILED" ) );
  1253. break;
  1254. }
  1255. ASSERT (pIrp != NULL);
  1256. TRACE( TL_N, TM_Irp, ( "BUS RESET, Flags%d on pAdapter %x", fulFlags, pAdapter) );
  1257. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1258. pIrp,
  1259. pIrb );
  1260. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1261. {
  1262. TRACE( TL_A, TM_Irp, ( "nicBusReset , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1263. break;
  1264. }
  1265. NdisInterlockedIncrement (&pAdapter->AdaptStats.ulNumResetsIssued);
  1266. } while (FALSE);
  1267. //
  1268. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1269. // functions return immediately
  1270. //
  1271. nicFreeIrb (pIrb);
  1272. nicFreeIrp (pIrp);
  1273. TRACE( TL_T, TM_Irp, ( "<==nicBusReset %x", NdisStatus ) );
  1274. MATCH_IRQL;
  1275. return NdisStatus;
  1276. }
  1277. NDIS_STATUS
  1278. nicBusResetNotification (
  1279. IN PADAPTERCB pAdapter,
  1280. IN ULONG fulFlags,
  1281. IN PBUS_BUS_RESET_NOTIFICATION pResetRoutine,
  1282. IN PVOID pResetContext
  1283. )
  1284. // Function Description:
  1285. // This function sends an Irp to the Bus driver to register/deregister
  1286. // a notification routine. Any remote Pdo can be used for the Irp.
  1287. //
  1288. // Arguments
  1289. // PdoCb The Pdo for the remote node to which the Irp is submitted
  1290. //
  1291. // Return Value:
  1292. // Success if the Irp Succeeded
  1293. // Failure otherwise
  1294. //
  1295. {
  1296. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1297. PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
  1298. PIRB pIrb = NULL;
  1299. PIRP pIrp = NULL;
  1300. STORE_CURRENT_IRQL;
  1301. TRACE( TL_T, TM_Irp, ( "==>nicBusResetNotification, pAdapter %x, Flags %x, Routine %x, Context %x", pAdapter, fulFlags, pResetRoutine, pResetContext ) );
  1302. ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
  1303. do
  1304. {
  1305. NdisStatus = nicGetIrb (&pIrb);
  1306. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1307. {
  1308. TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicGetIrb FAILED" ) );
  1309. break;
  1310. }
  1311. ASSERT ( pIrb != NULL);
  1312. //
  1313. //Initialize the datastructures in the Irb
  1314. //
  1315. pIrb->FunctionNumber = REQUEST_BUS_RESET_NOTIFICATION;
  1316. pIrb->Flags = 0;
  1317. pIrb->u.BusResetNotification.fulFlags = fulFlags;
  1318. pIrb->u.BusResetNotification.ResetRoutine = pResetRoutine;
  1319. pIrb->u.BusResetNotification.ResetContext= pResetContext;
  1320. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1321. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1322. {
  1323. TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicGetIrp FAILED" ) );
  1324. break;
  1325. }
  1326. ASSERT (pIrp != NULL);
  1327. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1328. pIrp,
  1329. pIrb );
  1330. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1331. {
  1332. TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1333. break;
  1334. }
  1335. TRACE( TL_N, TM_Irp, ( " nicBusResetNotification success, Flags %d on pAdapter %x", fulFlags, pAdapter) );
  1336. } while (FALSE);
  1337. //
  1338. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1339. // functions return immediately
  1340. //
  1341. nicFreeIrb (pIrb);
  1342. nicFreeIrp (pIrp);
  1343. MATCH_IRQL;
  1344. TRACE( TL_T, TM_Irp, ( "<==nicBusResetNotification %x", NdisStatus ) );
  1345. return NdisStatus;
  1346. }
  1347. NDIS_STATUS
  1348. nicGetMaxSpeedBetweenDevices (
  1349. PADAPTERCB pAdapter,
  1350. UINT NumOfRemoteNodes,
  1351. PDEVICE_OBJECT pArrayDestinationPDO[MAX_LOCAL_NODES],
  1352. PULONG pSpeed
  1353. )
  1354. // Function Description:
  1355. // This function submits an irp to the bus driver
  1356. // to get the max speed between 2 nodes
  1357. // Uses REQUEST_GET_SPEED_BETWEEN_DEVICES
  1358. //
  1359. //
  1360. // Arguments
  1361. // Remote Node Start of an array of PDOs for remote nodes
  1362. // NumOfRemoteNodes The number of remote nodes we are interested in
  1363. // pArrayDestinationPDO = Array of Destination PDO's
  1364. // Return Value:
  1365. // Success if irp succeeded
  1366. // pSpeed will point to the Speed
  1367. //
  1368. {
  1369. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1370. PIRB pIrb = NULL;
  1371. PIRP pIrp = NULL;
  1372. ULONG NumRemote = NumOfRemoteNodes;
  1373. TRACE( TL_T, TM_Irp, ( "==>nicGetMaxSpeedBetweenDevices pRemoteNodeArray %x",
  1374. pArrayDestinationPDO ) );
  1375. TRACE( TL_T, TM_Irp, ( "==>NumOfRemoteNodes %x, pSpeed %x",
  1376. NumOfRemoteNodes, pSpeed ) );
  1377. do
  1378. {
  1379. NdisStatus = nicGetIrb (&pIrb);
  1380. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1381. {
  1382. TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicGetIrb FAILED" ) );
  1383. break;
  1384. }
  1385. ASSERT ( pIrb != NULL);
  1386. while (NumRemote != 0)
  1387. {
  1388. pIrb->u.GetMaxSpeedBetweenDevices.hDestinationDeviceObjects[NumRemote-1] = pArrayDestinationPDO[NumRemote-1];
  1389. NumRemote --;
  1390. }
  1391. //
  1392. //Initialize the datastructures in the Irb
  1393. //
  1394. pIrb->FunctionNumber = REQUEST_GET_SPEED_BETWEEN_DEVICES;
  1395. pIrb->Flags = 0;
  1396. pIrb->u.GetMaxSpeedBetweenDevices.fulFlags = USE_LOCAL_NODE;
  1397. pIrb->u.GetMaxSpeedBetweenDevices.ulNumberOfDestinations = NumOfRemoteNodes;
  1398. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  1399. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1400. {
  1401. TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicGetIrp FAILED" ) );
  1402. break;
  1403. }
  1404. ASSERT (pIrp != NULL);
  1405. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1406. pIrp,
  1407. pIrb );
  1408. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1409. {
  1410. TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1411. break;
  1412. }
  1413. *pSpeed = pIrb->u.GetMaxSpeedBetweenDevices.fulSpeed ;
  1414. } while (FALSE);
  1415. //
  1416. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1417. // functions return immediately
  1418. //
  1419. nicFreeIrb (pIrb);
  1420. nicFreeIrp (pIrp);
  1421. TRACE( TL_T, TM_Irp, ( "<==nicGetMaxSpeedBetweenDevices Status %x, Speed %x",
  1422. NdisStatus, *pSpeed ) );
  1423. return NdisStatus;
  1424. }
  1425. NDIS_STATUS
  1426. nicIsochAttachBuffers (
  1427. IN PADAPTERCB pAdapter,
  1428. IN HANDLE hResource,
  1429. IN ULONG nNumberOfDescriptors,
  1430. PISOCH_DESCRIPTOR pIsochDescriptor
  1431. )
  1432. // Function Description:
  1433. //
  1434. // Arguments
  1435. //
  1436. // Return Value:
  1437. // Success if the Irp Succeeded
  1438. // Failure otherwise
  1439. //
  1440. {
  1441. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1442. PIRB pIrb = NULL;
  1443. PIRP pIrp = NULL;
  1444. STORE_CURRENT_IRQL;
  1445. ASSERT (pIsochDescriptor!=NULL);
  1446. ASSERT (hResource != NULL);
  1447. ASSERT (nNumberOfDescriptors > 0);
  1448. TRACE( TL_T, TM_Irp, ( "==>nicIsochAttachBuffers, pAdapter, %x ", pAdapter) );
  1449. TRACE( TL_N, TM_Irp, ( "hResource %x, nNumberOfDescriptors %x, pIsochDescriptor %x, ", hResource, nNumberOfDescriptors, pIsochDescriptor ) );
  1450. do
  1451. {
  1452. NdisStatus = nicGetIrb (&pIrb);
  1453. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1454. {
  1455. TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers, nicGetIrb FAILED" ) );
  1456. break;
  1457. }
  1458. ASSERT ( pIrb != NULL);
  1459. //
  1460. //Initialize the datastructures in the Irb
  1461. //
  1462. pIrb->FunctionNumber = REQUEST_ISOCH_ATTACH_BUFFERS;
  1463. pIrb->Flags = 0;
  1464. pIrb->u.IsochAttachBuffers.hResource = hResource ;
  1465. pIrb->u.IsochAttachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
  1466. pIrb->u.IsochAttachBuffers.pIsochDescriptor = pIsochDescriptor;
  1467. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  1468. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1469. {
  1470. TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers , nicGetIrp FAILED" ) );
  1471. break;
  1472. }
  1473. ASSERT (pIrp != NULL);
  1474. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1475. pIrp,
  1476. pIrb );
  1477. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1478. {
  1479. TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1480. break;
  1481. }
  1482. TRACE( TL_N, TM_Irp, ( "nicIsochAttachBuffers success") );
  1483. } while (FALSE);
  1484. //
  1485. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1486. // functions return immediately
  1487. //
  1488. nicFreeIrb (pIrb);
  1489. nicFreeIrp (pIrp);
  1490. MATCH_IRQL;
  1491. TRACE( TL_T, TM_Irp, ( "<==nicIsochAttachBuffers %x", NdisStatus ) );
  1492. return NdisStatus;
  1493. }
  1494. NDIS_STATUS
  1495. nicIsochDetachBuffers (
  1496. IN PADAPTERCB pAdapter,
  1497. IN HANDLE hResource,
  1498. IN ULONG nNumberOfDescriptors,
  1499. PISOCH_DESCRIPTOR pIsochDescriptor
  1500. )
  1501. // Function Description:
  1502. //
  1503. // Arguments
  1504. // HANDLE hResource; // Resource handle
  1505. // ULONG nNumberOfDescriptors; // Number to detach
  1506. // PISOCH_DESCRIPTOR pIsochDescriptor; // Pointer to Isoch descriptors - same as
  1507. // pointer used in Attach Buffers
  1508. // Return Status :
  1509. // Success if the Irp succeeded
  1510. //
  1511. {
  1512. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1513. PIRB pIrb = NULL;
  1514. PIRP pIrp = NULL;
  1515. PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
  1516. STORE_CURRENT_IRQL;
  1517. ASSERT (pIsochDescriptor!=NULL);
  1518. ASSERT (hResource != NULL);
  1519. ASSERT (nNumberOfDescriptors > 0);
  1520. TRACE( TL_T, TM_Irp, ( "==>nicIsochDetachBuffers, ") );
  1521. TRACE( TL_V, TM_Irp, ( "hResource %x, nNumberOfDescriptors %x, pIsochDescriptor %x, ", hResource, nNumberOfDescriptors, pIsochDescriptor ) );
  1522. do
  1523. {
  1524. NdisStatus = nicGetIrb (&pIrb);
  1525. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1526. {
  1527. TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers, nicGetIrb FAILED" ) );
  1528. break;
  1529. }
  1530. ASSERT ( pIrb != NULL);
  1531. //
  1532. //Initialize the datastructures in the Irb
  1533. //
  1534. pIrb->FunctionNumber = REQUEST_ISOCH_DETACH_BUFFERS;
  1535. pIrb->Flags = 0;
  1536. pIrb->u.IsochDetachBuffers.hResource = hResource ;
  1537. pIrb->u.IsochDetachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
  1538. pIrb->u.IsochDetachBuffers.pIsochDescriptor = pIsochDescriptor;
  1539. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1540. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1541. {
  1542. TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers , nicGetIrp FAILED" ) );
  1543. break;
  1544. }
  1545. ASSERT (pIrp != NULL);
  1546. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1547. pIrp,
  1548. pIrb );
  1549. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1550. {
  1551. TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1552. break;
  1553. }
  1554. TRACE( TL_V, TM_Irp, ( "nicIsochDetachBuffers success, ") );
  1555. } while (FALSE);
  1556. //
  1557. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1558. // functions return immediately
  1559. //
  1560. nicFreeIrb (pIrb);
  1561. nicFreeIrp (pIrp);
  1562. MATCH_IRQL;
  1563. TRACE( TL_T, TM_Irp, ( "<==nicIsochDetachBuffers %x", NdisStatus ) );
  1564. return NdisStatus;
  1565. }
  1566. NDIS_STATUS
  1567. nicIsochListen (
  1568. IN PADAPTERCB pAdapter,
  1569. HANDLE hResource,
  1570. ULONG fulFlags,
  1571. CYCLE_TIME StartTime
  1572. )
  1573. // Function Description:
  1574. // Activates the bus driver to listen to data on that channel
  1575. // Arguments
  1576. // RemoteNode - Remote Node
  1577. // hResource - Handle to resource with ISochDescriptors
  1578. // Flags - not used yet
  1579. // Return Value:
  1580. // Success if the Irp Succeeded
  1581. // Failure otherwise
  1582. //
  1583. {
  1584. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1585. PIRB pIrb = NULL;
  1586. PIRP pIrp = NULL;
  1587. STORE_CURRENT_IRQL;
  1588. ASSERT (hResource != NULL);
  1589. TRACE( TL_T, TM_Irp, ( "==>nicIsochListen, pAdapter %x, hResource %x ", pAdapter,hResource) );
  1590. do
  1591. {
  1592. NdisStatus = nicGetIrb (&pIrb);
  1593. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1594. {
  1595. TRACE( TL_A, TM_Irp, ( "nicIsochListen, nicGetIrb FAILED" ) );
  1596. break;
  1597. }
  1598. ASSERT ( pIrb != NULL);
  1599. //
  1600. //Initialize the datastructures in the Irb
  1601. //
  1602. pIrb->FunctionNumber = REQUEST_ISOCH_LISTEN;
  1603. pIrb->Flags = 0;
  1604. pIrb->u.IsochListen.hResource = hResource ;
  1605. pIrb->u.IsochListen.fulFlags = fulFlags;
  1606. pIrb->u.IsochListen.StartTime = StartTime;
  1607. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  1608. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1609. {
  1610. TRACE( TL_A, TM_Irp, ( "nicIsochListen , nicGetIrp FAILED" ) );
  1611. break;
  1612. }
  1613. ASSERT (pIrp != NULL);
  1614. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1615. pIrp,
  1616. pIrb );
  1617. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1618. {
  1619. TRACE( TL_A, TM_Irp, ( "nicIsochListen , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1620. break;
  1621. }
  1622. TRACE( TL_N, TM_Irp, ( "nicIsochListen success, pAdapter %x", pAdapter) );
  1623. } while (FALSE);
  1624. //
  1625. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1626. // functions return immediately
  1627. //
  1628. nicFreeIrb (pIrb);
  1629. nicFreeIrp (pIrp);
  1630. MATCH_IRQL;
  1631. TRACE( TL_T, TM_Irp, ( "<==nicIsochListen %x", NdisStatus ) );
  1632. return NdisStatus;
  1633. }
  1634. NDIS_STATUS
  1635. nicIsochStop (
  1636. IN PADAPTERCB pAdapter,
  1637. IN HANDLE hResource
  1638. )
  1639. // Function Description:
  1640. // Issues an IsochStop Irp to the Device
  1641. // Should stop Isoch IO on that resource
  1642. // Arguments
  1643. // PdoCb The Pdo for the remote node to which the Irp is submitted
  1644. //
  1645. // Return Value:
  1646. // Success if the Irp Succeeded
  1647. // Failure otherwise
  1648. //
  1649. {
  1650. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1651. PIRB pIrb = NULL;
  1652. PIRP pIrp = NULL;
  1653. PDEVICE_OBJECT pPdo = pAdapter->pNextDeviceObject;
  1654. STORE_CURRENT_IRQL;
  1655. TRACE( TL_T, TM_Irp, ( "==>nicIsochStop , pPdo, %x hResource %x", pPdo, hResource) );
  1656. do
  1657. {
  1658. NdisStatus = nicGetIrb (&pIrb);
  1659. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1660. {
  1661. TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicGetIrb FAILED" ) );
  1662. break;
  1663. }
  1664. ASSERT ( pIrb != NULL);
  1665. //
  1666. //Initialize the datastructures in the Irb
  1667. //
  1668. pIrb->FunctionNumber = REQUEST_ISOCH_STOP;
  1669. pIrb->Flags = 0;
  1670. pIrb->u.IsochStop.hResource = hResource;
  1671. pIrb->u.IsochStop.fulFlags = 0;
  1672. NdisStatus = nicGetIrp (pPdo, &pIrp);
  1673. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1674. {
  1675. TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicGetIrp FAILED" ) );
  1676. break;
  1677. }
  1678. ASSERT (pIrp != NULL);
  1679. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1680. pIrp,
  1681. pIrb );
  1682. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1683. {
  1684. TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1685. break;
  1686. }
  1687. } while (FALSE);
  1688. //
  1689. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1690. // functions return immediately
  1691. //
  1692. nicFreeIrb (pIrb);
  1693. nicFreeIrp (pIrp);
  1694. MATCH_IRQL;
  1695. TRACE( TL_T, TM_Irp, ( "<== nicIsochStop , Status ", NdisStatus) );
  1696. return NdisStatus;
  1697. }
  1698. NDIS_STATUS
  1699. nicGetLocalHostCSRTopologyMap(
  1700. IN PADAPTERCB pAdapter,
  1701. IN PULONG pLength,
  1702. IN PVOID pBuffer
  1703. )
  1704. // Function Description:
  1705. // Retrieves the local hosts CSR.
  1706. // Arguments
  1707. // pBuffer - LocalHostBuffer
  1708. //
  1709. // Return Value:
  1710. // Success if the Irp Succeeded
  1711. // Failure otherwise
  1712. //
  1713. {
  1714. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1715. PIRB pIrb = NULL;
  1716. PIRP pIrp = NULL;
  1717. GET_LOCAL_HOST_INFO6 LocalHostInfo6;
  1718. STORE_CURRENT_IRQL;
  1719. ASSERT (pLength != NULL);
  1720. ASSERT (pBuffer != NULL);
  1721. TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostCSRTopologyMap , pAdapter %x ,Length %x, Buffer",
  1722. pAdapter, *pLength, pBuffer) );
  1723. do
  1724. {
  1725. NdisStatus = nicGetIrb (&pIrb);
  1726. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1727. {
  1728. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrb FAILED" ) );
  1729. break;
  1730. }
  1731. ASSERT ( pIrb != NULL);
  1732. //
  1733. //Initialize the datastructures in the Irb
  1734. //
  1735. LocalHostInfo6.CsrBaseAddress.Off_High = INITIAL_REGISTER_SPACE_HI;
  1736. LocalHostInfo6.CsrBaseAddress.Off_Low = TOPOLOGY_MAP_LOCATION;
  1737. LocalHostInfo6.CsrDataLength = *pLength;
  1738. LocalHostInfo6.CsrDataBuffer = pBuffer;
  1739. pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
  1740. pIrb->Flags = 0;
  1741. pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CSR_CONTENTS;
  1742. pIrb->u.GetLocalHostInformation.Information = &LocalHostInfo6;
  1743. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  1744. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1745. {
  1746. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrp FAILED" ) );
  1747. break;
  1748. }
  1749. ASSERT (pIrp != NULL);
  1750. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1751. pIrp,
  1752. pIrb );
  1753. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1754. {
  1755. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1756. TRACE( TL_A, TM_Irp, ( "Length Needed %.x", LocalHostInfo6.CsrDataLength) );
  1757. if (pIrp->IoStatus.Status == STATUS_INVALID_BUFFER_SIZE)
  1758. {
  1759. *pLength = LocalHostInfo6.CsrDataLength;
  1760. }
  1761. break;
  1762. }
  1763. } while (FALSE);
  1764. //
  1765. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1766. // functions return immediately
  1767. //
  1768. nicFreeIrb (pIrb);
  1769. nicFreeIrp (pIrp);
  1770. MATCH_IRQL;
  1771. TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
  1772. return NdisStatus;
  1773. }
  1774. NDIS_STATUS
  1775. nicGetLocalHostConfigRom(
  1776. IN PADAPTERCB pAdapter,
  1777. OUT PVOID *ppCRom
  1778. )
  1779. // Function Description:
  1780. // Retrieves the local hosts CSR.
  1781. // Arguments
  1782. // pBuffer - Locally allocated. Caller has to free
  1783. //
  1784. // Return Value:
  1785. // Success if the Irp Succeeded
  1786. // Failure otherwise
  1787. //
  1788. {
  1789. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1790. PIRB pIrb = NULL;
  1791. PIRP pIrp = NULL;
  1792. GET_LOCAL_HOST_INFO5 Info;
  1793. PVOID pCRom;
  1794. STORE_CURRENT_IRQL;
  1795. TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostConfigRom, pAdapter %x ",
  1796. pAdapter) );
  1797. do
  1798. {
  1799. NdisStatus = nicGetIrb (&pIrb);
  1800. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1801. {
  1802. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom , nicGetIrb FAILED" ) );
  1803. break;
  1804. }
  1805. ASSERT ( pIrb != NULL);
  1806. Info.ConfigRom = NULL;
  1807. Info.ConfigRomLength = 0;
  1808. pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO ;
  1809. pIrb->Flags = 0;
  1810. pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CONFIG_ROM;
  1811. pIrb->u.GetLocalHostInformation.Information = &Info;
  1812. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  1813. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1814. {
  1815. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom , nicGetIrp FAILED" ) );
  1816. break;
  1817. }
  1818. ASSERT (pIrp != NULL);
  1819. //
  1820. // First find the length
  1821. //
  1822. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1823. pIrp,
  1824. pIrb );
  1825. if (Info.ConfigRomLength == 0)
  1826. {
  1827. NdisStatus = NDIS_STATUS_FAILURE;
  1828. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1829. break;
  1830. }
  1831. nicFreeIrp (pIrp);
  1832. pIrp = NULL;
  1833. pCRom = ALLOC_NONPAGED (Info.ConfigRomLength, 'C31N');
  1834. if (pCRom == NULL)
  1835. {
  1836. NdisStatus = NDIS_STATUS_FAILURE;
  1837. break;
  1838. }
  1839. Info.ConfigRom = pCRom;
  1840. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  1841. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1842. {
  1843. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicGetIrp FAILED" ) );
  1844. break;
  1845. }
  1846. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1847. pIrp,
  1848. pIrb );
  1849. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1850. {
  1851. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicGetIrp FAILED" ) );
  1852. break;
  1853. }
  1854. *ppCRom = pCRom;
  1855. } while (FALSE);
  1856. //
  1857. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1858. // functions return immediately
  1859. //
  1860. nicFreeIrb (pIrb);
  1861. nicFreeIrp (pIrp);
  1862. MATCH_IRQL;
  1863. TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
  1864. return NdisStatus;
  1865. }
  1866. NDIS_STATUS
  1867. nicGetConfigRom(
  1868. IN PDEVICE_OBJECT pPdo,
  1869. OUT PVOID *ppCrom
  1870. )
  1871. // Function Description:
  1872. // Retrieves the Config Rom from the Device Object.
  1873. // Caller responsibility to free this memory.
  1874. // Arguments
  1875. // pBuffer - LocalHostBuffer
  1876. //
  1877. // Return Value:
  1878. // Success if the Irp Succeeded
  1879. // Failure otherwise
  1880. //
  1881. {
  1882. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1883. PIRB pIrb = NULL;
  1884. PIRP pIrp = NULL;
  1885. ULONG SizeNeeded= 0;
  1886. PVOID pConfigInfoBuffer;
  1887. STORE_CURRENT_IRQL;
  1888. TRACE( TL_T, TM_Irp, ( "==>nicGetConfigRom, pPdo %x ",pPdo ) );
  1889. do
  1890. {
  1891. NdisStatus = nicGetIrb (&pIrb);
  1892. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1893. {
  1894. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrb FAILED" ) );
  1895. break;
  1896. }
  1897. ASSERT ( pIrb != NULL);
  1898. pIrb->FunctionNumber = REQUEST_GET_CONFIGURATION_INFO;
  1899. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1900. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1901. {
  1902. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicGetIrp FAILED" ) );
  1903. break;
  1904. }
  1905. ASSERT (pIrp != NULL);
  1906. NdisStatus = nicSubmitIrp_PDOSynch ( pPdo,
  1907. pIrp,
  1908. pIrb );
  1909. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1910. {
  1911. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1912. break;
  1913. }
  1914. nicFreeIrp (pIrp);
  1915. //
  1916. // Clear the Irp so that it will not be double freed if we fail
  1917. //
  1918. pIrp = NULL;
  1919. SizeNeeded = sizeof(CONFIG_ROM) +pIrb->u.GetConfigurationInformation.UnitDirectoryBufferSize +
  1920. pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize +
  1921. pIrb->u.GetConfigurationInformation.VendorLeafBufferSize +
  1922. pIrb->u.GetConfigurationInformation.ModelLeafBufferSize;
  1923. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom , SixeNeeded %x", SizeNeeded) );
  1924. pConfigInfoBuffer = ALLOC_NONPAGED (SizeNeeded , 'C13N');
  1925. if (pConfigInfoBuffer == NULL)
  1926. {
  1927. NdisStatus = NDIS_STATUS_FAILURE;
  1928. break;
  1929. }
  1930. pIrb->u.GetConfigurationInformation.ConfigRom = (PCONFIG_ROM)pConfigInfoBuffer;
  1931. pIrb->u.GetConfigurationInformation.UnitDirectory = (PVOID)((PUCHAR)pConfigInfoBuffer + sizeof(CONFIG_ROM));
  1932. pIrb->u.GetConfigurationInformation.UnitDependentDirectory = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.UnitDirectory +
  1933. pIrb->u.GetConfigurationInformation.UnitDirectoryBufferSize);
  1934. pIrb->u.GetConfigurationInformation.VendorLeaf = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.UnitDependentDirectory +
  1935. pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize);
  1936. pIrb->u.GetConfigurationInformation.ModelLeaf = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.VendorLeaf +
  1937. pIrb->u.GetConfigurationInformation.VendorLeafBufferSize);
  1938. pIrb->FunctionNumber = REQUEST_GET_CONFIGURATION_INFO;
  1939. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1940. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1941. {
  1942. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicGetIrp FAILED" ) );
  1943. break;
  1944. }
  1945. ASSERT (pIrp != NULL);
  1946. NdisStatus = nicSubmitIrp_PDOSynch ( pPdo,
  1947. pIrp,
  1948. pIrb );
  1949. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1950. {
  1951. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1952. break;
  1953. }
  1954. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, pConfigRom %x, Size %x", pConfigInfoBuffer , SizeNeeded ) );
  1955. *ppCrom = pConfigInfoBuffer;
  1956. } while (FALSE);
  1957. //
  1958. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1959. // functions return immediately
  1960. //
  1961. nicFreeIrb (pIrb);
  1962. nicFreeIrp (pIrp);
  1963. MATCH_IRQL;
  1964. TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
  1965. return NdisStatus;
  1966. }
  1967. NDIS_STATUS
  1968. nicGetReadWriteCapLocalHost(
  1969. IN PADAPTERCB pAdapter,
  1970. PGET_LOCAL_HOST_INFO2 pReadWriteCaps
  1971. )
  1972. /*++
  1973. Routine Description:
  1974. Gets the ReadWrite Capabilities for the local host
  1975. Arguments:
  1976. ReadWriteCaps - To be filled up byt the bus driver
  1977. Return Value:
  1978. --*/
  1979. {
  1980. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1981. PIRB pIrb = NULL;
  1982. PIRP pIrp = NULL;
  1983. STORE_CURRENT_IRQL;
  1984. TRACE( TL_T, TM_Irp, ( "==>nicGetReadWriteCapLocalHost, pAdapter %x pReadWriteCaps %x",
  1985. pAdapter, pReadWriteCaps) );
  1986. do
  1987. {
  1988. NdisStatus = nicGetIrb (&pIrb);
  1989. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1990. {
  1991. TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost , nicGetIrb FAILED" ) );
  1992. break;
  1993. }
  1994. ASSERT ( pIrb != NULL);
  1995. //
  1996. //Initialize the datastructures in the Irb
  1997. //
  1998. NdisZeroMemory (pReadWriteCaps, sizeof(*pReadWriteCaps));
  1999. pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
  2000. pIrb->Flags = 0;
  2001. pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CAPABILITIES;
  2002. pIrb->u.GetLocalHostInformation.Information = pReadWriteCaps;
  2003. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  2004. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2005. {
  2006. TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost, nicGetIrp FAILED" ) );
  2007. break;
  2008. }
  2009. ASSERT (pIrp != NULL);
  2010. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2011. pIrp,
  2012. pIrb );
  2013. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2014. {
  2015. TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2016. break;
  2017. }
  2018. } while (FALSE);
  2019. //
  2020. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2021. // functions return immediately
  2022. //
  2023. nicFreeIrb (pIrb);
  2024. nicFreeIrp (pIrp);
  2025. MATCH_IRQL;
  2026. TRACE( TL_T, TM_Irp, ( "<== nicGetReadWriteCapLocalHost, Status %x", NdisStatus) );
  2027. return NdisStatus;
  2028. }
  2029. NDIS_STATUS
  2030. nicSetLocalHostPropertiesCRom (
  2031. IN PADAPTERCB pAdapter,
  2032. IN PUCHAR pConfigRom,
  2033. IN ULONG Length,
  2034. IN ULONG Flags,
  2035. IN OUT PHANDLE phCromData,
  2036. IN OUT PMDL *ppConfigRomMdl
  2037. )
  2038. // Function Description:
  2039. // Allocates an MDL pointing to the Buffer
  2040. // and sends it to the bus driver
  2041. //
  2042. // Arguments
  2043. // pAdapter - Local host
  2044. // ConfigRom - Buffer to be sent to the bus driver
  2045. // Length - Length of the Config Rom Buffer
  2046. // Flags - Add or remove
  2047. // phConfigRom - if Remove then this is an input parameter
  2048. // Return Value:
  2049. // Handle - Is successful
  2050. //
  2051. {
  2052. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2053. PIRB pIrb = NULL;
  2054. PIRP pIrp = NULL;
  2055. PMDL pMdl = NULL;
  2056. SET_LOCAL_HOST_PROPS3 SetLocalHost3;
  2057. TRACE( TL_T, TM_Irp, ( "==>nicSetLocalHostPropertiesCRom , pAdapter %x, pConfigRom %x",pAdapter, pConfigRom) );
  2058. if (Flags == SLHP_FLAG_ADD_CROM_DATA)
  2059. {
  2060. TRACE( TL_T, TM_Irp, ( " ADD") );
  2061. }
  2062. else
  2063. {
  2064. TRACE( TL_T, TM_Irp, ( " REMOVE Handle %x", *pConfigRom) );
  2065. }
  2066. do
  2067. {
  2068. //
  2069. // Get an mdl describing the config rom
  2070. //
  2071. NdisStatus = nicGetIrb (&pIrb);
  2072. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2073. {
  2074. TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrb FAILED" ) );
  2075. break;
  2076. }
  2077. ASSERT ( pIrb != NULL);
  2078. //
  2079. // Initialize the set local host struct
  2080. //
  2081. if (Flags == SLHP_FLAG_ADD_CROM_DATA)
  2082. {
  2083. NdisStatus = nicGetMdl ( Length, pConfigRom, &pMdl);
  2084. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2085. {
  2086. TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrb FAILED" ) );
  2087. break;
  2088. }
  2089. SetLocalHost3.fulFlags = SLHP_FLAG_ADD_CROM_DATA;
  2090. SetLocalHost3.hCromData = NULL;
  2091. SetLocalHost3.nLength = Length;
  2092. SetLocalHost3.Mdl = pMdl;
  2093. }
  2094. else
  2095. {
  2096. SetLocalHost3.fulFlags = SLHP_FLAG_REMOVE_CROM_DATA ;
  2097. ASSERT (phCromData != NULL);
  2098. SetLocalHost3.hCromData = *phCromData;
  2099. }
  2100. pIrb->FunctionNumber = REQUEST_SET_LOCAL_HOST_PROPERTIES;
  2101. pIrb->Flags = 0;
  2102. pIrb->u.GetLocalHostInformation.nLevel = SET_LOCAL_HOST_PROPERTIES_MODIFY_CROM;
  2103. pIrb->u.GetLocalHostInformation.Information = &SetLocalHost3;
  2104. //
  2105. // Get an Irp
  2106. //
  2107. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  2108. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2109. {
  2110. TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrp FAILED" ) );
  2111. break;
  2112. }
  2113. ASSERT (pIrp != NULL);
  2114. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2115. pIrp,
  2116. pIrb );
  2117. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2118. {
  2119. TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2120. break;
  2121. }
  2122. if (Flags == SLHP_FLAG_ADD_CROM_DATA)
  2123. {
  2124. *phCromData = SetLocalHost3.hCromData;
  2125. *ppConfigRomMdl = pMdl;
  2126. }
  2127. else
  2128. {
  2129. //
  2130. // Free the Mdl that contains the CROM
  2131. //
  2132. ASSERT (*ppConfigRomMdl);
  2133. nicFreeMdl (*ppConfigRomMdl);
  2134. }
  2135. } while (FALSE);
  2136. //
  2137. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2138. // functions return immediately
  2139. //
  2140. nicFreeIrb (pIrb);
  2141. nicFreeIrp (pIrp);
  2142. TRACE( TL_T, TM_Irp, ( "<==nicSetLocalHostPropertiesCRom pAdapter %x", pAdapter ) );
  2143. return NdisStatus;
  2144. }
  2145. NDIS_STATUS
  2146. nicGetLocalHostUniqueId(
  2147. IN PADAPTERCB pAdapter,
  2148. IN OUT PGET_LOCAL_HOST_INFO1 pUid
  2149. )
  2150. // Function Description:
  2151. // Retrieves the local hosts UniqueId.
  2152. // Arguments
  2153. // pBuffer - LocalHostBuffer
  2154. //
  2155. // Return Value:
  2156. // Success if the Irp Succeeded
  2157. // Failure otherwise
  2158. //
  2159. {
  2160. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2161. PIRB pIrb = NULL;
  2162. PIRP pIrp = NULL;
  2163. STORE_CURRENT_IRQL;
  2164. TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostUniqueId , pAdapter%x ,pUid",
  2165. pAdapter, pUid) );
  2166. do
  2167. {
  2168. ASSERT (pAdapter->pNextDeviceObject != NULL);
  2169. NdisStatus = nicGetIrb (&pIrb);
  2170. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2171. {
  2172. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostUniqueId , nicGetIrb FAILED" ) );
  2173. break;
  2174. }
  2175. ASSERT ( pIrb != NULL);
  2176. //
  2177. //Initialize the datastructures in the Irb
  2178. //
  2179. pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
  2180. pIrb->Flags = 0;
  2181. pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_UNIQUE_ID;
  2182. pIrb->u.GetLocalHostInformation.Information = (PVOID) pUid;
  2183. NdisStatus = nicGetIrp ( pAdapter->pNextDeviceObject, &pIrp);
  2184. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2185. {
  2186. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrp FAILED" ) );
  2187. break;
  2188. }
  2189. ASSERT (pIrp != NULL);
  2190. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2191. pIrp,
  2192. pIrb );
  2193. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2194. {
  2195. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostUniqueId , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2196. break;
  2197. }
  2198. } while (FALSE);
  2199. //
  2200. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2201. // functions return immediately
  2202. //
  2203. nicFreeIrb (pIrb);
  2204. nicFreeIrp (pIrp);
  2205. MATCH_IRQL;
  2206. TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostUniqueId , Status %x", NdisStatus) );
  2207. return NdisStatus;
  2208. }
  2209. //---------------------------------------------------------
  2210. // The routines to submit Irp's to the bus, synchronously or
  2211. // asynchronously begin here
  2212. //---------------------------------------------------------
  2213. NTSTATUS
  2214. nicSubmitIrp(
  2215. IN PDEVICE_OBJECT pPdo,
  2216. IN PIRP pIrp,
  2217. IN PIRB pIrb,
  2218. IN PIO_COMPLETION_ROUTINE pCompletion,
  2219. IN PVOID pContext
  2220. )
  2221. //
  2222. // This is the generic function used by all Irp Send Handlers
  2223. // to do an IoCallDriver. It sets up the next location in the
  2224. // stack prior to calling the Irp
  2225. // Make sure the Irp knows about the Irb by setting it up as an argument
  2226. //
  2227. {
  2228. NTSTATUS NtStatus ;
  2229. PIO_STACK_LOCATION NextIrpStack;
  2230. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp, pPdo %x, Irp %x, Irb %x, ",
  2231. pPdo, pIrp ,pIrb, pCompletion ) );
  2232. TRACE( TL_T, TM_Irp, ( " pCompletion %x, pContext %x",
  2233. pCompletion, pContext ) );
  2234. ASSERT (pPdo != NULL);
  2235. IoSetCompletionRoutine (pIrp,
  2236. pCompletion,
  2237. pContext,
  2238. TRUE,
  2239. TRUE,
  2240. TRUE);
  2241. //
  2242. // Insert the Irp as as the argument in the NextStack location for the IRP
  2243. //
  2244. if (pIrb)
  2245. {
  2246. NextIrpStack = IoGetNextIrpStackLocation (pIrp);
  2247. NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  2248. NextIrpStack->DeviceObject = pPdo;
  2249. NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
  2250. NextIrpStack->Parameters.Others.Argument1 = pIrb;
  2251. }
  2252. else
  2253. {
  2254. IoCopyCurrentIrpStackLocationToNext(pIrp);
  2255. }
  2256. //
  2257. // Reference the PDO and Submit the Irp
  2258. // If Ref fails, it means the PDO has been deactivated on another thread
  2259. //
  2260. NtStatus = IoCallDriver (pPdo, pIrp);
  2261. TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp, PDO %x, NtStatus %x",
  2262. pPdo, NtStatus ) );
  2263. //
  2264. // Since we did a IoCallDriver, we have a guarantee that the completion
  2265. // routine will be called. Exit gracefully
  2266. //
  2267. return NtStatus;
  2268. }
  2269. NDIS_STATUS
  2270. nicSubmitIrp_Synch(
  2271. IN REMOTE_NODE *pRemoteNode,
  2272. IN PIRP pIrp,
  2273. IN PIRB pIrb
  2274. )
  2275. // Callers need to make sure that no context is set for the Irp
  2276. // as it will be a synchronous call for them
  2277. //
  2278. // We refcount the Pdo block so that the pdo block will not disappear
  2279. // during the duration of the IoCallDriver
  2280. {
  2281. NDIS_EVENT NdisSynchEvent;
  2282. NTSTATUS NtStatus;
  2283. NDIS_STATUS NdisStatus;
  2284. BOOLEAN bSuccessful = FALSE;
  2285. BOOLEAN bIsPdoValid = FALSE;
  2286. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_Synch, PDO %x", pRemoteNode->pPdo ) );
  2287. ASSERT (pRemoteNode != NULL);
  2288. ASSERT (pRemoteNode->pPdo != NULL);
  2289. ASSERT (pIrp != NULL);
  2290. ASSERT (pIrb != NULL)
  2291. do
  2292. {
  2293. //
  2294. // Check to see if Pdo is Valid. We do not care here if the Pdo is being
  2295. // removed because Vcs may want to submit Irps as part of their cleanup
  2296. // process
  2297. //
  2298. REMOTE_NODE_ACQUIRE_LOCK (pRemoteNode);
  2299. if ( REMOTE_NODE_TEST_FLAG (pRemoteNode, PDO_Activated )
  2300. && (nicReferenceRemoteNode (pRemoteNode, SubmitIrp_Synch) == TRUE) )
  2301. {
  2302. bIsPdoValid = TRUE;
  2303. }
  2304. REMOTE_NODE_RELEASE_LOCK (pRemoteNode);
  2305. if ( bIsPdoValid == FALSE)
  2306. {
  2307. NtStatus = STATUS_NO_SUCH_DEVICE;
  2308. TRACE( TL_A, TM_Irp, ( "==>PDO is NOT Valid, nicSubmitIrp_Synch, PdoCb %x, Pdo %x", pRemoteNode, pRemoteNode->pPdo ) );
  2309. break;
  2310. }
  2311. //
  2312. // Add a reference to the PDO block so it cannot be removed
  2313. // This reference is decremented at the end of this function
  2314. //
  2315. NdisInitializeEvent (&NdisSynchEvent);
  2316. NtStatus = nicSubmitIrp ( pRemoteNode->pPdo,
  2317. pIrp,
  2318. pIrb,
  2319. nicSubmitIrp_SynchComplete,
  2320. (PVOID)&NdisSynchEvent);
  2321. } while (FALSE);
  2322. if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
  2323. {
  2324. //
  2325. // Now we need to wait for the event to complete
  2326. // and return a good status if we do not hit the timeout
  2327. //
  2328. ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
  2329. bSuccessful = NdisWaitEvent (&NdisSynchEvent,WAIT_INFINITE);
  2330. if (bSuccessful == TRUE)
  2331. {
  2332. //
  2333. // We waited successfully. Now lets see how the Irp fared.
  2334. //
  2335. TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
  2336. NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
  2337. }
  2338. else
  2339. {
  2340. NdisStatus = NDIS_STATUS_FAILURE;
  2341. }
  2342. }
  2343. else
  2344. { //
  2345. // The call to submit Irp failed synvhronously. Presently, the only cause is an
  2346. NdisStatus = NtStatusToNdisStatus (NtStatus);
  2347. }
  2348. if (bIsPdoValid == TRUE)
  2349. {
  2350. //
  2351. // If this variable is set, it means we have referenced the PDO
  2352. //
  2353. nicDereferenceRemoteNode (pRemoteNode, SubmitIrp_Synch);
  2354. }
  2355. TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_Synch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
  2356. return NdisStatus;
  2357. }
  2358. NTSTATUS
  2359. nicSubmitIrp_SynchComplete(
  2360. IN PDEVICE_OBJECT DeviceObject,
  2361. IN PIRP pIrp,
  2362. IN PVOID Context
  2363. )
  2364. // This is the completion routine for functions nicSubmitIrp_synch.
  2365. // It sets the event (int the context) and exits
  2366. //
  2367. {
  2368. PNDIS_EVENT pNdisSynchEvent = (PNDIS_EVENT) Context;
  2369. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_SynchComplete, PDO %x, pIrp %x, status %x",DeviceObject,pIrp, pIrp->IoStatus.Status ) );
  2370. NdisSetEvent (pNdisSynchEvent);
  2371. return (STATUS_MORE_PROCESSING_REQUIRED);
  2372. }
  2373. NDIS_STATUS
  2374. nicSubmitIrp_LocalHostSynch(
  2375. IN PADAPTERCB pAdapter,
  2376. IN PIRP pIrp,
  2377. IN PIRB pIrb
  2378. )
  2379. // Callers need to make sure that no context is set for the Irp
  2380. // as it will be a synchronous call for them
  2381. //
  2382. // No Checking
  2383. //
  2384. {
  2385. NDIS_EVENT NdisSynchEvent;
  2386. NTSTATUS NtStatus;
  2387. NDIS_STATUS NdisStatus;
  2388. BOOLEAN bSuccessful = FALSE;
  2389. BOOLEAN bIsPdoValid = FALSE;
  2390. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_LocalHostSynch, PDO %x", pAdapter->pNextDeviceObject ) );
  2391. TRACE( TL_V, TM_Irp, ( "Current Irql , %.2x", KeGetCurrentIrql()) );
  2392. ASSERT (pIrp != NULL);
  2393. ASSERT (pIrb != NULL)
  2394. do
  2395. {
  2396. //
  2397. // Check to see if Pdo is Valid.
  2398. //
  2399. //
  2400. // Add a reference to the PDO block so it cannot be removed
  2401. // This reference is decremented at the end of this function
  2402. //
  2403. // This reference is decrement below
  2404. if (ADAPTER_ACTIVE(pAdapter))
  2405. {
  2406. nicReferenceAdapter(pAdapter, "nicSubmitIrp_LocalHostSynch");
  2407. TRACE( TL_V, TM_Irp, ( "Adapter Active pAdapter %x, ulflags %x", pAdapter , pAdapter->ulFlags) );
  2408. bIsPdoValid = TRUE;
  2409. }
  2410. else
  2411. {
  2412. TRACE( TL_V, TM_Irp, ( "Adapter INActive pAdapter %x, ulflags %x", pAdapter , pAdapter->ulFlags) );
  2413. bIsPdoValid = FALSE;
  2414. }
  2415. if ( bIsPdoValid == FALSE)
  2416. {
  2417. NtStatus = STATUS_NO_SUCH_DEVICE;
  2418. TRACE( TL_A, TM_Irp, ( "==>PDO is NOT Valid, nicSubmitIrp_LocalHostSynch, pAdapter %x, Pdo %x", pAdapter , pAdapter->pNextDeviceObject) );
  2419. break;
  2420. }
  2421. NdisInitializeEvent (&NdisSynchEvent);
  2422. NtStatus = nicSubmitIrp ( pAdapter->pNextDeviceObject,
  2423. pIrp,
  2424. pIrb,
  2425. nicSubmitIrp_SynchComplete,
  2426. (PVOID)&NdisSynchEvent);
  2427. } while (FALSE);
  2428. if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
  2429. {
  2430. //
  2431. // Now we need to wait for the event to complete
  2432. // and return a good status if we do not hit the timeout
  2433. //
  2434. bSuccessful = NdisWaitEvent (&NdisSynchEvent,WAIT_INFINITE);
  2435. if (bSuccessful == TRUE)
  2436. {
  2437. //
  2438. // We waited successfully. Now lets see how the Irp fared.
  2439. //
  2440. TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
  2441. NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
  2442. }
  2443. else
  2444. {
  2445. NdisStatus = NDIS_STATUS_FAILURE;
  2446. }
  2447. }
  2448. else
  2449. {
  2450. //
  2451. // IoCallDriver failed synchronously
  2452. //
  2453. NdisStatus = NtStatusToNdisStatus (NtStatus);
  2454. }
  2455. if (bIsPdoValid == TRUE)
  2456. {
  2457. nicDereferenceAdapter(pAdapter, "nicSubmitIrp_LocalHostSynch");
  2458. }
  2459. TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_LocalHostSynch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
  2460. return NdisStatus;
  2461. }
  2462. NDIS_STATUS
  2463. nicSubmitIrp_PDOSynch(
  2464. IN PDEVICE_OBJECT pPdo,
  2465. IN PIRP pIrp,
  2466. IN PIRB pIrb
  2467. )
  2468. // Callers need to make sure that no context is set for the Irp
  2469. // as it will be a synchronous call for them
  2470. //
  2471. // No Checking
  2472. //
  2473. {
  2474. NDIS_EVENT NdisSynchEvent;
  2475. NTSTATUS NtStatus;
  2476. NDIS_STATUS NdisStatus;
  2477. BOOLEAN bSuccessful = FALSE;
  2478. STORE_CURRENT_IRQL;
  2479. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_PDOSynch, PDO %x", pPdo) );
  2480. TRACE( TL_V, TM_Irp, ( "Current Irql , %.2x", KeGetCurrentIrql()) );
  2481. ASSERT (pIrp != NULL);
  2482. ASSERT (pIrb != NULL)
  2483. //
  2484. // No Checks to see if Pdo is Valid.
  2485. //
  2486. //
  2487. // Send the Irp to the bus driver
  2488. //
  2489. NdisInitializeEvent (&NdisSynchEvent);
  2490. NtStatus = nicSubmitIrp ( pPdo,
  2491. pIrp,
  2492. pIrb,
  2493. nicSubmitIrp_SynchComplete,
  2494. (PVOID)&NdisSynchEvent);
  2495. if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
  2496. {
  2497. //
  2498. // Now we need to wait for the event to complete
  2499. // and return a good status if we do not hit the timeout
  2500. //
  2501. ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
  2502. bSuccessful = NdisWaitEvent (&NdisSynchEvent,WAIT_INFINITE);
  2503. if (bSuccessful == TRUE)
  2504. {
  2505. //
  2506. // We waited successfully. Now lets see how the Irp fared.
  2507. //
  2508. TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
  2509. NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
  2510. }
  2511. else
  2512. {
  2513. NdisStatus = NDIS_STATUS_FAILURE;
  2514. }
  2515. }
  2516. else
  2517. {
  2518. //
  2519. // IoCallDriver failed synchronously
  2520. //
  2521. NdisStatus = NtStatusToNdisStatus (NtStatus);
  2522. }
  2523. TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_PDOSynch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
  2524. MATCH_IRQL;
  2525. return NdisStatus;
  2526. }