Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4163 lines
110 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, adapted from the l2tp sources.
  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->pNdisDeviceObject, &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. if (pIrb != NULL)
  245. {
  246. nicFreeIrb (pIrb);
  247. }
  248. if (pIrp != NULL)
  249. {
  250. nicFreeIrp (pIrp);
  251. }
  252. TRACE( TL_T, TM_Irp, ( "<==nicGet1394AddressOfRemoteNode, Status %x, Address %x", NdisStatus, *pNodeAddress ) );
  253. return NdisStatus;
  254. }
  255. NDIS_STATUS
  256. nicGet1394AddressFromDeviceObject(
  257. IN PDEVICE_OBJECT pPdo,
  258. IN OUT NODE_ADDRESS *pNodeAddress,
  259. IN ULONG fulFlags
  260. )
  261. // Function Description:
  262. // This function will get the 1394 Address from the device object.
  263. //
  264. // Arguments
  265. // PdoCb * Local Host's Pdo Control Block
  266. // NodeAddress * Node Address structre wher the address will be returned in
  267. // fulFlags - Could specify USE_LOCAL_HOST
  268. //
  269. // Return Value:
  270. // Success if the irp succeeeded
  271. // Failure: if the pdo is not active or the irp failed
  272. //
  273. {
  274. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  275. PIRB pIrb = NULL;
  276. PIRP pIrp = NULL;
  277. TRACE( TL_T, TM_Irp, ( "==>nicGet1394AddressFromDeviceObject, pPdo %x, pNodeAdddress ",
  278. pPdo, pNodeAddress) );
  279. ASSERT (pNodeAddress != NULL);
  280. ASSERT (pPdo != NULL);
  281. do
  282. {
  283. NdisStatus = nicGetIrb (&pIrb);
  284. if (NdisStatus != NDIS_STATUS_SUCCESS)
  285. {
  286. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrb FAILED" ) );
  287. break;
  288. }
  289. ASSERT ( pIrb != NULL);
  290. pIrb->Flags = 0;
  291. pIrb->FunctionNumber = REQUEST_GET_ADDR_FROM_DEVICE_OBJECT;
  292. pIrb->u.Get1394AddressFromDeviceObject.fulFlags = fulFlags;
  293. NdisStatus = nicGetIrp (pPdo, &pIrp);
  294. if (NdisStatus != NDIS_STATUS_SUCCESS)
  295. {
  296. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicGetIrp FAILED" ) );
  297. break;
  298. }
  299. ASSERT (pIrp != NULL);
  300. NdisStatus = nicSubmitIrp_PDOSynch (pPdo,
  301. pIrp,
  302. pIrb );
  303. if (NdisStatus != NDIS_STATUS_SUCCESS)
  304. {
  305. TRACE( TL_A, TM_Irp, ( "nicGet1394AddressFromDeviceObject, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  306. break;
  307. }
  308. (*pNodeAddress) = pIrb->u.Get1394AddressFromDeviceObject.NodeAddress;
  309. } while (FALSE);
  310. //
  311. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  312. // functions return immediately
  313. //
  314. if (pIrb != NULL)
  315. {
  316. nicFreeIrb (pIrb);
  317. }
  318. if (pIrp != NULL)
  319. {
  320. nicFreeIrp (pIrp);
  321. }
  322. TRACE( TL_T, TM_Irp, ( "<==nicGet1394AddressFromDeviceObject, Status %x, Address %x", NdisStatus, *pNodeAddress ) );
  323. return NdisStatus;
  324. }
  325. NDIS_STATUS
  326. nicGetGenerationCount(
  327. IN PADAPTERCB pAdapter,
  328. IN OUT PULONG GenerationCount
  329. )
  330. // This function returns the generation count of the Device Object that PDO points to.
  331. //
  332. {
  333. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  334. PIRB pIrb = NULL;
  335. PIRP pIrp = NULL;
  336. PDEVICE_OBJECT pDeviceObject = pAdapter->pNdisDeviceObject;
  337. TRACE( TL_T, TM_Irp, ( "==>nicGetGenerationCount, PDO %x, pVc %x", pDeviceObject ) );
  338. ASSERT( pDeviceObject != NULL);
  339. do
  340. {
  341. NdisStatus = nicGetIrb( &pIrb );
  342. if (NdisStatus != NDIS_STATUS_SUCCESS)
  343. {
  344. TRACE( TL_A, TM_Irp, ( "Failed to allocate an Irb in nicGetGenerationCout") );
  345. NdisStatus = NDIS_STATUS_RESOURCES;
  346. break;
  347. }
  348. NdisStatus = nicGetIrp (pDeviceObject, &pIrp);
  349. if (NdisStatus != NDIS_STATUS_SUCCESS)
  350. {
  351. TRACE( TL_A, TM_Irp, ( "Failed to allocate an Irp in nicGetGenerationCout") );
  352. NdisStatus = NDIS_STATUS_RESOURCES;
  353. break;
  354. }
  355. pIrb->FunctionNumber = REQUEST_GET_GENERATION_COUNT;
  356. pIrb->Flags = 0;
  357. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter, pIrp, pIrb);
  358. if (NdisStatus == NDIS_STATUS_SUCCESS)
  359. {
  360. *GenerationCount = pIrb->u.GetGenerationCount.GenerationCount;
  361. TRACE( TL_N, TM_Irp, ("GenerationCount = 0x%x\n", *GenerationCount) );
  362. }
  363. else
  364. {
  365. TRACE(TL_A, TM_Irp, ("SubmitIrpSync failed = 0x%x\n", NdisStatus));
  366. ASSERT (0);
  367. break;
  368. }
  369. } while(FALSE);
  370. //
  371. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  372. // functions return immediately
  373. //
  374. if (pIrb != NULL)
  375. {
  376. nicFreeIrb (pIrb);
  377. }
  378. if (pIrp != NULL)
  379. {
  380. nicFreeIrp (pIrp);
  381. }
  382. TRACE( TL_T, TM_Irp, ( "<==nicGetGenerationCount, PDO %x, Generation %x", pDeviceObject, *GenerationCount) );
  383. return NdisStatus;
  384. }
  385. NDIS_STATUS
  386. nicFreeAddressRange(
  387. IN PADAPTERCB pAdapter,
  388. IN ULONG nAddressesToFree,
  389. IN PADDRESS_RANGE p1394AddressRange,
  390. IN PHANDLE phAddressRange
  391. )
  392. // Function Description:
  393. // This is the generic call to free an address range. It is the callers responsibility to figure out
  394. // the reference counting on the RemoteNode
  395. // This is because in the RecvFIFO code path we allocate one address range on each remote node
  396. // whereas in the Broadcast channel register, we allocate one addreesss on ONE remote node only
  397. //
  398. // Arguments
  399. // pRemoteNode, - Remote Node used to submit the IRP
  400. // nAddressesToFree, - Number of addreses to free
  401. // p1394AddressRange, - pointer to the address range which was allocated
  402. // phAddressRange - Handle returned by the bus driver
  403. //
  404. // Return Value:
  405. // Success if the irp succeeeded
  406. // Failure: if the pdo is not active or the irp failed
  407. //
  408. {
  409. PIRP pIrp = NULL;
  410. PIRB pIrb = NULL;
  411. PDEVICE_OBJECT pPdo = pAdapter->pNdisDeviceObject;
  412. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  413. TRACE( TL_T, TM_Irp, ( "==>nicFreeAddressRange pAdapter %x", pAdapter ) );
  414. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  415. do
  416. {
  417. if (pPdo == NULL)
  418. {
  419. TRACE( TL_A, TM_Irp, ( "pPdo is NULL in nicFreeRecvFifoAddressRange" ) );
  420. NdisStatus = NDIS_STATUS_FAILURE;
  421. break;
  422. }
  423. NdisStatus = nicGetIrb(&pIrb);
  424. if (NdisStatus != NDIS_STATUS_SUCCESS)
  425. {
  426. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicFreeRecvFifoAddressRange" ) );
  427. break;
  428. }
  429. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  430. if (NdisStatus != NDIS_STATUS_SUCCESS)
  431. {
  432. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicFreeRecvFifoAddressRange" ) );
  433. break;
  434. }
  435. TRACE (TL_V, TM_Cm, (" NumAddresses %x, hAddressRange %x, Hi %x, Length %x, Lo %x",
  436. nAddressesToFree,
  437. phAddressRange,
  438. p1394AddressRange->AR_Off_High,
  439. p1394AddressRange->AR_Length,
  440. p1394AddressRange->AR_Off_Low ) );
  441. //
  442. //Initialize the datastructures in the Irb
  443. //
  444. pIrb->FunctionNumber = REQUEST_FREE_ADDRESS_RANGE;
  445. pIrb->Flags = 0;
  446. pIrb->u.FreeAddressRange.nAddressesToFree = nAddressesToFree;
  447. pIrb->u.FreeAddressRange.p1394AddressRange = p1394AddressRange;
  448. pIrb->u.FreeAddressRange.pAddressRange = phAddressRange;
  449. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
  450. pIrp,
  451. pIrb );
  452. } while (FALSE);
  453. //
  454. // Free the locally allocated memory
  455. //
  456. if (pIrp!= NULL)
  457. {
  458. nicFreeIrp(pIrp);
  459. }
  460. if (pIrb != NULL)
  461. {
  462. nicFreeIrb(pIrb);
  463. }
  464. //
  465. // We do not care about the status, because we do not know what to do if it fails.
  466. // However, spew some debug out.
  467. //
  468. if (NdisStatus != NDIS_STATUS_SUCCESS)
  469. {
  470. TRACE( TL_N, TM_Irp, ( "nicFreeAddressRangeFAILED %x", NdisStatus) );
  471. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  472. }
  473. TRACE( TL_T, TM_Irp, ( "<==nicFreeAddressRangeStatus %x (always success)", NdisStatus) );
  474. NdisStatus = NDIS_STATUS_SUCCESS;
  475. return NdisStatus;
  476. }
  477. NDIS_STATUS
  478. nicFreeRecvFifoAddressRange(
  479. IN REMOTE_NODE *pRemoteNode
  480. )
  481. //
  482. // This function will send an Irp to the bus1394 to free the address range in the VC
  483. // that was allocated by the AllocatedAddressRange
  484. //
  485. // The argument will be changed to RecvFIFOData once a Pdo can have multiple
  486. // RecvFIFOVc hanging off it.
  487. //
  488. // This will not change the refcount on the call, the calling function must take care of it.
  489. //
  490. {
  491. PIRP pIrp = NULL;
  492. PIRB pIrb = NULL;
  493. DEVICE_OBJECT * pPdo = pRemoteNode->pPdo;
  494. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  495. TRACE( TL_T, TM_Irp, ( "==>nicFreeRecvFifoAddressRange pRemoteNode %x, ", pRemoteNode) );
  496. ASSERT (pRemoteNode != NULL);
  497. ASSERT (pRemoteNode->pPdo != NULL);
  498. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  499. do
  500. {
  501. if (pRemoteNode->pPdo == NULL)
  502. {
  503. TRACE( TL_A, TM_Irp, ( "pPdo is NULL in nicFreeRecvFifoAddressRange" ) );
  504. NdisStatus = NDIS_STATUS_FAILURE;
  505. break;
  506. }
  507. NdisStatus = nicGetIrb(&pIrb);
  508. if (NdisStatus != NDIS_STATUS_SUCCESS)
  509. {
  510. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicFreeRecvFifoAddressRange" ) );
  511. break;
  512. }
  513. ASSERT (pRemoteNode->pPdo != NULL);
  514. NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
  515. if (NdisStatus != NDIS_STATUS_SUCCESS)
  516. {
  517. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicFreeRecvFifoAddressRange" ) );
  518. break;
  519. }
  520. //
  521. //Initialize the datastructures in the Irb
  522. //
  523. pIrb->FunctionNumber = REQUEST_FREE_ADDRESS_RANGE;
  524. pIrb->Flags = 0;
  525. pIrb->u.FreeAddressRange.nAddressesToFree = pRemoteNode->RecvFIFOData.AddressesReturned;
  526. pIrb->u.FreeAddressRange.p1394AddressRange = &pRemoteNode->RecvFIFOData.VcAddressRange;
  527. pIrb->u.FreeAddressRange.pAddressRange = &pRemoteNode->RecvFIFOData.hAddressRange;
  528. NdisStatus = nicSubmitIrp_Synch( pRemoteNode,
  529. pIrp,
  530. pIrb );
  531. REMOTE_NODE_ACQUIRE_LOCK (pRemoteNode);
  532. pRemoteNode->RecvFIFOData.AllocatedAddressRange = FALSE;
  533. REMOTE_NODE_RELEASE_LOCK (pRemoteNode);
  534. // Dereference the Pdo Structure. Ref added in AllocateAddressRange.
  535. // The Address Range is now free
  536. //
  537. nicDereferenceRemoteNode (pRemoteNode, "nicFreeRecvFifoAddressRange");
  538. } while (FALSE);
  539. //
  540. // Free the locally allocated memory
  541. //
  542. if (pIrp!= NULL)
  543. {
  544. nicFreeIrp(pIrp);
  545. }
  546. if (pIrb != NULL)
  547. {
  548. nicFreeIrb(pIrb);
  549. }
  550. //
  551. // We do not care about the status, because we do not know what to do if it fails.
  552. // However, spew some debug out.
  553. //
  554. if (NdisStatus != NDIS_STATUS_SUCCESS)
  555. {
  556. TRACE( TL_N, TM_Irp, ( "nicFreeRecvFifoAddressRange FAILED %x", NdisStatus) );
  557. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  558. }
  559. TRACE( TL_T, TM_Irp, ( "<==nicFreeRecvFifoAddressRange Status %x (always success)", NdisStatus) );
  560. NdisStatus = NDIS_STATUS_SUCCESS;
  561. return NdisStatus;
  562. }
  563. VOID
  564. nicFreeAddressRangeDebugSpew(
  565. IN PIRB pIrb
  566. )
  567. // This functions spews out the parameters in a Free Address Range Irb
  568. //
  569. //
  570. {
  571. TRACE( TL_V, TM_Irp, ( "==>nicFreeAddressRangeDebugSpew, pIrb = %x", pIrb) );
  572. ASSERT(pIrb != NULL);
  573. TRACE( TL_N, TM_Irp, ( "Num Addresses Returned %x ",pIrb->u.FreeAddressRange.nAddressesToFree ) );
  574. TRACE( TL_N, TM_Irp, ( "Address High %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Off_High ) );
  575. TRACE( TL_N, TM_Irp, ( "Address Low %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Off_Low ) );
  576. TRACE( TL_N, TM_Irp, ( "Address Length %x", pIrb->u.FreeAddressRange.p1394AddressRange->AR_Length ) );
  577. TRACE( TL_N, TM_Irp, ( "Handle %x", pIrb->u.FreeAddressRange.pAddressRange ) );
  578. TRACE( TL_V, TM_Irp, ( "<==nicFreeAddressRangeDebugSpew " ) );
  579. }
  580. NDIS_STATUS
  581. nicFreeChannel(
  582. IN PADAPTERCB pAdapter,
  583. IN ULONG nChannel
  584. )
  585. // Function Description:
  586. // This function sends an Irp to the Bus driver to free a channel
  587. // Any remote Pdo can be used for the Irp. However for the sake of
  588. // bookkeeping use the same Pdo that the channel was allocated on (maybe)
  589. // Arguments
  590. // PdoCb The Pdo for the remote node to which the Irp is submitted
  591. // Channel Pointer The Channel, requested and the channel returned
  592. //
  593. // Return Value:
  594. // Success if the channel was allocated
  595. // Failure otherwise
  596. //
  597. {
  598. PIRP pIrp = NULL;
  599. PIRB pIrb = NULL;
  600. PDEVICE_OBJECT pPdo = pAdapter->pNdisDeviceObject;
  601. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  602. TRACE( TL_T, TM_Irp, ( "==>nicFreeChannel pAdapter %x, Channel %x", pAdapter, nChannel) );
  603. ASSERT (pAdapter!= NULL);
  604. ASSERT (pPdo != NULL);
  605. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  606. do
  607. {
  608. if (pPdo == NULL)
  609. {
  610. TRACE( TL_A, TM_Irp, ( "pPdo is NULL in nicFreeChannel" ) );
  611. NdisStatus = NDIS_STATUS_FAILURE;
  612. break;
  613. }
  614. NdisStatus = nicGetIrb(&pIrb);
  615. if (NdisStatus != NDIS_STATUS_SUCCESS)
  616. {
  617. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicFreeChannel" ) );
  618. break;
  619. }
  620. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  621. if (NdisStatus != NDIS_STATUS_SUCCESS)
  622. {
  623. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicFreeChannel" ) );
  624. break;
  625. }
  626. //
  627. //Initialize the datastructures in the Irb
  628. //
  629. pIrb->FunctionNumber = REQUEST_ISOCH_FREE_CHANNEL;
  630. pIrb->Flags = 0;
  631. pIrb->u.IsochFreeChannel.nChannel = nChannel;
  632. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
  633. pIrp,
  634. pIrb );
  635. //
  636. // Regardless update the mask, as the channel could have been freed by a bus reset
  637. //
  638. if (nChannel != BROADCAST_CHANNEL)
  639. {
  640. ADAPTER_ACQUIRE_LOCK (pAdapter);
  641. //
  642. // Clear the channel in the mask
  643. //
  644. pAdapter->ChannelsAllocatedByLocalHost &= (~( g_ullOne <<nChannel ));
  645. ADAPTER_RELEASE_LOCK (pAdapter);
  646. }
  647. } while (FALSE);
  648. //
  649. // Free the locally allocated memory
  650. //
  651. if (pIrp!= NULL)
  652. {
  653. nicFreeIrp(pIrp);
  654. }
  655. if (pIrb != NULL)
  656. {
  657. nicFreeIrb(pIrb);
  658. }
  659. //
  660. // We do not care about the status, because we do not know what to do if it fails.
  661. // However, spew some debug out.
  662. //
  663. if (NdisStatus != NDIS_STATUS_SUCCESS)
  664. {
  665. TRACE( TL_N, TM_Irp, ( "nicFreeChannel FAILED %x", NdisStatus) );
  666. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  667. }
  668. TRACE( TL_T, TM_Irp, ( "<==nicFreeChannel Status %x ", NdisStatus) );
  669. return NdisStatus;
  670. }
  671. NDIS_STATUS
  672. nicAllocateChannel (
  673. IN PADAPTERCB pAdapter,
  674. IN ULONG Channel,
  675. OUT PULARGE_INTEGER pChannelsAvailable OPTIONAL
  676. )
  677. // Function Description:
  678. // This function sends an Irp to the Bus driver to allocate a channel
  679. // Any remote Pdo can be used for the Irp
  680. //
  681. // Arguments
  682. // PdoCb The Pdo for the remote node to which the Irp is submitted
  683. // Channel -The Channel, requested and the channel returned
  684. //
  685. // Return Value:
  686. // Success if the channel was allocated
  687. // Failure otherwise
  688. //
  689. {
  690. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  691. PIRB pIrb = NULL;
  692. PIRP pIrp = NULL;
  693. PDEVICE_OBJECT pDeviceObject = pAdapter->pNdisDeviceObject;
  694. STORE_CURRENT_IRQL;
  695. TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateChannel, PdoCb, %x Channel %d", pAdapter, Channel ) );
  696. do
  697. {
  698. NdisStatus = nicGetIrb (&pIrb);
  699. if (NdisStatus != NDIS_STATUS_SUCCESS)
  700. {
  701. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicGetIrb FAILED" ) );
  702. break;
  703. }
  704. ASSERT ( pIrb != NULL);
  705. //
  706. //Initialize the datastructures in the Irb
  707. //
  708. pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_CHANNEL;
  709. pIrb->Flags = 0;
  710. pIrb->u.IsochAllocateChannel.nRequestedChannel = Channel;
  711. ASSERT (Channel < 64);
  712. NdisStatus = nicGetIrp ( pDeviceObject, &pIrp);
  713. if (NdisStatus != NDIS_STATUS_SUCCESS)
  714. {
  715. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicGetIrp FAILED" ) );
  716. break;
  717. }
  718. ASSERT (pIrp != NULL);
  719. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  720. pIrp,
  721. pIrb );
  722. if (NdisStatus != NDIS_STATUS_SUCCESS)
  723. {
  724. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateChannel , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  725. break;
  726. }
  727. if (pChannelsAvailable != NULL)
  728. {
  729. pChannelsAvailable->QuadPart = pIrb->u.IsochAllocateChannel.ChannelsAvailable.QuadPart;
  730. }
  731. TRACE( TL_N, TM_Irp, ( "Channel allocated %d", Channel ) );
  732. if (Channel != BROADCAST_CHANNEL)
  733. {
  734. ADAPTER_ACQUIRE_LOCK (pAdapter);
  735. //
  736. // Set the channel in the mask
  737. //
  738. pAdapter->ChannelsAllocatedByLocalHost |= ( g_ullOne <<Channel );
  739. ADAPTER_RELEASE_LOCK (pAdapter);
  740. }
  741. } while (FALSE);
  742. //
  743. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  744. // functions return immediately
  745. //
  746. nicFreeIrb (pIrb);
  747. nicFreeIrp (pIrp);
  748. MATCH_IRQL;
  749. TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateChannel, Channel %d, Status %x", Channel, NdisStatus ) );
  750. return NdisStatus;
  751. }
  752. NDIS_STATUS
  753. nicQueryChannelMap (
  754. IN PADAPTERCB pAdapter,
  755. OUT PULARGE_INTEGER pChannelsAvailable
  756. )
  757. // Function Description:
  758. // This function sends an Irp to the Bus driver to allocate a channel
  759. // Any remote Pdo can be used for the Irp
  760. //
  761. // Arguments
  762. // PdoCb The Pdo for the remote node to which the Irp is submitted
  763. // Channel -The Channel, requested and the channel returned
  764. //
  765. // Return Value:
  766. // Success if the channel was allocated
  767. // Failure otherwise
  768. //
  769. {
  770. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  771. PIRB pIrb = NULL;
  772. PIRP pIrp = NULL;
  773. PDEVICE_OBJECT pDeviceObject = pAdapter->pNdisDeviceObject;
  774. STORE_CURRENT_IRQL;
  775. TRACE( TL_T, TM_Irp, ( "==>nicQueryChannelMap , PdoCb, %x ", pAdapter) );
  776. do
  777. {
  778. if (pChannelsAvailable == NULL)
  779. {
  780. ASSERT (pChannelsAvailable != NULL);
  781. NdisStatus = NDIS_STATUS_FAILURE;
  782. break;
  783. }
  784. NdisStatus = nicGetIrb (&pIrb);
  785. if (NdisStatus != NDIS_STATUS_SUCCESS)
  786. {
  787. TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicGetIrb FAILED" ) );
  788. break;
  789. }
  790. ASSERT ( pIrb != NULL);
  791. //
  792. //Initialize the datastructures in the Irb
  793. //
  794. pIrb->FunctionNumber = REQUEST_ISOCH_QUERY_RESOURCES ;
  795. pIrb->u.IsochQueryResources.fulSpeed = SPEED_FLAGS_100;
  796. pIrb->Flags = 0;
  797. NdisStatus = nicGetIrp ( pDeviceObject, &pIrp);
  798. if (NdisStatus != NDIS_STATUS_SUCCESS)
  799. {
  800. TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicGetIrp FAILED" ) );
  801. break;
  802. }
  803. ASSERT (pIrp != NULL);
  804. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  805. pIrp,
  806. pIrb );
  807. if (NdisStatus != NDIS_STATUS_SUCCESS)
  808. {
  809. TRACE( TL_A, TM_Irp, ( "nicQueryChannelMap , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  810. break;
  811. }
  812. //
  813. // We get the *available* channels, in network-byte order.
  814. // We have to byte reverse and flip the bits to get
  815. // it in the form we want.
  816. //
  817. // Looks like we really have to flip the *bits*, not just the bytes.
  818. //
  819. {
  820. LARGE_INTEGER in, out;
  821. PUCHAR puc;
  822. UINT u;
  823. in = pIrb->u.IsochQueryResources.ChannelsAvailable;
  824. out.LowPart = ~SWAPBYTES_ULONG (in.HighPart );
  825. out.HighPart = ~SWAPBYTES_ULONG (in.LowPart );
  826. // Now swap the bits in each byte.
  827. //
  828. puc = (PUCHAR) &out;
  829. for (u=sizeof(out); u; u--,puc++)
  830. {
  831. UCHAR uc,uc1;
  832. UINT u1;
  833. uc= *puc;
  834. uc1=0;
  835. for (u1=0;u1<8;u1++)
  836. {
  837. if (uc & (1<<u1))
  838. {
  839. uc1 |= (1 << (7-u1));
  840. }
  841. }
  842. *puc = uc1;
  843. }
  844. pChannelsAvailable->QuadPart = out.QuadPart;
  845. }
  846. } while (FALSE);
  847. //
  848. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  849. // functions return immediately
  850. //
  851. nicFreeIrb (pIrb);
  852. nicFreeIrp (pIrp);
  853. MATCH_IRQL;
  854. TRACE( TL_T, TM_Irp, ( "<==nicQueryChannelMap , , Status %x", NdisStatus ) );
  855. return NdisStatus;
  856. }
  857. NDIS_STATUS
  858. nicIsochAllocateBandwidth(
  859. IN PREMOTE_NODE pRemoteNodePdoCb,
  860. IN ULONG MaxBytesPerFrameRequested,
  861. IN ULONG SpeedRequested,
  862. OUT PHANDLE phBandwidth,
  863. OUT PULONG pBytesPerFrameAvailable,
  864. OUT PULONG pSpeedSelected
  865. )
  866. // Function Description:
  867. // This function allocates bandwith on the bus
  868. //
  869. // Arguments
  870. // PdoCb - Remote Nodes Pdo Block
  871. // MaxBytesPerFrame Requested -
  872. // SpeedRequested -
  873. // hBandwidth
  874. // pSpeedSelected
  875. // Bytes Per Frame Available
  876. //
  877. //
  878. // Return Value:
  879. // hBandwidth,
  880. // Speed and
  881. // BytesPerFrameAvailable
  882. //
  883. //
  884. //
  885. {
  886. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  887. PIRB pIrb = NULL;
  888. PIRP pIrp = NULL;
  889. TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateBandwidth, pRemoteNodePdoCb %x", pRemoteNodePdoCb) );
  890. do
  891. {
  892. NdisStatus = nicGetIrb (&pIrb);
  893. if (NdisStatus != NDIS_STATUS_SUCCESS)
  894. {
  895. BREAK( TM_Irp, ( "nicIsochAllocateBandwidth, nicGetIrb FAILED" ) );
  896. }
  897. ASSERT ( pIrb != NULL);
  898. pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_BANDWIDTH;
  899. pIrb->Flags = 0;
  900. pIrb->u.IsochAllocateBandwidth.nMaxBytesPerFrameRequested = MaxBytesPerFrameRequested;
  901. pIrb->u.IsochAllocateBandwidth.fulSpeed = SpeedRequested;
  902. ASSERT (pRemoteNodePdoCb->pPdo != NULL);
  903. NdisStatus = nicGetIrp (pRemoteNodePdoCb->pPdo, &pIrp);
  904. if (NdisStatus != NDIS_STATUS_SUCCESS)
  905. {
  906. BREAK( TM_Irp, ( "nicIsochAllocateBandwidth, nicGetIrp FAILED" ) );
  907. }
  908. ASSERT (pIrp != NULL);
  909. NdisStatus = nicSubmitIrp_Synch ( pRemoteNodePdoCb,
  910. pIrp,
  911. pIrb );
  912. if (NdisStatus != NDIS_STATUS_SUCCESS)
  913. {
  914. TRACE (TL_N, TM_Irp, ( "nicIsochAllocateBandwidth, nicSubmitIrp_Synch FAILED ") );
  915. break;
  916. }
  917. *phBandwidth = pIrb->u.IsochAllocateBandwidth.hBandwidth ;
  918. *pBytesPerFrameAvailable = pIrb->u.IsochAllocateBandwidth.BytesPerFrameAvailable;
  919. *pSpeedSelected = pIrb->u.IsochAllocateBandwidth.SpeedSelected;
  920. TRACE( TL_V, TM_Irp, ( "hBandwidth %x", *phBandwidth) );
  921. TRACE( TL_V, TM_Irp, ( "BytesPerFrameAvailable %x", *pBytesPerFrameAvailable) );
  922. TRACE( TL_V, TM_Irp, ( "SpeedSelected %x", *pSpeedSelected) );
  923. } while (FALSE);
  924. //
  925. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  926. // functions return immediately
  927. //
  928. nicFreeIrb (pIrb);
  929. nicFreeIrp (pIrp);
  930. TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateBandwidth NdisStatus %x", NdisStatus) );
  931. return NdisStatus;
  932. }
  933. NDIS_STATUS
  934. nicAsyncLock(
  935. PREMOTE_NODE pRemoteNode,
  936. IO_ADDRESS DestinationAddress, // Address to lock to
  937. ULONG nNumberOfArgBytes, // Bytes in Arguments
  938. ULONG nNumberOfDataBytes, // Bytes in DataValues
  939. ULONG fulTransactionType, // Lock transaction type
  940. ULONG Arguments[2], // Arguments used in Lock
  941. ULONG DataValues[2], // Data values
  942. PVOID pBuffer, // Destination buffer (virtual address)
  943. ULONG ulGeneration // Generation as known by driver
  944. )
  945. // Function Description:
  946. // This performs an asynchronous lock operation in another
  947. // nodes address space
  948. //
  949. // Arguments
  950. //PREMOTE_NODE pRemoteNode // Remote Node which owns the Destination address
  951. //IO_ADDRESS DestinationAddress, // Address to lock to
  952. //ULONG nNumberOfArgBytes, // Bytes in Arguments
  953. //ULONG nNumberOfDataBytes, // Bytes in DataValues
  954. //ULONG fulTransactionType, // Lock transaction type
  955. //ULONG fulFlags, // Flags pertinent to lock
  956. //ULONG Arguments[2], // Arguments used in Lock
  957. //ULONG DataValues[2], // Data values
  958. //PVOID pBuffer, // Destination buffer (virtual address)
  959. //ULONG ulGeneration, // Generation as known by driver
  960. //
  961. // Return Value:
  962. // Success - if successful
  963. // Invalid Generation
  964. //
  965. //
  966. {
  967. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  968. PIRB pIrb = NULL;
  969. PIRP pIrp = NULL;
  970. STORE_CURRENT_IRQL;
  971. TRACE( TL_T, TM_Mp, ( "==>nicAsyncLock, Remote Node, %x ", pRemoteNode ) );
  972. TRACE( TL_V, TM_Mp, ( " Destination %x, NumArgBytes %x, NumDataBytes ",
  973. DestinationAddress, nNumberOfArgBytes, nNumberOfDataBytes ) );
  974. TRACE( TL_V, TM_Mp, ( " TransactionType %x, , Buffer %x, Generation %x",
  975. fulTransactionType, pBuffer, ulGeneration ) );
  976. TRACE( TL_V, TM_Mp, ( " Arg[0] %x, Arg[1] %x, Data[0] %x, Data[1] %x",
  977. Arguments[0], Arguments[1], DataValues[0], DataValues[1] ) );
  978. do
  979. {
  980. NdisStatus = nicGetIrb (&pIrb);
  981. if (NdisStatus != NDIS_STATUS_SUCCESS)
  982. {
  983. BREAK ( TM_Irp, ( "nicAsyncLock, nicGetIrb FAILED" ) );
  984. }
  985. ASSERT ( pIrb != NULL);
  986. pIrb->FunctionNumber = REQUEST_ASYNC_LOCK;
  987. pIrb->Flags = 0;
  988. pIrb->u.AsyncLock.DestinationAddress = DestinationAddress;
  989. pIrb->u.AsyncLock.nNumberOfArgBytes = nNumberOfArgBytes;
  990. pIrb->u.AsyncLock.nNumberOfDataBytes = nNumberOfDataBytes;
  991. pIrb->u.AsyncLock.fulTransactionType = fulTransactionType;
  992. pIrb->u.AsyncLock.Arguments[0] = Arguments[0];
  993. pIrb->u.AsyncLock.Arguments[1] = Arguments[1];
  994. pIrb->u.AsyncLock.DataValues[0] = DataValues[0];
  995. pIrb->u.AsyncLock.DataValues[1] = DataValues[1];
  996. pIrb->u.AsyncLock.pBuffer = pBuffer;
  997. pIrb->u.AsyncLock.ulGeneration = ulGeneration;
  998. NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
  999. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1000. {
  1001. BREAK ( TM_Irp, ( "nicAsyncLock, nicGetIrp FAILED" ) );
  1002. break;
  1003. }
  1004. ASSERT (pIrp != NULL);
  1005. NdisStatus = nicSubmitIrp_Synch ( pRemoteNode,
  1006. pIrp,
  1007. pIrb );
  1008. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1009. {
  1010. TRACE ( TL_A, TM_Irp, ( "nicAsyncLock, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1011. break;
  1012. }
  1013. } while (FALSE);
  1014. TRACE( TL_T, TM_Mp, ( "<==nicAsyncLock, Success , %x ", NdisStatus) );
  1015. return NdisStatus;
  1016. }
  1017. NDIS_STATUS
  1018. nicAsyncRead_Synch(
  1019. PREMOTE_NODE pRemoteNode,
  1020. IO_ADDRESS DestinationAddress,
  1021. ULONG nNumberOfBytesToRead,
  1022. ULONG nBlockSize,
  1023. ULONG fulFlags,
  1024. PMDL Mdl,
  1025. ULONG ulGeneration,
  1026. OUT NTSTATUS *pNtStatus
  1027. )
  1028. // Function Description:
  1029. // This is an asyc read operation a remote node;s address space
  1030. //
  1031. //
  1032. //
  1033. //
  1034. // Arguments
  1035. //PREMOTE_NODE pRemoteNode // Remote Node which owns the Destination address
  1036. // IO_ADDRESS DestinationAddress; // Address to read from
  1037. // ULONG nNumberOfBytesToRead; // Bytes to read
  1038. // ULONG nBlockSize; // Block size of read
  1039. // ULONG fulFlags; // Flags pertinent to read
  1040. // PMDL Mdl; // Destination buffer
  1041. // ULONG ulGeneration; // Generation as known by driver
  1042. //
  1043. // Return Value:
  1044. // Success - if successful
  1045. // Invalid Generation
  1046. //
  1047. //
  1048. {
  1049. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1050. PIRB pIrb = NULL;
  1051. PIRP pIrp = NULL;
  1052. STORE_CURRENT_IRQL;
  1053. TRACE( TL_T, TM_Mp, ( "==>nicAsyncRead, Remote Node, %x ", pRemoteNode ) );
  1054. TRACE( TL_V, TM_Mp, ( " fulFlags %x, Mdl %x, Generation %x, pNtStatus %x",
  1055. fulFlags, Mdl, ulGeneration, pNtStatus ) );
  1056. ASSERT(DestinationAddress.IA_Destination_Offset.Off_High == INITIAL_REGISTER_SPACE_HI);
  1057. do
  1058. {
  1059. NdisStatus = nicGetIrb (&pIrb);
  1060. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1061. {
  1062. BREAK ( TM_Irp, ( "nicAsyncRead, nicGetIrb FAILED" ) );
  1063. }
  1064. ASSERT ( pIrb != NULL);
  1065. pIrb->FunctionNumber = REQUEST_ASYNC_READ;
  1066. pIrb->Flags = 0;
  1067. pIrb->u.AsyncRead.DestinationAddress = DestinationAddress;
  1068. pIrb->u.AsyncRead.nNumberOfBytesToRead = nNumberOfBytesToRead ;
  1069. pIrb->u.AsyncRead.nBlockSize = nBlockSize ;
  1070. pIrb->u.AsyncRead.fulFlags = fulFlags;
  1071. pIrb->u.AsyncRead.Mdl = Mdl;
  1072. pIrb->u.AsyncRead.ulGeneration = ulGeneration;
  1073. NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
  1074. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1075. {
  1076. BREAK ( TM_Irp, ( "nicAsyncRead, nicGetIrp FAILED" ) );
  1077. break;
  1078. }
  1079. ASSERT (pIrp != NULL);
  1080. NdisStatus = nicSubmitIrp_Synch ( pRemoteNode,
  1081. pIrp,
  1082. pIrb );
  1083. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1084. {
  1085. TRACE ( TL_A, TM_Irp, ( "nicAsyncRead, nicSubmitIrp_Synch FAILED %xm pRemoteNode %x", NdisStatus, pRemoteNode) );
  1086. break;
  1087. }
  1088. if (pNtStatus != NULL)
  1089. {
  1090. *pNtStatus = pIrp->IoStatus.Status;
  1091. }
  1092. } while (FALSE);
  1093. TRACE( TL_T, TM_Mp, ( "<==nicAsyncRead, Status, %x ", NdisStatus) );
  1094. nicFreeIrb (pIrb);
  1095. nicFreeIrp (pIrp);
  1096. return NdisStatus;
  1097. }
  1098. NDIS_STATUS
  1099. nicAsyncWrite_Synch(
  1100. PREMOTE_NODE pRemoteNode,
  1101. IO_ADDRESS DestinationAddress, // Address to write to
  1102. ULONG nNumberOfBytesToWrite, // Bytes to write
  1103. ULONG nBlockSize, // Block size of write
  1104. ULONG fulFlags, // Flags pertinent to write
  1105. PMDL Mdl, // Destination buffer
  1106. ULONG ulGeneration, // Generation as known by driver
  1107. OUT NTSTATUS *pNtStatus // pointer to NTSTatus returned by the IRP
  1108. )
  1109. // Function Description:
  1110. // This performs an asynchronous write operation in thje remote node's
  1111. // address space
  1112. //
  1113. // Arguments
  1114. //PREMOTE_NODE pRemoteNode // Remote Node which owns the Destination address
  1115. //IO_ADDRESS DestinationAddress; // Address to write to
  1116. //ULONG nNumberOfBytesToWrite; // Bytes to write
  1117. //ULONG nBlockSize; // Block size of write
  1118. //ULONG fulFlags; // Flags pertinent to write
  1119. //PMDL Mdl; // Destination buffer
  1120. //ULONG ulGeneration; // Generation as known by driver
  1121. //
  1122. // Return Value:
  1123. // Success - if successful
  1124. // Invalid Generation
  1125. //
  1126. //
  1127. {
  1128. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1129. PIRB pIrb = NULL;
  1130. PIRP pIrp = NULL;
  1131. STORE_CURRENT_IRQL;
  1132. TRACE( TL_T, TM_Mp, ( "==>nicAsyncWrite_Synch, Remote Node, %x ", pRemoteNode ) );
  1133. TRACE( TL_V, TM_Mp, ( " Destination %x, nNumberOfBytesToWrite %x, nBlockSize %x",
  1134. DestinationAddress, nNumberOfBytesToWrite, nBlockSize) );
  1135. TRACE( TL_V, TM_Mp, ( " fulFlags %x, , Mdl %x, Generation %x, pNtStatus %x",
  1136. fulFlags , Mdl, ulGeneration, pNtStatus ) );
  1137. do
  1138. {
  1139. NdisStatus = nicGetIrb (&pIrb);
  1140. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1141. {
  1142. BREAK ( TM_Irp, ( "nicAsyncWrite_Synch, nicGetIrb FAILED" ) );
  1143. }
  1144. ASSERT ( pIrb != NULL);
  1145. pIrb->FunctionNumber = REQUEST_ASYNC_WRITE;
  1146. pIrb->Flags = 0;
  1147. pIrb->u.AsyncWrite.DestinationAddress = DestinationAddress;
  1148. pIrb->u.AsyncWrite.nNumberOfBytesToWrite = nNumberOfBytesToWrite;
  1149. pIrb->u.AsyncWrite.nBlockSize = nBlockSize;
  1150. pIrb->u.AsyncWrite.fulFlags = fulFlags;
  1151. pIrb->u.AsyncWrite.Mdl = Mdl;
  1152. pIrb->u.AsyncWrite.ulGeneration = ulGeneration;
  1153. NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
  1154. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1155. {
  1156. BREAK ( TM_Irp, ( "nicAsyncWrite_Synch, nicGetIrp FAILED" ) );
  1157. break;
  1158. }
  1159. ASSERT (pIrp != NULL);
  1160. NdisStatus = nicSubmitIrp_Synch ( pRemoteNode,
  1161. pIrp,
  1162. pIrb );
  1163. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1164. {
  1165. TRACE ( TL_A, TM_Irp, ( "nicAsyncWrite_Synch, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1166. break;
  1167. }
  1168. if (pNtStatus != NULL)
  1169. {
  1170. *pNtStatus = pIrp->IoStatus.Status;
  1171. }
  1172. } while (FALSE);
  1173. TRACE( TL_T, TM_Mp, ( "<==nicAsyncWrite_Synch, Success , %x Nt %x", NdisStatus, pIrp->IoStatus.Status) );
  1174. nicFreeIrb (pIrb);
  1175. nicFreeIrp (pIrp);
  1176. return NdisStatus;
  1177. }
  1178. NDIS_STATUS
  1179. nicIsochAllocateResources (
  1180. IN PADAPTERCB pAdapter,
  1181. IN ULONG fulSpeed, // Speed flags
  1182. IN ULONG fulFlags, // Flags
  1183. IN ULONG nChannel, // Channel to be used
  1184. IN ULONG nMaxBytesPerFrame, // Expected size of Isoch frame
  1185. IN ULONG nNumberOfBuffers, // Number of buffer(s) that will be attached
  1186. IN ULONG nMaxBufferSize, // Max size of buffer(s)
  1187. IN ULONG nQuadletsToStrip, // Number striped from start of every packet
  1188. IN ULARGE_INTEGER uliChannelMask, // ChannelMask for Multiple channels
  1189. IN OUT PHANDLE phResource // handle to Resource
  1190. )
  1191. // Function Description:
  1192. // This function sends an allocate resources irp to the driver. The miniport must do this before it
  1193. // attempts any channel operation
  1194. // Arguments
  1195. // Taken from documentation for the IsochAllocateResources
  1196. // fulSpeed - should be the max speed the tx side is expected to stream
  1197. // The payload size in nMaxBytesPerFram cannot exceed the max payload for
  1198. // for this speed.
  1199. // fulFlags - For receive, wtih the standard header stripped, the field should
  1200. // be = (RESOURCE_USED_IN_LISTEN | RESOURCES_STRIP_ADDITIONAL_QUADLETS)
  1201. // Also nQuadletsToStrip = 1
  1202. // For no stripping set nQuadsTostrip to 0 and dont specify the stripping flag.
  1203. // nMaxBytesPerframe - If not stripping it should include the 8 bytes for header/trailer
  1204. // expected to be recieved for each packet.
  1205. // nNumberOfBuffer - see below
  1206. // nMaxBufferSize - This should be always such mode(nMaxBufferSize,nMaxBytesPerFrame) == 0
  1207. // (integer product of number of bytes per packet).
  1208. // nQuadletsTostrip - If stripping only one quadlet (standrd iso header) this is set to 1
  1209. // if zero, the isoch header will be included AND the trailer. So 8 bytes extra will be recieved
  1210. // hResource - see below
  1211. // Return Value:
  1212. // Success if the channel was allocated
  1213. // Failure otherwise
  1214. //
  1215. {
  1216. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1217. PIRB pIrb = NULL;
  1218. PIRP pIrp = NULL;
  1219. STORE_CURRENT_IRQL;
  1220. TRACE( TL_T, TM_Irp, ( "==>nicIsochAllocateResources ") );
  1221. ASSERT (fulSpeed != 0); // 0 is undefined in ISOCH_SP...
  1222. do
  1223. {
  1224. NdisStatus = nicGetIrb (&pIrb);
  1225. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1226. {
  1227. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicGetIrb FAILED" ) );
  1228. break;
  1229. }
  1230. ASSERT ( pIrb != NULL);
  1231. //
  1232. //Initialize the datastructures in the Irb
  1233. //
  1234. pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_RESOURCES;
  1235. pIrb->Flags = 0;
  1236. pIrb->u.IsochAllocateResources.fulSpeed = fulSpeed;
  1237. pIrb->u.IsochAllocateResources.fulFlags = fulFlags;
  1238. pIrb->u.IsochAllocateResources.nChannel = nChannel;
  1239. pIrb->u.IsochAllocateResources.nMaxBytesPerFrame = nMaxBytesPerFrame;
  1240. pIrb->u.IsochAllocateResources.nNumberOfBuffers = nNumberOfBuffers;
  1241. pIrb->u.IsochAllocateResources.nMaxBufferSize = nMaxBufferSize;
  1242. pIrb->u.IsochAllocateResources.nQuadletsToStrip = nQuadletsToStrip;
  1243. pIrb->u.IsochAllocateResources.ChannelMask = uliChannelMask;
  1244. nicIsochAllocateResourcesDebugSpew(pIrb);
  1245. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  1246. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1247. {
  1248. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicGetIrp FAILED" ) );
  1249. break;
  1250. }
  1251. ASSERT (pIrp != NULL);
  1252. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1253. pIrp,
  1254. pIrb );
  1255. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1256. {
  1257. TRACE( TL_A, TM_Irp, ( "nicIsochAllocateResources , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1258. break;
  1259. }
  1260. TRACE( TL_N, TM_Irp, ( "nicIsochAllocateResources Succeeded hResource %x", pIrb->u.IsochAllocateResources.hResource) );
  1261. *phResource = pIrb->u.IsochAllocateResources.hResource;
  1262. } while (FALSE);
  1263. //
  1264. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1265. // functions return immediately
  1266. //
  1267. nicFreeIrb (pIrb);
  1268. nicFreeIrp (pIrp);
  1269. TRACE( TL_T, TM_Irp, ( "<==nicIsochAllocateResources , Status %x, hResource %x", NdisStatus, *phResource ) );
  1270. MATCH_IRQL;
  1271. return NdisStatus;
  1272. }
  1273. VOID
  1274. nicIsochAllocateResourcesDebugSpew(
  1275. IN PIRB pIrb)
  1276. {
  1277. TRACE( TL_V, TM_Irp, ( " Speed %x", pIrb->u.IsochAllocateResources.fulSpeed ) );
  1278. TRACE( TL_V, TM_Irp, ( " flags %x", pIrb->u.IsochAllocateResources.fulFlags ) );
  1279. TRACE( TL_V, TM_Irp, ( " Channel %x", pIrb->u.IsochAllocateResources.nChannel ) );
  1280. TRACE( TL_V, TM_Irp, ( " nMaxBytesPerFrame %x", pIrb->u.IsochAllocateResources.nMaxBytesPerFrame ) );
  1281. TRACE( TL_V, TM_Irp, ( " nNumberOfBuffers %x", pIrb->u.IsochAllocateResources.nNumberOfBuffers ) );
  1282. TRACE( TL_V, TM_Irp, ( " nMaxBufferSize %x", pIrb->u.IsochAllocateResources.nMaxBufferSize ) );
  1283. TRACE( TL_V, TM_Irp, ( " nQuadletsToStrip %x", pIrb->u.IsochAllocateResources.nQuadletsToStrip ) );
  1284. TRACE( TL_V, TM_Irp, ( " pIrb->u.IsochAllocateResources.ChannelMask %I64x", pIrb->u.IsochAllocateResources.ChannelMask ) );
  1285. }
  1286. NDIS_STATUS
  1287. nicIsochFreeBandwidth(
  1288. IN REMOTE_NODE *pRemoteNode,
  1289. IN HANDLE hBandwidth
  1290. )
  1291. // Function Description:
  1292. // Arguments
  1293. //
  1294. // Return Value:
  1295. //
  1296. {
  1297. PIRP pIrp = NULL;
  1298. PIRB pIrb = NULL;
  1299. DEVICE_OBJECT * pPdo = pRemoteNode->pPdo;
  1300. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  1301. TRACE( TL_T, TM_Irp, ( "==>nicIsochFreeBandwidth pRemoteNode %x, hBandwidth %8x", pRemoteNode , hBandwidth) );
  1302. ASSERT (pRemoteNode != NULL);
  1303. ASSERT (pRemoteNode->pPdo != NULL);
  1304. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  1305. ASSERT (hBandwidth != NULL);
  1306. do
  1307. {
  1308. if (pRemoteNode->pPdo == NULL)
  1309. {
  1310. TRACE( TL_A, TM_Irp, ( "pPdo is NULL in nicIsochFreeBandwidth" ) );
  1311. NdisStatus = NDIS_STATUS_FAILURE;
  1312. break;
  1313. }
  1314. NdisStatus = nicGetIrb(&pIrb);
  1315. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1316. {
  1317. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicIsochFreeBandwidth" ) );
  1318. break;
  1319. }
  1320. ASSERT (pRemoteNode->pPdo != NULL);
  1321. NdisStatus = nicGetIrp ( pRemoteNode->pPdo, &pIrp);
  1322. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1323. {
  1324. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicIsochFreeBandwidth" ) );
  1325. break;
  1326. }
  1327. //
  1328. //Initialize the datastructures in the Irb
  1329. //
  1330. pIrb->FunctionNumber = REQUEST_ISOCH_FREE_BANDWIDTH;
  1331. pIrb->Flags = 0;
  1332. pIrb->u.IsochFreeBandwidth.hBandwidth = hBandwidth;
  1333. NdisStatus = nicSubmitIrp_Synch( pRemoteNode,
  1334. pIrp,
  1335. pIrb );
  1336. } while (FALSE);
  1337. //
  1338. // Free the locally allocated memory
  1339. //
  1340. if (pIrp!= NULL)
  1341. {
  1342. nicFreeIrp(pIrp);
  1343. }
  1344. if (pIrb != NULL)
  1345. {
  1346. nicFreeIrb(pIrb);
  1347. }
  1348. //
  1349. // We do not care about the status, because we do not know what to do if it fails.
  1350. // However, spew some debug out.
  1351. //
  1352. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1353. {
  1354. TRACE( TL_N, TM_Irp, ( "nicIsochFreeBandwidth FAILED %x", NdisStatus) );
  1355. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  1356. }
  1357. TRACE( TL_T, TM_Irp, ( "<==nicIsochFreeBandwidth Status %x (always success)", NdisStatus) );
  1358. NdisStatus = NDIS_STATUS_SUCCESS;
  1359. return NdisStatus;
  1360. }
  1361. NDIS_STATUS
  1362. nicIsochFreeResources(
  1363. IN PADAPTERCB pAdapter,
  1364. IN HANDLE hResource
  1365. )
  1366. // Function Description:
  1367. // Arguments
  1368. //
  1369. // Return Value:
  1370. //
  1371. {
  1372. PIRP pIrp = NULL;
  1373. PIRB pIrb = NULL;
  1374. PDEVICE_OBJECT pPdo = pAdapter->pNdisDeviceObject;
  1375. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  1376. TRACE( TL_T, TM_Irp, ( "==>nicIsochFreeResources pAdapter %x, hResource %8x", pAdapter, hResource) );
  1377. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  1378. ASSERT (hResource != NULL);
  1379. do
  1380. {
  1381. NdisStatus = nicGetIrb(&pIrb);
  1382. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1383. {
  1384. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicIsochFreeResources" ) );
  1385. break;
  1386. }
  1387. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1388. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1389. {
  1390. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicIsochFreeResources" ) );
  1391. break;
  1392. }
  1393. //
  1394. //Initialize the datastructures in the Irb
  1395. //
  1396. pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
  1397. pIrb->Flags = 0;
  1398. pIrb->u.IsochFreeResources.hResource = hResource;
  1399. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
  1400. pIrp,
  1401. pIrb );
  1402. } while (FALSE);
  1403. //
  1404. // Free the locally allocated memory
  1405. //
  1406. if (pIrp!= NULL)
  1407. {
  1408. nicFreeIrp(pIrp);
  1409. }
  1410. if (pIrb != NULL)
  1411. {
  1412. nicFreeIrb(pIrb);
  1413. }
  1414. //
  1415. // We do not care about the status, because we do not know what to do if it fails.
  1416. // However, spew some debug out.
  1417. //
  1418. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1419. {
  1420. TRACE( TL_N, TM_Irp, ( "nicIsochFreeResources FAILED %x", NdisStatus) );
  1421. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  1422. }
  1423. TRACE( TL_T, TM_Irp, ( "<==nicIsochFreeResources Status %x (always success)", NdisStatus) );
  1424. NdisStatus = NDIS_STATUS_SUCCESS;
  1425. return NdisStatus;
  1426. }
  1427. NDIS_STATUS
  1428. nicIsochModifyStreamProperties (
  1429. PADAPTERCB pAdapter,
  1430. NDIS_HANDLE hResource,
  1431. ULARGE_INTEGER ullChannelMap,
  1432. ULONG ulSpeed)
  1433. /*++
  1434. Routine Description:
  1435. Sets up the Irp and uses the VDO to do an IoCallDriver
  1436. Arguments:
  1437. Return Value:
  1438. --*/
  1439. {
  1440. PIRP pIrp = NULL;
  1441. PIRB pIrb = NULL;
  1442. PDEVICE_OBJECT pPdo = pAdapter->pNdisDeviceObject;
  1443. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  1444. TRACE( TL_T, TM_Irp, ( "==>nicIsochModifyStreamProperties pAdapter %x, hResource %x, Speed %x, ChannelMap %I64x",
  1445. pAdapter,
  1446. hResource,
  1447. ulSpeed,
  1448. ullChannelMap) );
  1449. ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);
  1450. ASSERT (hResource != NULL);
  1451. do
  1452. {
  1453. NdisStatus = nicGetIrb(&pIrb);
  1454. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1455. {
  1456. TRACE( TL_A, TM_Irp, ( "nicGetIrb failed in nicIsochModifyStreamProperties " ) );
  1457. break;
  1458. }
  1459. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1460. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1461. {
  1462. TRACE( TL_A, TM_Irp, ( "nicGetIrp failed in nicIsochModifyStreamProperties " ) );
  1463. break;
  1464. }
  1465. //
  1466. //Initialize the datastructures in the Irb
  1467. //
  1468. pIrb->FunctionNumber = REQUEST_ISOCH_MODIFY_STREAM_PROPERTIES ;
  1469. pIrb->Flags = 0;
  1470. pIrb->u.IsochModifyStreamProperties.hResource = hResource;
  1471. pIrb->u.IsochModifyStreamProperties.ChannelMask = ullChannelMap;
  1472. pIrb->u.IsochModifyStreamProperties.fulSpeed = ulSpeed;
  1473. NdisStatus = nicSubmitIrp_LocalHostSynch( pAdapter,
  1474. pIrp,
  1475. pIrb );
  1476. } while (FALSE);
  1477. //
  1478. // Free the locally allocated memory
  1479. //
  1480. if (pIrp!= NULL)
  1481. {
  1482. nicFreeIrp(pIrp);
  1483. }
  1484. if (pIrb != NULL)
  1485. {
  1486. nicFreeIrb(pIrb);
  1487. }
  1488. //
  1489. // We do not care about the status, because we do not know what to do if it fails.
  1490. // However, spew some debug out.
  1491. //
  1492. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1493. {
  1494. TRACE( TL_N, TM_Irp, ( "nicIsochModifyStreamProperties FAILED %x", NdisStatus) );
  1495. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  1496. }
  1497. TRACE( TL_T, TM_Irp, ( "<==nicIsochModifyStreamProperties Status %x (always success)", NdisStatus) );
  1498. return NdisStatus;
  1499. }
  1500. NDIS_STATUS
  1501. nicBusReset (
  1502. IN PADAPTERCB pAdapter,
  1503. IN OUT ULONG fulFlags
  1504. )
  1505. // Function Description:
  1506. // This function sends an Irp to the Bus driver to reset the bus
  1507. // Any remote Pdo can be used for the Irp.
  1508. // A flag can be set to force the root to be reset
  1509. // Arguments
  1510. // PdoCb The Pdo for the remote node to which the Irp is submitted
  1511. //
  1512. // Return Value:
  1513. // Success if the Irp Succeeded
  1514. // Failure otherwise
  1515. //
  1516. {
  1517. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1518. PIRB pIrb = NULL;
  1519. PIRP pIrp = NULL;
  1520. PDEVICE_OBJECT pPdo = pAdapter->pNdisDeviceObject;
  1521. STORE_CURRENT_IRQL;
  1522. TRACE( TL_T, TM_Irp, ( "==>nicBusReset , PdoCb, %x Flags %x", pAdapter, fulFlags ) );
  1523. ASSERT (pPdo != NULL);
  1524. do
  1525. {
  1526. NdisStatus = nicGetIrb (&pIrb);
  1527. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1528. {
  1529. TRACE( TL_A, TM_Irp, ( "nicBusReset , nicGetIrb FAILED" ) );
  1530. break;
  1531. }
  1532. ASSERT ( pIrb != NULL);
  1533. //
  1534. //Initialize the datastructures in the Irb
  1535. //
  1536. pIrb->FunctionNumber = REQUEST_BUS_RESET;
  1537. pIrb->Flags = 0;
  1538. pIrb->u.BusReset.fulFlags = fulFlags;
  1539. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1540. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1541. {
  1542. TRACE( TL_A, TM_Irp, ( "nicBusReset, nicGetIrp FAILED" ) );
  1543. break;
  1544. }
  1545. ASSERT (pIrp != NULL);
  1546. TRACE( TL_N, TM_Irp, ( "BUS RESET, Flags%d on pAdapter %x", fulFlags, pAdapter) );
  1547. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1548. pIrp,
  1549. pIrb );
  1550. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1551. {
  1552. TRACE( TL_A, TM_Irp, ( "nicBusReset , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1553. break;
  1554. }
  1555. NdisInterlockedIncrement (&pAdapter->AdaptStats.ulNumResetsIssued);
  1556. } while (FALSE);
  1557. //
  1558. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1559. // functions return immediately
  1560. //
  1561. nicFreeIrb (pIrb);
  1562. nicFreeIrp (pIrp);
  1563. TRACE( TL_T, TM_Irp, ( "<==nicBusReset %x", NdisStatus ) );
  1564. MATCH_IRQL;
  1565. return NdisStatus;
  1566. }
  1567. NDIS_STATUS
  1568. nicBusResetNotification (
  1569. IN PADAPTERCB pAdapter,
  1570. IN ULONG fulFlags,
  1571. IN PBUS_BUS_RESET_NOTIFICATION pResetRoutine,
  1572. IN PVOID pResetContext
  1573. )
  1574. // Function Description:
  1575. // This function sends an Irp to the Bus driver to register/deregister
  1576. // a notification routine. Any remote Pdo can be used for the Irp.
  1577. //
  1578. // Arguments
  1579. // PdoCb The Pdo for the remote node to which the Irp is submitted
  1580. //
  1581. // Return Value:
  1582. // Success if the Irp Succeeded
  1583. // Failure otherwise
  1584. //
  1585. {
  1586. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1587. PDEVICE_OBJECT pPdo = pAdapter->pNdisDeviceObject;
  1588. PIRB pIrb = NULL;
  1589. PIRP pIrp = NULL;
  1590. STORE_CURRENT_IRQL;
  1591. TRACE( TL_T, TM_Irp, ( "==>nicBusResetNotification, pAdapter %x, Flags %x, Routine %x, Context %x", pAdapter, fulFlags, pResetRoutine, pResetContext ) );
  1592. ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
  1593. do
  1594. {
  1595. NdisStatus = nicGetIrb (&pIrb);
  1596. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1597. {
  1598. TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicGetIrb FAILED" ) );
  1599. break;
  1600. }
  1601. ASSERT ( pIrb != NULL);
  1602. //
  1603. //Initialize the datastructures in the Irb
  1604. //
  1605. pIrb->FunctionNumber = REQUEST_BUS_RESET_NOTIFICATION;
  1606. pIrb->Flags = 0;
  1607. pIrb->u.BusResetNotification.fulFlags = fulFlags;
  1608. pIrb->u.BusResetNotification.ResetRoutine = pResetRoutine;
  1609. pIrb->u.BusResetNotification.ResetContext= pResetContext;
  1610. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1611. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1612. {
  1613. TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicGetIrp FAILED" ) );
  1614. break;
  1615. }
  1616. ASSERT (pIrp != NULL);
  1617. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1618. pIrp,
  1619. pIrb );
  1620. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1621. {
  1622. TRACE( TL_A, TM_Irp, ( "nicBusResetNotification , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1623. break;
  1624. }
  1625. TRACE( TL_N, TM_Irp, ( " nicBusResetNotification success, Flags %d on pAdapter %x", fulFlags, pAdapter) );
  1626. } while (FALSE);
  1627. //
  1628. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1629. // functions return immediately
  1630. //
  1631. nicFreeIrb (pIrb);
  1632. nicFreeIrp (pIrp);
  1633. MATCH_IRQL;
  1634. TRACE( TL_T, TM_Irp, ( "<==nicBusResetNotification %x", NdisStatus ) );
  1635. return NdisStatus;
  1636. }
  1637. NDIS_STATUS
  1638. nicAsyncStream (
  1639. PREMOTE_NODE pRemoteNodePdoCb,
  1640. ULONG nNumberOfBytesToStream, // Bytes to stream
  1641. ULONG fulFlags, // Flags pertinent to stream
  1642. PMDL pMdl, // Source buffer
  1643. ULONG ulTag, // Tag
  1644. ULONG nChannel, // Channel
  1645. ULONG ulSynch, // Sy
  1646. ULONG Reserved, // Reserved for future use
  1647. UCHAR nSpeed
  1648. )
  1649. // Function Description:
  1650. // This is the interface to the Bus Apis. This will cause transmission on
  1651. // an isochronous channel. The data is supllied by a single Mdl
  1652. //
  1653. // Arguments
  1654. //
  1655. // nNumberOfBytesToStream, // Bytes to stream
  1656. // fulFlags, // Flags pertinent to stream
  1657. // Mdl, // Source buffer
  1658. // ulTag, // Tag
  1659. // nChannel, // Channel
  1660. // ulSynch, // Sy
  1661. // Reserved, // Reserved for future use
  1662. // nSpeed
  1663. //
  1664. //
  1665. // Return Value:
  1666. // Status of the Irp
  1667. {
  1668. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1669. PIRB pIrb = NULL;
  1670. PIRP pIrp = NULL;
  1671. TRACE( TL_T, TM_Irp, ( "==>nicAsyncStream , pRemoteNodePdoCb %x, Mdl %x", pRemoteNodePdoCb, pMdl) );
  1672. ASSERT (pRemoteNodePdoCb->pPdo != NULL);
  1673. ASSERT (pMdl != NULL);
  1674. do
  1675. {
  1676. NdisStatus = nicGetIrb (&pIrb);
  1677. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1678. {
  1679. TRACE( TL_A, TM_Irp, ( "nicAsyncStream , nicGetIrb FAILED" ) );
  1680. break;
  1681. }
  1682. ASSERT ( pIrb != NULL);
  1683. pIrb->FunctionNumber = REQUEST_ASYNC_STREAM;
  1684. pIrb->Flags = 0;
  1685. pIrb->u.AsyncStream.nNumberOfBytesToStream = nNumberOfBytesToStream;
  1686. pIrb->u.AsyncStream.fulFlags = fulFlags;
  1687. pIrb->u.AsyncStream.ulTag = ulTag;
  1688. pIrb->u.AsyncStream.nChannel = nChannel;
  1689. pIrb->u.AsyncStream.ulSynch = ulSynch;
  1690. pIrb->u.AsyncStream.nSpeed = nSpeed;
  1691. pIrb->u.AsyncStream.Mdl = pMdl;
  1692. nicAsyncStreamDebugSpew (pIrb);
  1693. NdisStatus = nicGetIrp ( pRemoteNodePdoCb->pPdo,
  1694. &pIrp );
  1695. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1696. {
  1697. TRACE( TL_A, TM_Irp, ( "nicAsyncStream , nicGetIrp FAILED" ) );
  1698. break;
  1699. }
  1700. ASSERT (pIrp != NULL);
  1701. ASSERT ( REMOTE_NODE_TEST_FLAG (pRemoteNodePdoCb, PDO_Activated) );
  1702. NdisStatus = nicSubmitIrp_Synch ( pRemoteNodePdoCb,
  1703. pIrp,
  1704. pIrb );
  1705. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1706. {
  1707. TRACE( TL_A, TM_Irp, ( "nicAsyncStream , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1708. break;
  1709. }
  1710. } while (FALSE);
  1711. //
  1712. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1713. // functions return immediately
  1714. //
  1715. if (pIrb != NULL)
  1716. {
  1717. nicFreeIrb (pIrb);
  1718. }
  1719. if (pIrp != NULL)
  1720. {
  1721. nicFreeIrp (pIrp);
  1722. }
  1723. TRACE( TL_T, TM_Irp, ( "<==nicAsyncStream , Status %x", NdisStatus ) );
  1724. return NdisStatus;
  1725. }
  1726. VOID
  1727. nicAsyncStreamDebugSpew (
  1728. PIRB pIrb
  1729. )
  1730. // Function Description:
  1731. // This function prints out all the parameters for an async stream irb
  1732. // Arguments
  1733. // Irb - whose paramters will be printed out
  1734. // Return Value:
  1735. //
  1736. {
  1737. TRACE( TL_V, TM_Irp, ( "==>nicAsyncStreamDebugSpew " ) );
  1738. TRACE( TL_V, TM_Irp, ( "Number of Bytes to Stream %x ", pIrb->u.AsyncStream.nNumberOfBytesToStream ) );
  1739. TRACE( TL_V, TM_Irp, ( "fulFlags %x ", pIrb->u.AsyncStream.fulFlags ) );
  1740. TRACE( TL_V, TM_Irp, ( "ulTag %x ", pIrb->u.AsyncStream.ulTag ) );
  1741. TRACE( TL_V, TM_Irp, ( "Channel %x", pIrb->u.AsyncStream.nChannel ) );
  1742. TRACE( TL_V, TM_Irp, ( "Synch %x", pIrb->u.AsyncStream.ulSynch ) );
  1743. TRACE( TL_V, TM_Irp, ( "Speed %x", pIrb->u.AsyncStream.nSpeed ) );
  1744. TRACE( TL_V, TM_Irp, ( "Mdl %x", pIrb->u.AsyncStream.Mdl ) );
  1745. TRACE( TL_V, TM_Irp, ( "<==nicAsyncStreamDebugSpew " ) );
  1746. }
  1747. NDIS_STATUS
  1748. nicGetMaxSpeedBetweenDevices (
  1749. PADAPTERCB pAdapter,
  1750. UINT NumOfRemoteNodes,
  1751. PDEVICE_OBJECT pArrayDestinationPDO[64],
  1752. PULONG pSpeed
  1753. )
  1754. // Function Description:
  1755. // This function submits an irp to the bus driver
  1756. // to get the max speed between 2 nodes
  1757. // Uses REQUEST_GET_SPEED_BETWEEN_DEVICES
  1758. //
  1759. //
  1760. // Arguments
  1761. // Remote Node Start of an array of PDOs for remote nodes
  1762. // NumOfRemoteNodes The number of remote nodes we are interested in
  1763. // pArrayDestinationPDO = Array of Destination PDO's
  1764. // Return Value:
  1765. // Success if irp succeeded
  1766. // pSpeed will point to the Speed
  1767. //
  1768. {
  1769. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1770. UINT index =0;
  1771. PIRB pIrb = NULL;
  1772. PIRP pIrp = NULL;
  1773. BOOLEAN fRefRemoteNode = FALSE;
  1774. ULONG NumRemote = NumOfRemoteNodes;
  1775. TRACE( TL_T, TM_Irp, ( "==>nicGetMaxSpeedBetweenDevices pRemoteNodeArray %x",
  1776. pArrayDestinationPDO ) );
  1777. TRACE( TL_T, TM_Irp, ( "==>NumOfRemoteNodes %x, pSpeed %x",
  1778. NumOfRemoteNodes, pSpeed ) );
  1779. do
  1780. {
  1781. NdisStatus = nicGetIrb (&pIrb);
  1782. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1783. {
  1784. TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicGetIrb FAILED" ) );
  1785. break;
  1786. }
  1787. ASSERT ( pIrb != NULL);
  1788. while (NumRemote != 0)
  1789. {
  1790. pIrb->u.GetMaxSpeedBetweenDevices.hDestinationDeviceObjects[NumRemote-1] = pArrayDestinationPDO[NumRemote-1];
  1791. TRACE( TL_V, TM_Irp, ( " NumRemote %x, hPdo[] %x = pArray[] %x",NumRemote ,
  1792. pIrb->u.GetMaxSpeedBetweenDevices.hDestinationDeviceObjects[NumRemote-1] ,pArrayDestinationPDO[NumRemote-1] ) );
  1793. TRACE( TL_V, TM_Irp, ( " &hPdo[] %x, &pArray[] %x",
  1794. &pIrb->u.GetMaxSpeedBetweenDevices.hDestinationDeviceObjects[NumRemote-1] ,&pArrayDestinationPDO[NumRemote-1] ) );
  1795. //
  1796. // catching a strange condition that debug spew showed up
  1797. //
  1798. ASSERT (pArrayDestinationPDO[NumRemote] != pArrayDestinationPDO[NumRemote-1]);
  1799. NumRemote --;
  1800. }
  1801. //
  1802. //Initialize the datastructures in the Irb
  1803. //
  1804. pIrb->FunctionNumber = REQUEST_GET_SPEED_BETWEEN_DEVICES;
  1805. pIrb->Flags = 0;
  1806. pIrb->u.GetMaxSpeedBetweenDevices.fulFlags = USE_LOCAL_NODE;
  1807. pIrb->u.GetMaxSpeedBetweenDevices.ulNumberOfDestinations = NumOfRemoteNodes;
  1808. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  1809. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1810. {
  1811. TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicGetIrp FAILED" ) );
  1812. break;
  1813. }
  1814. ASSERT (pIrp != NULL);
  1815. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1816. pIrp,
  1817. pIrb );
  1818. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1819. {
  1820. TRACE( TL_A, TM_Irp, ( "nicGetMaxSpeedBetweenDevices , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1821. break;
  1822. }
  1823. *pSpeed = pIrb->u.GetMaxSpeedBetweenDevices.fulSpeed ;
  1824. } while (FALSE);
  1825. //
  1826. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1827. // functions return immediately
  1828. //
  1829. nicFreeIrb (pIrb);
  1830. nicFreeIrp (pIrp);
  1831. TRACE( TL_T, TM_Irp, ( "<==nicGetMaxSpeedBetweenDevices Status %x, Speed %x",
  1832. NdisStatus, *pSpeed ) );
  1833. return NdisStatus;
  1834. }
  1835. NDIS_STATUS
  1836. nicIsochAttachBuffers (
  1837. IN PADAPTERCB pAdapter,
  1838. IN HANDLE hResource,
  1839. IN ULONG nNumberOfDescriptors,
  1840. PISOCH_DESCRIPTOR pIsochDescriptor
  1841. )
  1842. // Function Description:
  1843. //
  1844. // Arguments
  1845. //
  1846. // Return Value:
  1847. // Success if the Irp Succeeded
  1848. // Failure otherwise
  1849. //
  1850. {
  1851. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1852. PIRB pIrb = NULL;
  1853. PIRP pIrp = NULL;
  1854. STORE_CURRENT_IRQL;
  1855. ASSERT (pIsochDescriptor!=NULL);
  1856. ASSERT (hResource != NULL);
  1857. ASSERT (nNumberOfDescriptors > 0);
  1858. TRACE( TL_T, TM_Irp, ( "==>nicIsochAttachBuffers, pAdapter, %x ", pAdapter) );
  1859. TRACE( TL_N, TM_Irp, ( "hResource %x, nNumberOfDescriptors %x, pIsochDescriptor %x, ", hResource, nNumberOfDescriptors, pIsochDescriptor ) );
  1860. do
  1861. {
  1862. NdisStatus = nicGetIrb (&pIrb);
  1863. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1864. {
  1865. TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers, nicGetIrb FAILED" ) );
  1866. break;
  1867. }
  1868. ASSERT ( pIrb != NULL);
  1869. //
  1870. //Initialize the datastructures in the Irb
  1871. //
  1872. pIrb->FunctionNumber = REQUEST_ISOCH_ATTACH_BUFFERS;
  1873. pIrb->Flags = 0;
  1874. pIrb->u.IsochAttachBuffers.hResource = hResource ;
  1875. pIrb->u.IsochAttachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
  1876. pIrb->u.IsochAttachBuffers.pIsochDescriptor = pIsochDescriptor;
  1877. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  1878. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1879. {
  1880. TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers , nicGetIrp FAILED" ) );
  1881. break;
  1882. }
  1883. ASSERT (pIrp != NULL);
  1884. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1885. pIrp,
  1886. pIrb );
  1887. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1888. {
  1889. TRACE( TL_A, TM_Irp, ( "nicIsochAttachBuffers , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1890. break;
  1891. }
  1892. TRACE( TL_N, TM_Irp, ( "nicIsochAttachBuffers success") );
  1893. } while (FALSE);
  1894. //
  1895. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1896. // functions return immediately
  1897. //
  1898. nicFreeIrb (pIrb);
  1899. nicFreeIrp (pIrp);
  1900. MATCH_IRQL;
  1901. TRACE( TL_T, TM_Irp, ( "<==nicIsochAttachBuffers %x", NdisStatus ) );
  1902. return NdisStatus;
  1903. }
  1904. NDIS_STATUS
  1905. nicIsochDetachBuffers (
  1906. IN PADAPTERCB pAdapter,
  1907. IN HANDLE hResource,
  1908. IN ULONG nNumberOfDescriptors,
  1909. PISOCH_DESCRIPTOR pIsochDescriptor
  1910. )
  1911. // Function Description:
  1912. //
  1913. // Arguments
  1914. // HANDLE hResource; // Resource handle
  1915. // ULONG nNumberOfDescriptors; // Number to detach
  1916. // PISOCH_DESCRIPTOR pIsochDescriptor; // Pointer to Isoch descriptors - same as
  1917. // pointer used in Attach Buffers
  1918. // Return Status :
  1919. // Success if the Irp succeeded
  1920. //
  1921. {
  1922. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1923. PIRB pIrb = NULL;
  1924. PIRP pIrp = NULL;
  1925. PDEVICE_OBJECT pPdo = pAdapter->pNdisDeviceObject;
  1926. STORE_CURRENT_IRQL;
  1927. ASSERT (pIsochDescriptor!=NULL);
  1928. ASSERT (hResource != NULL);
  1929. ASSERT (nNumberOfDescriptors > 0);
  1930. TRACE( TL_T, TM_Irp, ( "==>nicIsochDetachBuffers, ") );
  1931. TRACE( TL_V, TM_Irp, ( "hResource %x, nNumberOfDescriptors %x, pIsochDescriptor %x, ", hResource, nNumberOfDescriptors, pIsochDescriptor ) );
  1932. do
  1933. {
  1934. NdisStatus = nicGetIrb (&pIrb);
  1935. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1936. {
  1937. TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers, nicGetIrb FAILED" ) );
  1938. break;
  1939. }
  1940. ASSERT ( pIrb != NULL);
  1941. //
  1942. //Initialize the datastructures in the Irb
  1943. //
  1944. pIrb->FunctionNumber = REQUEST_ISOCH_DETACH_BUFFERS;
  1945. pIrb->Flags = 0;
  1946. pIrb->u.IsochDetachBuffers.hResource = hResource ;
  1947. pIrb->u.IsochDetachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
  1948. pIrb->u.IsochDetachBuffers.pIsochDescriptor = pIsochDescriptor;
  1949. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  1950. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1951. {
  1952. TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers , nicGetIrp FAILED" ) );
  1953. break;
  1954. }
  1955. ASSERT (pIrp != NULL);
  1956. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  1957. pIrp,
  1958. pIrb );
  1959. if (NdisStatus != NDIS_STATUS_SUCCESS)
  1960. {
  1961. TRACE( TL_A, TM_Irp, ( "nicIsochDetachBuffers , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  1962. break;
  1963. }
  1964. TRACE( TL_V, TM_Irp, ( "nicIsochDetachBuffers success, ") );
  1965. } while (FALSE);
  1966. //
  1967. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  1968. // functions return immediately
  1969. //
  1970. nicFreeIrb (pIrb);
  1971. nicFreeIrp (pIrp);
  1972. MATCH_IRQL;
  1973. TRACE( TL_T, TM_Irp, ( "<==nicIsochDetachBuffers %x", NdisStatus ) );
  1974. return NdisStatus;
  1975. }
  1976. NDIS_STATUS
  1977. nicIsochListen (
  1978. IN PADAPTERCB pAdapter,
  1979. HANDLE hResource,
  1980. ULONG fulFlags,
  1981. CYCLE_TIME StartTime
  1982. )
  1983. // Function Description:
  1984. // Activates the bus driver to listen to data on that channel
  1985. // Arguments
  1986. // RemoteNode - Remote Node
  1987. // hResource - Handle to resource with ISochDescriptors
  1988. // Flags - not used yet
  1989. // Return Value:
  1990. // Success if the Irp Succeeded
  1991. // Failure otherwise
  1992. //
  1993. {
  1994. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  1995. PIRB pIrb = NULL;
  1996. PIRP pIrp = NULL;
  1997. STORE_CURRENT_IRQL;
  1998. ASSERT (hResource != NULL);
  1999. TRACE( TL_T, TM_Irp, ( "==>nicIsochListen, pAdapter %x, hResource %x ", pAdapter,hResource) );
  2000. do
  2001. {
  2002. NdisStatus = nicGetIrb (&pIrb);
  2003. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2004. {
  2005. TRACE( TL_A, TM_Irp, ( "nicIsochListen, nicGetIrb FAILED" ) );
  2006. break;
  2007. }
  2008. ASSERT ( pIrb != NULL);
  2009. //
  2010. //Initialize the datastructures in the Irb
  2011. //
  2012. pIrb->FunctionNumber = REQUEST_ISOCH_LISTEN;
  2013. pIrb->Flags = 0;
  2014. pIrb->u.IsochListen.hResource = hResource ;
  2015. pIrb->u.IsochListen.fulFlags = fulFlags;
  2016. pIrb->u.IsochListen.StartTime = StartTime;
  2017. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  2018. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2019. {
  2020. TRACE( TL_A, TM_Irp, ( "nicIsochListen , nicGetIrp FAILED" ) );
  2021. break;
  2022. }
  2023. ASSERT (pIrp != NULL);
  2024. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2025. pIrp,
  2026. pIrb );
  2027. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2028. {
  2029. TRACE( TL_A, TM_Irp, ( "nicIsochListen , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2030. break;
  2031. }
  2032. TRACE( TL_N, TM_Irp, ( "nicIsochListen success, pAdapter %x", pAdapter) );
  2033. } while (FALSE);
  2034. //
  2035. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2036. // functions return immediately
  2037. //
  2038. nicFreeIrb (pIrb);
  2039. nicFreeIrp (pIrp);
  2040. MATCH_IRQL;
  2041. TRACE( TL_T, TM_Irp, ( "<==nicIsochListen %x", NdisStatus ) );
  2042. return NdisStatus;
  2043. }
  2044. NDIS_STATUS
  2045. nicIsochStop (
  2046. IN PADAPTERCB pAdapter,
  2047. IN HANDLE hResource
  2048. )
  2049. // Function Description:
  2050. // Issues an IsochStop Irp to the Device
  2051. // Should stop Isoch IO on that resource
  2052. // Arguments
  2053. // PdoCb The Pdo for the remote node to which the Irp is submitted
  2054. //
  2055. // Return Value:
  2056. // Success if the Irp Succeeded
  2057. // Failure otherwise
  2058. //
  2059. {
  2060. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2061. PIRB pIrb = NULL;
  2062. PIRP pIrp = NULL;
  2063. PDEVICE_OBJECT pPdo = pAdapter->pNdisDeviceObject;
  2064. STORE_CURRENT_IRQL;
  2065. TRACE( TL_T, TM_Irp, ( "==>nicIsochStop , pPdo, %x hResource %x", pPdo, hResource) );
  2066. do
  2067. {
  2068. NdisStatus = nicGetIrb (&pIrb);
  2069. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2070. {
  2071. TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicGetIrb FAILED" ) );
  2072. break;
  2073. }
  2074. ASSERT ( pIrb != NULL);
  2075. //
  2076. //Initialize the datastructures in the Irb
  2077. //
  2078. pIrb->FunctionNumber = REQUEST_ISOCH_STOP;
  2079. pIrb->Flags = 0;
  2080. pIrb->u.IsochStop.hResource = hResource;
  2081. pIrb->u.IsochStop.fulFlags = 0;
  2082. NdisStatus = nicGetIrp (pPdo, &pIrp);
  2083. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2084. {
  2085. TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicGetIrp FAILED" ) );
  2086. break;
  2087. }
  2088. ASSERT (pIrp != NULL);
  2089. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2090. pIrp,
  2091. pIrb );
  2092. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2093. {
  2094. TRACE( TL_A, TM_Irp, ( "nicIsochStop , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2095. break;
  2096. }
  2097. } while (FALSE);
  2098. //
  2099. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2100. // functions return immediately
  2101. //
  2102. nicFreeIrb (pIrb);
  2103. nicFreeIrp (pIrp);
  2104. MATCH_IRQL;
  2105. TRACE( TL_T, TM_Irp, ( "<== nicIsochStop , Status ", NdisStatus) );
  2106. return NdisStatus;
  2107. }
  2108. NDIS_STATUS
  2109. nicGetLocalHostCSRTopologyMap(
  2110. IN PADAPTERCB pAdapter,
  2111. IN PULONG pLength,
  2112. IN PVOID pBuffer
  2113. )
  2114. // Function Description:
  2115. // Retrieves the local hosts CSR.
  2116. // Arguments
  2117. // pBuffer - LocalHostBuffer
  2118. //
  2119. // Return Value:
  2120. // Success if the Irp Succeeded
  2121. // Failure otherwise
  2122. //
  2123. {
  2124. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2125. PIRB pIrb = NULL;
  2126. PIRP pIrp = NULL;
  2127. GET_LOCAL_HOST_INFO6 LocalHostInfo6;
  2128. STORE_CURRENT_IRQL;
  2129. ASSERT (pLength != NULL);
  2130. ASSERT (pBuffer != NULL);
  2131. TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostCSRTopologyMap , pAdapter %x ,Length %x, Buffer",
  2132. pAdapter, *pLength, pBuffer) );
  2133. do
  2134. {
  2135. NdisStatus = nicGetIrb (&pIrb);
  2136. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2137. {
  2138. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrb FAILED" ) );
  2139. break;
  2140. }
  2141. ASSERT ( pIrb != NULL);
  2142. //
  2143. //Initialize the datastructures in the Irb
  2144. //
  2145. LocalHostInfo6.CsrBaseAddress.Off_High = INITIAL_REGISTER_SPACE_HI;
  2146. LocalHostInfo6.CsrBaseAddress.Off_Low = TOPOLOGY_MAP_LOCATION;
  2147. LocalHostInfo6.CsrDataLength = *pLength;
  2148. LocalHostInfo6.CsrDataBuffer = pBuffer;
  2149. pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
  2150. pIrb->Flags = 0;
  2151. pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CSR_CONTENTS;
  2152. pIrb->u.GetLocalHostInformation.Information = &LocalHostInfo6;
  2153. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  2154. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2155. {
  2156. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrp FAILED" ) );
  2157. break;
  2158. }
  2159. ASSERT (pIrp != NULL);
  2160. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2161. pIrp,
  2162. pIrb );
  2163. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2164. {
  2165. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2166. TRACE( TL_A, TM_Irp, ( "Length Needed %.x", LocalHostInfo6.CsrDataLength) );
  2167. if (pIrp->IoStatus.Status == STATUS_INVALID_BUFFER_SIZE)
  2168. {
  2169. *pLength = LocalHostInfo6.CsrDataLength;
  2170. }
  2171. break;
  2172. }
  2173. } while (FALSE);
  2174. //
  2175. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2176. // functions return immediately
  2177. //
  2178. nicFreeIrb (pIrb);
  2179. nicFreeIrp (pIrp);
  2180. MATCH_IRQL;
  2181. TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
  2182. return NdisStatus;
  2183. }
  2184. NDIS_STATUS
  2185. nicGetLocalHostConfigRom(
  2186. IN PADAPTERCB pAdapter,
  2187. OUT PVOID *ppCRom
  2188. )
  2189. // Function Description:
  2190. // Retrieves the local hosts CSR.
  2191. // Arguments
  2192. // pBuffer - Locally allocated. Caller has to free
  2193. //
  2194. // Return Value:
  2195. // Success if the Irp Succeeded
  2196. // Failure otherwise
  2197. //
  2198. {
  2199. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2200. PIRB pIrb = NULL;
  2201. PIRP pIrp = NULL;
  2202. GET_LOCAL_HOST_INFO5 Info;
  2203. PVOID pCRom;
  2204. STORE_CURRENT_IRQL;
  2205. TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostConfigRom, pAdapter %x ",
  2206. pAdapter) );
  2207. do
  2208. {
  2209. NdisStatus = nicGetIrb (&pIrb);
  2210. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2211. {
  2212. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom , nicGetIrb FAILED" ) );
  2213. break;
  2214. }
  2215. ASSERT ( pIrb != NULL);
  2216. Info.ConfigRom = NULL;
  2217. Info.ConfigRomLength = 0;
  2218. pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO ;
  2219. pIrb->Flags = 0;
  2220. pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CONFIG_ROM;
  2221. pIrb->u.GetLocalHostInformation.Information = &Info;
  2222. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  2223. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2224. {
  2225. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom , nicGetIrp FAILED" ) );
  2226. break;
  2227. }
  2228. ASSERT (pIrp != NULL);
  2229. //
  2230. // First find the length
  2231. //
  2232. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2233. pIrp,
  2234. pIrb );
  2235. if (Info.ConfigRomLength == 0)
  2236. {
  2237. NdisStatus = NDIS_STATUS_FAILURE;
  2238. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2239. break;
  2240. }
  2241. nicFreeIrp (pIrp);
  2242. pCRom = ALLOC_NONPAGED (Info.ConfigRomLength, 'C31N');
  2243. if (pCRom == NULL)
  2244. {
  2245. NdisStatus = NDIS_STATUS_FAILURE;
  2246. break;
  2247. }
  2248. Info.ConfigRom = pCRom;
  2249. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  2250. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2251. {
  2252. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicGetIrp FAILED" ) );
  2253. break;
  2254. }
  2255. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2256. pIrp,
  2257. pIrb );
  2258. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2259. {
  2260. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostConfigRom, nicGetIrp FAILED" ) );
  2261. break;
  2262. }
  2263. *ppCRom = pCRom;
  2264. } while (FALSE);
  2265. //
  2266. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2267. // functions return immediately
  2268. //
  2269. nicFreeIrb (pIrb);
  2270. nicFreeIrp (pIrp);
  2271. MATCH_IRQL;
  2272. TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
  2273. return NdisStatus;
  2274. }
  2275. NDIS_STATUS
  2276. nicGetConfigRom(
  2277. IN PDEVICE_OBJECT pPdo,
  2278. OUT PVOID *ppCrom
  2279. )
  2280. // Function Description:
  2281. // Retrieves the Config Rom from the Device Object.
  2282. // Caller responsibility to free this memory.
  2283. // Arguments
  2284. // pBuffer - LocalHostBuffer
  2285. //
  2286. // Return Value:
  2287. // Success if the Irp Succeeded
  2288. // Failure otherwise
  2289. //
  2290. {
  2291. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2292. PIRB pIrb = NULL;
  2293. PIRP pIrp = NULL;
  2294. ULONG SizeNeeded= 0;
  2295. PVOID pConfigInfoBuffer;
  2296. STORE_CURRENT_IRQL;
  2297. TRACE( TL_T, TM_Irp, ( "==>nicGetConfigRom, pPdo %x ",pPdo ) );
  2298. do
  2299. {
  2300. NdisStatus = nicGetIrb (&pIrb);
  2301. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2302. {
  2303. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrb FAILED" ) );
  2304. break;
  2305. }
  2306. ASSERT ( pIrb != NULL);
  2307. pIrb->FunctionNumber = REQUEST_GET_CONFIGURATION_INFO;
  2308. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  2309. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2310. {
  2311. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicGetIrp FAILED" ) );
  2312. break;
  2313. }
  2314. ASSERT (pIrp != NULL);
  2315. NdisStatus = nicSubmitIrp_PDOSynch ( pPdo,
  2316. pIrp,
  2317. pIrb );
  2318. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2319. {
  2320. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2321. break;
  2322. }
  2323. nicFreeIrp (pIrp);
  2324. SizeNeeded = sizeof(CONFIG_ROM) +pIrb->u.GetConfigurationInformation.UnitDirectoryBufferSize +
  2325. pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize +
  2326. pIrb->u.GetConfigurationInformation.VendorLeafBufferSize +
  2327. pIrb->u.GetConfigurationInformation.ModelLeafBufferSize;
  2328. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom , SixeNeeded %x", SizeNeeded) );
  2329. pConfigInfoBuffer = ALLOC_NONPAGED (SizeNeeded , 'C13N');
  2330. if (pConfigInfoBuffer == NULL)
  2331. {
  2332. NdisStatus = NDIS_STATUS_FAILURE;
  2333. break;
  2334. }
  2335. pIrb->u.GetConfigurationInformation.ConfigRom = (PCONFIG_ROM)pConfigInfoBuffer;
  2336. pIrb->u.GetConfigurationInformation.UnitDirectory = (PVOID)((PUCHAR)pConfigInfoBuffer + sizeof(CONFIG_ROM));
  2337. pIrb->u.GetConfigurationInformation.UnitDependentDirectory = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.UnitDirectory +
  2338. pIrb->u.GetConfigurationInformation.UnitDirectoryBufferSize);
  2339. pIrb->u.GetConfigurationInformation.VendorLeaf = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.UnitDependentDirectory +
  2340. pIrb->u.GetConfigurationInformation.UnitDependentDirectoryBufferSize);
  2341. pIrb->u.GetConfigurationInformation.ModelLeaf = (PVOID)((PUCHAR)pIrb->u.GetConfigurationInformation.VendorLeaf +
  2342. pIrb->u.GetConfigurationInformation.VendorLeafBufferSize);
  2343. pIrb->FunctionNumber = REQUEST_GET_CONFIGURATION_INFO;
  2344. NdisStatus = nicGetIrp ( pPdo, &pIrp);
  2345. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2346. {
  2347. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicGetIrp FAILED" ) );
  2348. break;
  2349. }
  2350. ASSERT (pIrp != NULL);
  2351. NdisStatus = nicSubmitIrp_PDOSynch ( pPdo,
  2352. pIrp,
  2353. pIrb );
  2354. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2355. {
  2356. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2357. break;
  2358. }
  2359. TRACE( TL_A, TM_Irp, ( "nicGetConfigRom, pConfigRom %x, Size %x", pConfigInfoBuffer , SizeNeeded ) );
  2360. *ppCrom = pConfigInfoBuffer;
  2361. } while (FALSE);
  2362. //
  2363. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2364. // functions return immediately
  2365. //
  2366. nicFreeIrb (pIrb);
  2367. nicFreeIrp (pIrp);
  2368. MATCH_IRQL;
  2369. TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostCSRTopologyMap , Status %x", NdisStatus) );
  2370. return NdisStatus;
  2371. }
  2372. NDIS_STATUS
  2373. nicGetReadWriteCapLocalHost(
  2374. IN PADAPTERCB pAdapter,
  2375. PGET_LOCAL_HOST_INFO2 pReadWriteCaps
  2376. )
  2377. /*++
  2378. Routine Description:
  2379. Gets the ReadWrite Capabilities for the local host
  2380. Arguments:
  2381. ReadWriteCaps - To be filled up byt the bus driver
  2382. Return Value:
  2383. --*/
  2384. {
  2385. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2386. PIRB pIrb = NULL;
  2387. PIRP pIrp = NULL;
  2388. STORE_CURRENT_IRQL;
  2389. TRACE( TL_T, TM_Irp, ( "==>nicGetReadWriteCapLocalHost, pAdapter %x pReadWriteCaps %x",
  2390. pAdapter, pReadWriteCaps) );
  2391. do
  2392. {
  2393. NdisStatus = nicGetIrb (&pIrb);
  2394. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2395. {
  2396. TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost , nicGetIrb FAILED" ) );
  2397. break;
  2398. }
  2399. ASSERT ( pIrb != NULL);
  2400. //
  2401. //Initialize the datastructures in the Irb
  2402. //
  2403. NdisZeroMemory (pReadWriteCaps, sizeof(*pReadWriteCaps));
  2404. pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
  2405. pIrb->Flags = 0;
  2406. pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_CAPABILITIES;
  2407. pIrb->u.GetLocalHostInformation.Information = pReadWriteCaps;
  2408. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  2409. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2410. {
  2411. TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost, nicGetIrp FAILED" ) );
  2412. break;
  2413. }
  2414. ASSERT (pIrp != NULL);
  2415. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2416. pIrp,
  2417. pIrb );
  2418. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2419. {
  2420. TRACE( TL_A, TM_Irp, ( "nicGetReadWriteCapLocalHost, nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2421. break;
  2422. }
  2423. } while (FALSE);
  2424. //
  2425. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2426. // functions return immediately
  2427. //
  2428. nicFreeIrb (pIrb);
  2429. nicFreeIrp (pIrp);
  2430. MATCH_IRQL;
  2431. TRACE( TL_T, TM_Irp, ( "<== nicGetReadWriteCapLocalHost, Status %x", NdisStatus) );
  2432. return NdisStatus;
  2433. }
  2434. NDIS_STATUS
  2435. nicSetLocalHostPropertiesCRom (
  2436. IN PADAPTERCB pAdapter,
  2437. IN PUCHAR pConfigRom,
  2438. IN ULONG Length,
  2439. IN ULONG Flags,
  2440. IN OUT PHANDLE phCromData,
  2441. IN OUT PMDL *ppConfigRomMdl
  2442. )
  2443. // Function Description:
  2444. // Allocates an MDL pointing to the Buffer
  2445. // and sends it to the bus driver
  2446. //
  2447. // Arguments
  2448. // pAdapter - Local host
  2449. // ConfigRom - Buffer to be sent to the bus driver
  2450. // Length - Length of the Config Rom Buffer
  2451. // Flags - Add or remove
  2452. // phConfigRom - if Remove then this is an input parameter
  2453. // Return Value:
  2454. // Handle - Is successful
  2455. //
  2456. {
  2457. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2458. PIRB pIrb = NULL;
  2459. PIRP pIrp = NULL;
  2460. PMDL pMdl = NULL;
  2461. SET_LOCAL_HOST_PROPS3 SetLocalHost3;
  2462. TRACE( TL_T, TM_Irp, ( "==>nicSetLocalHostPropertiesCRom , pAdapter %x, pConfigRom %x",pAdapter, pConfigRom) );
  2463. if (Flags == SLHP_FLAG_ADD_CROM_DATA)
  2464. {
  2465. TRACE( TL_T, TM_Irp, ( " ADD") );
  2466. }
  2467. else
  2468. {
  2469. TRACE( TL_T, TM_Irp, ( " REMOVE Handle %x", *pConfigRom) );
  2470. }
  2471. do
  2472. {
  2473. //
  2474. // Get an mdl describing the config rom
  2475. //
  2476. NdisStatus = nicGetIrb (&pIrb);
  2477. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2478. {
  2479. TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrb FAILED" ) );
  2480. break;
  2481. }
  2482. ASSERT ( pIrb != NULL);
  2483. //
  2484. // Initialize the set local host struct
  2485. //
  2486. if (Flags == SLHP_FLAG_ADD_CROM_DATA)
  2487. {
  2488. NdisStatus = nicGetMdl ( Length, pConfigRom, &pMdl);
  2489. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2490. {
  2491. TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrb FAILED" ) );
  2492. break;
  2493. }
  2494. SetLocalHost3.fulFlags = SLHP_FLAG_ADD_CROM_DATA;
  2495. SetLocalHost3.hCromData = NULL;
  2496. SetLocalHost3.nLength = Length;
  2497. SetLocalHost3.Mdl = pMdl;
  2498. }
  2499. else
  2500. {
  2501. SetLocalHost3.fulFlags = SLHP_FLAG_REMOVE_CROM_DATA ;
  2502. ASSERT (phCromData != NULL);
  2503. SetLocalHost3.hCromData = *phCromData;
  2504. }
  2505. pIrb->FunctionNumber = REQUEST_SET_LOCAL_HOST_PROPERTIES;
  2506. pIrb->Flags = 0;
  2507. pIrb->u.GetLocalHostInformation.nLevel = SET_LOCAL_HOST_PROPERTIES_MODIFY_CROM;
  2508. pIrb->u.GetLocalHostInformation.Information = &SetLocalHost3;
  2509. //
  2510. // Get an Irp
  2511. //
  2512. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  2513. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2514. {
  2515. TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicGetIrp FAILED" ) );
  2516. break;
  2517. }
  2518. ASSERT (pIrp != NULL);
  2519. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2520. pIrp,
  2521. pIrb );
  2522. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2523. {
  2524. TRACE( TL_A, TM_Irp, ( "nicSetLocalHostPropertiesCRom , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2525. break;
  2526. }
  2527. if (Flags == SLHP_FLAG_ADD_CROM_DATA)
  2528. {
  2529. *phCromData = SetLocalHost3.hCromData;
  2530. *ppConfigRomMdl = pMdl;
  2531. }
  2532. else
  2533. {
  2534. //
  2535. // Free the Mdl that contains the CROM
  2536. //
  2537. ASSERT (*ppConfigRomMdl);
  2538. nicFreeMdl (*ppConfigRomMdl);
  2539. }
  2540. } while (FALSE);
  2541. //
  2542. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2543. // functions return immediately
  2544. //
  2545. nicFreeIrb (pIrb);
  2546. nicFreeIrp (pIrp);
  2547. TRACE( TL_T, TM_Irp, ( "<==nicSetLocalHostPropertiesCRom pAdapter %x", pAdapter ) );
  2548. return NdisStatus;
  2549. }
  2550. NDIS_STATUS
  2551. nicGetLocalHostUniqueId(
  2552. IN PADAPTERCB pAdapter,
  2553. IN OUT PGET_LOCAL_HOST_INFO1 pUid
  2554. )
  2555. // Function Description:
  2556. // Retrieves the local hosts UniqueId.
  2557. // Arguments
  2558. // pBuffer - LocalHostBuffer
  2559. //
  2560. // Return Value:
  2561. // Success if the Irp Succeeded
  2562. // Failure otherwise
  2563. //
  2564. {
  2565. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2566. PIRB pIrb = NULL;
  2567. PIRP pIrp = NULL;
  2568. STORE_CURRENT_IRQL;
  2569. TRACE( TL_T, TM_Irp, ( "==>nicGetLocalHostUniqueId , pAdapter%x ,pUid",
  2570. pAdapter, pUid) );
  2571. do
  2572. {
  2573. ASSERT (pAdapter->pNdisDeviceObject != NULL);
  2574. NdisStatus = nicGetIrb (&pIrb);
  2575. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2576. {
  2577. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostUniqueId , nicGetIrb FAILED" ) );
  2578. break;
  2579. }
  2580. ASSERT ( pIrb != NULL);
  2581. //
  2582. //Initialize the datastructures in the Irb
  2583. //
  2584. pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
  2585. pIrb->Flags = 0;
  2586. pIrb->u.GetLocalHostInformation.nLevel = GET_HOST_UNIQUE_ID;
  2587. pIrb->u.GetLocalHostInformation.Information = (PVOID) pUid;
  2588. NdisStatus = nicGetIrp ( pAdapter->pNdisDeviceObject, &pIrp);
  2589. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2590. {
  2591. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostCSRTopologyMap , nicGetIrp FAILED" ) );
  2592. break;
  2593. }
  2594. ASSERT (pIrp != NULL);
  2595. NdisStatus = nicSubmitIrp_LocalHostSynch ( pAdapter,
  2596. pIrp,
  2597. pIrb );
  2598. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2599. {
  2600. TRACE( TL_A, TM_Irp, ( "nicGetLocalHostUniqueId , nicSubmitIrp_Synch FAILED %x", NdisStatus ) );
  2601. break;
  2602. }
  2603. } while (FALSE);
  2604. //
  2605. // Now free all the locally allocated resources. They can point to NULL, in which case the called
  2606. // functions return immediately
  2607. //
  2608. nicFreeIrb (pIrb);
  2609. nicFreeIrp (pIrp);
  2610. MATCH_IRQL;
  2611. TRACE( TL_T, TM_Irp, ( "<== nicGetLocalHostUniqueId , Status %x", NdisStatus) );
  2612. return NdisStatus;
  2613. }
  2614. //---------------------------------------------------------
  2615. // The routines to submit Irp's to the bus, synchronously or
  2616. // asynchronously begin here
  2617. //---------------------------------------------------------
  2618. NTSTATUS
  2619. nicSubmitIrp(
  2620. IN PDEVICE_OBJECT pPdo,
  2621. IN PIRP pIrp,
  2622. IN PIRB pIrb,
  2623. IN PIO_COMPLETION_ROUTINE pCompletion,
  2624. IN PVOID pContext
  2625. )
  2626. //
  2627. // This is the generic function used by all Irp Send Handlers
  2628. // to do an IoCallDriver. It sets up the next location in the
  2629. // stack prior to calling the Irp
  2630. // Make sure the Irp knows about the Irb by setting it up as an argument
  2631. //
  2632. {
  2633. NTSTATUS NtStatus ;
  2634. PIO_STACK_LOCATION NextIrpStack;
  2635. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp, pPdo %x, Irp %x, Irb %x, ",
  2636. pPdo, pIrp ,pIrb, pCompletion ) );
  2637. TRACE( TL_T, TM_Irp, ( " pCompletion %x, pContext %x",
  2638. pCompletion, pContext ) );
  2639. ASSERT (pPdo != NULL);
  2640. IoSetCompletionRoutine (pIrp,
  2641. pCompletion,
  2642. pContext,
  2643. TRUE,
  2644. TRUE,
  2645. TRUE);
  2646. //
  2647. // Insert the Irp as as the argument in the NextStack location for the IRP
  2648. //
  2649. if (pIrb)
  2650. {
  2651. NextIrpStack = IoGetNextIrpStackLocation (pIrp);
  2652. NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  2653. NextIrpStack->DeviceObject = pPdo;
  2654. NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
  2655. NextIrpStack->Parameters.Others.Argument1 = pIrb;
  2656. }
  2657. else
  2658. {
  2659. IoCopyCurrentIrpStackLocationToNext(pIrp);
  2660. }
  2661. //
  2662. // Reference the PDO and Submit the Irp
  2663. // If Ref fails, it means the PDO has been deactivated on another thread
  2664. //
  2665. NtStatus = IoCallDriver (pPdo, pIrp);
  2666. TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp, PDO %x, NtStatus %x",
  2667. pPdo, NtStatus ) );
  2668. //
  2669. // Since we did a IoCallDriver, we have a guarantee that the completion
  2670. // routine will be called. Exit gracefully
  2671. //
  2672. return NtStatus;
  2673. }
  2674. NDIS_STATUS
  2675. nicSubmitIrp_Synch(
  2676. IN REMOTE_NODE *pRemoteNode,
  2677. IN PIRP pIrp,
  2678. IN PIRB pIrb
  2679. )
  2680. // Callers need to make sure that no context is set for the Irp
  2681. // as it will be a synchronous call for them
  2682. //
  2683. // We refcount the Pdo block so that the pdo block will not disappear
  2684. // during the duration of the IoCallDriver
  2685. {
  2686. NDIS_EVENT NdisSynchEvent;
  2687. NTSTATUS NtStatus;
  2688. NDIS_STATUS NdisStatus;
  2689. BOOLEAN bSuccessful = FALSE;
  2690. BOOLEAN bIsPdoValid = FALSE;
  2691. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_Synch, PDO %x", pRemoteNode->pPdo ) );
  2692. ASSERT (pRemoteNode != NULL);
  2693. ASSERT (pRemoteNode->pPdo != NULL);
  2694. ASSERT (pIrp != NULL);
  2695. ASSERT (pIrb != NULL)
  2696. do
  2697. {
  2698. //
  2699. // Check to see if Pdo is Valid. We do not care here if the Pdo is being
  2700. // removed because Vcs may want to submit Irps as part of their cleanup
  2701. // process
  2702. //
  2703. REMOTE_NODE_ACQUIRE_LOCK (pRemoteNode);
  2704. if ( REMOTE_NODE_TEST_FLAG (pRemoteNode, PDO_Activated )
  2705. && (nicReferenceRemoteNode (pRemoteNode, "nicSubmitIrp_Synch") == TRUE) )
  2706. {
  2707. bIsPdoValid = TRUE;
  2708. }
  2709. REMOTE_NODE_RELEASE_LOCK (pRemoteNode);
  2710. if ( bIsPdoValid == FALSE)
  2711. {
  2712. NtStatus = STATUS_NO_SUCH_DEVICE;
  2713. TRACE( TL_A, TM_Irp, ( "==>PDO is NOT Valid, nicSubmitIrp_Synch, PdoCb %x, Pdo %x", pRemoteNode, pRemoteNode->pPdo ) );
  2714. break;
  2715. }
  2716. //
  2717. // Add a reference to the PDO block so it cannot be removed
  2718. // This reference is decremented at the end of this function
  2719. //
  2720. NdisInitializeEvent (&NdisSynchEvent);
  2721. NtStatus = nicSubmitIrp ( pRemoteNode->pPdo,
  2722. pIrp,
  2723. pIrb,
  2724. nicSubmitIrp_SynchComplete,
  2725. (PVOID)&NdisSynchEvent);
  2726. } while (FALSE);
  2727. if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
  2728. {
  2729. //
  2730. // Now we need to wait for the event to complete
  2731. // and return a good status if we do not hit the timeout
  2732. //
  2733. ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
  2734. bSuccessful = NdisWaitEvent (&NdisSynchEvent,0x0fffffff);
  2735. if (bSuccessful == TRUE)
  2736. {
  2737. //
  2738. // We waited successfully. Now lets see how the Irp fared.
  2739. //
  2740. TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
  2741. NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
  2742. }
  2743. else
  2744. {
  2745. NdisStatus = NDIS_STATUS_FAILURE;
  2746. }
  2747. }
  2748. else
  2749. { //
  2750. // The call to submit Irp failed synvhronously. Presently, the only cause is an
  2751. NdisStatus = NtStatusToNdisStatus (NtStatus);
  2752. }
  2753. if (bIsPdoValid == TRUE)
  2754. {
  2755. //
  2756. // If this variable is set, it means we have referenced the PDO
  2757. //
  2758. nicDereferenceRemoteNode (pRemoteNode, "nicSubmitIrp_Synch");
  2759. }
  2760. TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_Synch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
  2761. return NdisStatus;
  2762. }
  2763. NTSTATUS
  2764. nicSubmitIrp_SynchComplete(
  2765. IN PDEVICE_OBJECT DeviceObject,
  2766. IN PIRP pIrp,
  2767. IN PVOID Context
  2768. )
  2769. // This is the completion routine for functions nicSubmitIrp_synch.
  2770. // It sets the event (int the context) and exits
  2771. //
  2772. {
  2773. PNDIS_EVENT pNdisSynchEvent = (PNDIS_EVENT) Context;
  2774. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_SynchComplete, PDO %x, pIrp %x, status %x",DeviceObject,pIrp, pIrp->IoStatus.Status ) );
  2775. NdisSetEvent (pNdisSynchEvent);
  2776. return (STATUS_MORE_PROCESSING_REQUIRED);
  2777. }
  2778. NDIS_STATUS
  2779. nicSubmitIrp_LocalHostSynch(
  2780. IN PADAPTERCB pAdapter,
  2781. IN PIRP pIrp,
  2782. IN PIRB pIrb
  2783. )
  2784. // Callers need to make sure that no context is set for the Irp
  2785. // as it will be a synchronous call for them
  2786. //
  2787. // No Checking
  2788. //
  2789. {
  2790. NDIS_EVENT NdisSynchEvent;
  2791. NTSTATUS NtStatus;
  2792. NDIS_STATUS NdisStatus;
  2793. BOOLEAN bSuccessful = FALSE;
  2794. BOOLEAN bIsPdoValid = FALSE;
  2795. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_LocalHostSynch, PDO %x", pAdapter->pNdisDeviceObject ) );
  2796. TRACE( TL_V, TM_Irp, ( "Current Irql , %.2x", KeGetCurrentIrql()) );
  2797. ASSERT (pIrp != NULL);
  2798. ASSERT (pIrb != NULL)
  2799. do
  2800. {
  2801. //
  2802. // Check to see if Pdo is Valid.
  2803. //
  2804. //
  2805. // Add a reference to the PDO block so it cannot be removed
  2806. // This reference is decremented at the end of this function
  2807. //
  2808. // This reference is decrement below
  2809. if (ADAPTER_ACTIVE(pAdapter))
  2810. {
  2811. nicReferenceAdapter(pAdapter, "nicSubmitIrp_LocalHostSynch");
  2812. TRACE( TL_V, TM_Irp, ( "Adapter Active pAdapter %x, ulflags %x", pAdapter , pAdapter->ulFlags) );
  2813. bIsPdoValid = TRUE;
  2814. }
  2815. else
  2816. {
  2817. TRACE( TL_V, TM_Irp, ( "Adapter INActive pAdapter %x, ulflags %x", pAdapter , pAdapter->ulFlags) );
  2818. bIsPdoValid = FALSE;
  2819. }
  2820. if ( bIsPdoValid == FALSE)
  2821. {
  2822. NtStatus = STATUS_NO_SUCH_DEVICE;
  2823. TRACE( TL_A, TM_Irp, ( "==>PDO is NOT Valid, nicSubmitIrp_LocalHostSynch, pAdapter %x, Pdo %x", pAdapter , pAdapter->pNdisDeviceObject) );
  2824. break;
  2825. }
  2826. NdisInitializeEvent (&NdisSynchEvent);
  2827. NtStatus = nicSubmitIrp ( pAdapter->pNdisDeviceObject,
  2828. pIrp,
  2829. pIrb,
  2830. nicSubmitIrp_SynchComplete,
  2831. (PVOID)&NdisSynchEvent);
  2832. } while (FALSE);
  2833. if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
  2834. {
  2835. //
  2836. // Now we need to wait for the event to complete
  2837. // and return a good status if we do not hit the timeout
  2838. //
  2839. bSuccessful = NdisWaitEvent (&NdisSynchEvent,WAIT_INFINITE);
  2840. if (bSuccessful == TRUE)
  2841. {
  2842. //
  2843. // We waited successfully. Now lets see how the Irp fared.
  2844. //
  2845. TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
  2846. NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
  2847. }
  2848. else
  2849. {
  2850. NdisStatus = NDIS_STATUS_FAILURE;
  2851. }
  2852. }
  2853. else
  2854. {
  2855. //
  2856. // IoCallDriver failed synchronously
  2857. //
  2858. NdisStatus = NtStatusToNdisStatus (NtStatus);
  2859. }
  2860. if (bIsPdoValid == TRUE)
  2861. {
  2862. nicDereferenceAdapter(pAdapter, "nicSubmitIrp_LocalHostSynch");
  2863. }
  2864. TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_LocalHostSynch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
  2865. return NdisStatus;
  2866. }
  2867. NDIS_STATUS
  2868. nicSubmitIrp_PDOSynch(
  2869. IN PDEVICE_OBJECT pPdo,
  2870. IN PIRP pIrp,
  2871. IN PIRB pIrb
  2872. )
  2873. // Callers need to make sure that no context is set for the Irp
  2874. // as it will be a synchronous call for them
  2875. //
  2876. // No Checking
  2877. //
  2878. {
  2879. NDIS_EVENT NdisSynchEvent;
  2880. NTSTATUS NtStatus;
  2881. NDIS_STATUS NdisStatus;
  2882. BOOLEAN bSuccessful = FALSE;
  2883. BOOLEAN bIsPdoValid = FALSE;
  2884. STORE_CURRENT_IRQL;
  2885. TRACE( TL_T, TM_Irp, ( "==>nicSubmitIrp_PDOSynch, PDO %x", pPdo) );
  2886. TRACE( TL_V, TM_Irp, ( "Current Irql , %.2x", KeGetCurrentIrql()) );
  2887. ASSERT (pIrp != NULL);
  2888. ASSERT (pIrb != NULL)
  2889. //
  2890. // No Checks to see if Pdo is Valid.
  2891. //
  2892. //
  2893. // Send the Irp to the bus driver
  2894. //
  2895. NdisInitializeEvent (&NdisSynchEvent);
  2896. NtStatus = nicSubmitIrp ( pPdo,
  2897. pIrp,
  2898. pIrb,
  2899. nicSubmitIrp_SynchComplete,
  2900. (PVOID)&NdisSynchEvent);
  2901. if (NT_SUCCESS (NtStatus) ==TRUE) // Could also pend
  2902. {
  2903. //
  2904. // Now we need to wait for the event to complete
  2905. // and return a good status if we do not hit the timeout
  2906. //
  2907. ASSERT (KeGetCurrentIrql()==PASSIVE_LEVEL);
  2908. bSuccessful = NdisWaitEvent (&NdisSynchEvent,WAIT_INFINITE);
  2909. if (bSuccessful == TRUE)
  2910. {
  2911. //
  2912. // We waited successfully. Now lets see how the Irp fared.
  2913. //
  2914. TRACE( TL_V, TM_Irp, (" Irp Completed Status %x", pIrp->IoStatus.Status) );
  2915. NdisStatus = NtStatusToNdisStatus (pIrp->IoStatus.Status);
  2916. }
  2917. else
  2918. {
  2919. NdisStatus = NDIS_STATUS_FAILURE;
  2920. }
  2921. }
  2922. else
  2923. {
  2924. //
  2925. // IoCallDriver failed synchronously
  2926. //
  2927. NdisStatus = NtStatusToNdisStatus (NtStatus);
  2928. }
  2929. TRACE( TL_T, TM_Irp, ( "<==nicSubmitIrp_PDOSynch, bSuccessful %.2x, Status %x", bSuccessful, NdisStatus) );
  2930. MATCH_IRQL;
  2931. return NdisStatus;
  2932. }