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.

762 lines
23 KiB

  1. /*
  2. (C) Copyright 1998
  3. All rights reserved.
  4. Portions of this software are:
  5. (C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
  6. License to use this software is granted under the terms outlined in
  7. the TriplePoint Software Services Agreement.
  8. (C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
  9. License to use this software is granted under the terms outlined in
  10. the Microsoft Windows Device Driver Development Kit.
  11. @doc INTERNAL BChannel BChannel_c
  12. @module BChannel.c |
  13. This module implements the interface to the <t BCHANNEL_OBJECT>.
  14. Supports the high-level channel control functions used by the NDIS WAN
  15. Minport driver. This module isolates most the vendor specific channel
  16. access interfaces. It will require some changes to accomodate your
  17. hardware device's channel access methods.
  18. @head3 Contents |
  19. @index class,mfunc,func,msg,mdata,struct,enum | BChannel_c
  20. @end
  21. */
  22. #define __FILEID__ BCHANNEL_OBJECT_TYPE
  23. // Unique file ID for error logging
  24. #include "Miniport.h" // Defines all the miniport objects
  25. #if defined(NDIS_LCODE)
  26. # pragma NDIS_LCODE // Windows 95 wants this code locked down!
  27. # pragma NDIS_LDATA
  28. #endif
  29. DBG_STATIC ULONG g_BChannelInstanceCounter // @globalv
  30. // Keeps track of how many <t BCHANNEL_OBJECT>s are created.
  31. = 0;
  32. /* @doc EXTERNAL INTERNAL BChannel BChannel_c g_BChannelParameters
  33. @topic 5.3 BChannel Parameters |
  34. This section describes the registry parameters read into the
  35. <t BCHANNEL_OBJECT>.
  36. @globalv PARAM_TABLE | g_BChannelParameters |
  37. This table defines the registry based parameters to be assigned to data
  38. members of the <t BCHANNEL_OBJECT>.
  39. <f Note>:
  40. If you add any registry based data members to <t BCHANNEL_OBJECT>
  41. you will need to modify <f BChannelReadParameters> and add the parameter
  42. definitions to the <f g_BChannelParameters> table.
  43. */
  44. DBG_STATIC PARAM_TABLE g_BChannelParameters[] =
  45. {
  46. PARAM_ENTRY(BCHANNEL_OBJECT,
  47. TODO, PARAM_TODO,
  48. FALSE, NdisParameterInteger, 0,
  49. 0, 0, 0),
  50. /* The last entry must be an empty string! */
  51. { { 0 } }
  52. };
  53. /* @doc INTERNAL BChannel BChannel_c BChannelReadParameters
  54. @func
  55. <f BChannelReadParameters> reads the BChannel parameters from the registry
  56. and initializes the associated data members. This should only be called
  57. by <f BChannelCreate>.
  58. @rdesc
  59. <f BChannelReadParameters> returns zero if it is successful.<nl>
  60. Otherwise, a non-zero return value indicates an error condition.
  61. <f Note>:
  62. If you add any registry based data members to <t BCHANNEL_OBJECT>
  63. you will need to modify <f BChannelReadParameters> and add the parameter
  64. definitions to the <f g_BChannelParameters> table.
  65. */
  66. DBG_STATIC NDIS_STATUS BChannelReadParameters(
  67. IN PBCHANNEL_OBJECT pBChannel // @parm
  68. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  69. )
  70. {
  71. DBG_FUNC("BChannelReadParameters")
  72. NDIS_STATUS Status;
  73. // Status result returned from an NDIS function call.
  74. PMINIPORT_ADAPTER_OBJECT pAdapter;
  75. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  76. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  77. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  78. DBG_ENTER(pAdapter);
  79. /*
  80. // Parse the registry parameters.
  81. */
  82. Status = ParamParseRegistry(
  83. pAdapter->MiniportAdapterHandle,
  84. pAdapter->WrapperConfigurationContext,
  85. (PUCHAR)pBChannel,
  86. g_BChannelParameters
  87. );
  88. if (Status == NDIS_STATUS_SUCCESS)
  89. {
  90. /*
  91. // Make sure the parameters are valid.
  92. */
  93. if (pBChannel->TODO)
  94. {
  95. DBG_ERROR(pAdapter,("Invalid parameter\n"
  96. ));
  97. NdisWriteErrorLogEntry(
  98. pAdapter->MiniportAdapterHandle,
  99. NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
  100. 3,
  101. pBChannel->TODO,
  102. __FILEID__,
  103. __LINE__
  104. );
  105. Status = NDIS_STATUS_FAILURE;
  106. }
  107. else
  108. {
  109. /*
  110. // Finish setting up data members based on registry settings.
  111. */
  112. }
  113. }
  114. DBG_RETURN(pAdapter, Status);
  115. return (Status);
  116. }
  117. /* @doc INTERNAL BChannel BChannel_c BChannelCreateObjects
  118. @func
  119. <f BChannelCreateObjects> calls the create routines for all the objects
  120. contained in <t BCHANNEL_OBJECT>. This should only be called
  121. by <f BChannelCreate>.
  122. <f Note>:
  123. If you add any new objects to <t BCHANNEL_OBJECT> you will need
  124. to modify <f BChannelCreateObjects> and <f BChannelDestroyObjects> so they
  125. will get created and destroyed properly.
  126. @rdesc
  127. <f BChannelCreateObjects> returns zero if it is successful.<nl>
  128. Otherwise, a non-zero return value indicates an error condition.
  129. */
  130. DBG_STATIC NDIS_STATUS BChannelCreateObjects(
  131. IN PBCHANNEL_OBJECT pBChannel // @parm
  132. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  133. )
  134. {
  135. DBG_FUNC("BChannelCreateObjects")
  136. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  137. // Holds the result code returned by this function.
  138. PMINIPORT_ADAPTER_OBJECT pAdapter;
  139. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  140. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  141. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  142. DBG_ENTER(pAdapter);
  143. // TODO - Add code here
  144. DBG_RETURN(pAdapter, Result);
  145. return (Result);
  146. }
  147. /* @doc INTERNAL BChannel BChannel_c BChannelCreate
  148. @func
  149. <f BChannelCreate> allocates memory for a <t BCHANNEL_OBJECT> and then
  150. initializes the data members to their starting state.
  151. If successful, <p ppBChannel> will be set to point to the newly created
  152. <t BCHANNEL_OBJECT>. Otherwise, <p ppBChannel> will be set to NULL.
  153. @comm
  154. This function should be called only once when the Miniport is loaded.
  155. Before the Miniport is unloaded, <f BChannelDestroy> must be called to
  156. release the <t BCHANNEL_OBJECT> created by this function.
  157. @rdesc
  158. <f BChannelCreate> returns zero if it is successful.<nl>
  159. Otherwise, a non-zero return value indicates an error condition.
  160. */
  161. NDIS_STATUS BChannelCreate(
  162. OUT PBCHANNEL_OBJECT * ppBChannel, // @parm
  163. // Points to a caller-defined memory location to which this function
  164. // writes the virtual address of the allocated <t BCHANNEL_OBJECT>.
  165. IN ULONG BChannelIndex, // @parm
  166. // Index into the pBChannelArray.
  167. IN PUCHAR pTapiLineAddress, // @parm
  168. // A pointer to the RAS/TAPI line address assigned to each RAS line.
  169. IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
  170. // A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
  171. )
  172. {
  173. DBG_FUNC("BChannelCreate")
  174. PBCHANNEL_OBJECT pBChannel;
  175. // Pointer to our newly allocated object.
  176. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  177. // Holds the result code returned by this function.
  178. ASSERT(pAdapter && pAdapter->ObjectType == MINIPORT_ADAPTER_OBJECT_TYPE);
  179. DBG_ENTER(pAdapter);
  180. /*
  181. // Make sure the caller's object pointer is NULL to begin with.
  182. // It will be set later only if everything is successful.
  183. */
  184. *ppBChannel = NULL;
  185. /*
  186. // Allocate memory for the object.
  187. */
  188. Result = ALLOCATE_OBJECT(pBChannel, pAdapter->MiniportAdapterHandle);
  189. if (Result == NDIS_STATUS_SUCCESS)
  190. {
  191. /*
  192. // Zero everything to begin with.
  193. // Then set the object type and assign a unique ID .
  194. */
  195. pBChannel->ObjectType = BCHANNEL_OBJECT_TYPE;
  196. pBChannel->ObjectID = ++g_BChannelInstanceCounter;
  197. /*
  198. // Initialize the member variables to their default settings.
  199. */
  200. pBChannel->pAdapter = pAdapter;
  201. pBChannel->BChannelIndex = BChannelIndex;
  202. strcpy(pBChannel->pTapiLineAddress, pTapiLineAddress);
  203. // TODO - Add code here
  204. /*
  205. // Parse the registry parameters.
  206. */
  207. Result = BChannelReadParameters(pBChannel);
  208. /*
  209. // If all goes well, we are ready to create the sub-components.
  210. */
  211. if (Result == NDIS_STATUS_SUCCESS)
  212. {
  213. Result = BChannelCreateObjects(pBChannel);
  214. }
  215. if (Result == NDIS_STATUS_SUCCESS)
  216. {
  217. /*
  218. // All is well, so return the object pointer to the caller.
  219. */
  220. *ppBChannel = pBChannel;
  221. }
  222. else
  223. {
  224. /*
  225. // Something went wrong, so let's make sure everything is
  226. // cleaned up.
  227. */
  228. BChannelDestroy(pBChannel);
  229. }
  230. }
  231. DBG_RETURN(pAdapter, Result);
  232. return (Result);
  233. }
  234. /* @doc INTERNAL BChannel BChannel_c BChannelDestroyObjects
  235. @func
  236. <f BChannelDestroyObjects> calls the destroy routines for all the objects
  237. contained in <t BCHANNEL_OBJECT>. This should only be called by
  238. <f BChannelDestroy>.
  239. <f Note>:
  240. If you add any new objects to <t PBCHANNEL_OBJECT> you will need to
  241. modify <f BChannelCreateObjects> and <f BChannelDestroyObjects> so they
  242. will get created and destroyed properly.
  243. */
  244. DBG_STATIC void BChannelDestroyObjects(
  245. IN PBCHANNEL_OBJECT pBChannel // @parm
  246. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  247. )
  248. {
  249. DBG_FUNC("BChannelDestroyObjects")
  250. PMINIPORT_ADAPTER_OBJECT pAdapter;
  251. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  252. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  253. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  254. DBG_ENTER(pAdapter);
  255. // TODO - Add code here
  256. DBG_LEAVE(pAdapter);
  257. }
  258. /* @doc INTERNAL BChannel BChannel_c BChannelDestroy
  259. @func
  260. <f BChannelDestroy> frees the memory for this <t BCHANNEL_OBJECT>.
  261. All memory allocated by <f BChannelCreate> will be released back to the
  262. OS.
  263. */
  264. void BChannelDestroy(
  265. IN PBCHANNEL_OBJECT pBChannel // @parm
  266. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  267. )
  268. {
  269. DBG_FUNC("BChannelDestroy")
  270. PMINIPORT_ADAPTER_OBJECT pAdapter;
  271. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  272. if (pBChannel)
  273. {
  274. ASSERT(pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  275. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  276. DBG_ENTER(pAdapter);
  277. // TODO - Add code here
  278. /*
  279. // Release all objects allocated within this object.
  280. */
  281. BChannelDestroyObjects(pBChannel);
  282. /*
  283. // Make sure we fail the ASSERT if we see this object again.
  284. */
  285. pBChannel->ObjectType = 0;
  286. FREE_OBJECT(pBChannel);
  287. DBG_LEAVE(pAdapter);
  288. }
  289. }
  290. /* @doc INTERNAL BChannel BChannel_c BChannelInitialize
  291. @func
  292. <f BChannelInitialize> resets all the internal data members contained
  293. in <t BCHANNEL_OBJECT> back to their initial state.
  294. <f Note>:
  295. If you add any new members to <t BCHANNEL_OBJECT> you will need to
  296. modify <f BChannelInitialize> to initialize your new data mamebers.
  297. */
  298. void BChannelInitialize(
  299. IN PBCHANNEL_OBJECT pBChannel // @parm
  300. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  301. )
  302. {
  303. DBG_FUNC("BChannelInitialize")
  304. PMINIPORT_ADAPTER_OBJECT pAdapter;
  305. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  306. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  307. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  308. DBG_ENTER(pAdapter);
  309. /*
  310. // Initially, the BChannel is not allocated to anyone and these fields
  311. // must be reset.
  312. */
  313. ASSERT(pBChannel->NdisLinkContext == NULL);
  314. ASSERT(pBChannel->htLine == (HTAPI_LINE)0);
  315. ASSERT(pBChannel->htCall == (HTAPI_CALL)0);
  316. /*
  317. // Setup the static features of the link.
  318. */
  319. pBChannel->LinkSpeed = _64KBPS;
  320. pBChannel->BearerModesCaps = LINEBEARERMODE_DATA
  321. | LINEBEARERMODE_VOICE
  322. ;
  323. pBChannel->MediaModesCaps = LINEMEDIAMODE_DIGITALDATA
  324. | LINEMEDIAMODE_UNKNOWN
  325. // | LINEMEDIAMODE_DATAMODEM
  326. ;
  327. /*
  328. // Initialize the TAPI event capabilities supported by the link.
  329. */
  330. pBChannel->DevStatesCaps = LINEDEVSTATE_RINGING
  331. | LINEDEVSTATE_CONNECTED
  332. | LINEDEVSTATE_DISCONNECTED
  333. | LINEDEVSTATE_INSERVICE
  334. | LINEDEVSTATE_OUTOFSERVICE
  335. | LINEDEVSTATE_OPEN
  336. | LINEDEVSTATE_CLOSE
  337. | LINEDEVSTATE_REINIT
  338. ;
  339. pBChannel->AddressStatesCaps = 0;
  340. pBChannel->CallStatesCaps = LINECALLSTATE_IDLE
  341. | LINECALLSTATE_DIALTONE
  342. | LINECALLSTATE_DIALING
  343. | LINECALLSTATE_PROCEEDING
  344. | LINECALLSTATE_RINGBACK
  345. | LINECALLSTATE_BUSY
  346. | LINECALLSTATE_OFFERING
  347. | LINECALLSTATE_ACCEPTED
  348. | LINECALLSTATE_CONNECTED
  349. | LINECALLSTATE_DISCONNECTED
  350. ;
  351. /*
  352. // We use this timer to keep track of incoming and outgoing call
  353. // status, and to provide timeouts for certain call states.
  354. */
  355. NdisMInitializeTimer(
  356. &pBChannel->CallTimer,
  357. pAdapter->MiniportAdapterHandle,
  358. TspiCallTimerHandler,
  359. pBChannel
  360. );
  361. /*
  362. // Set the TransmitBusyList and ReceivePendingList to empty.
  363. */
  364. InitializeListHead(&pBChannel->TransmitBusyList);
  365. InitializeListHead(&pBChannel->ReceivePendingList);
  366. // TODO - Add code here
  367. DBG_LEAVE(pAdapter);
  368. }
  369. /* @doc INTERNAL BChannel BChannel_c BChannelOpen
  370. @func
  371. <f BChannelOpen> makes the BChannel connection ready to transmit and
  372. receive data.
  373. @rdesc
  374. <f BChannelOpen> returns zero if it is successful.<nl>
  375. Otherwise, a non-zero return value indicates an error condition.
  376. */
  377. NDIS_STATUS BChannelOpen(
  378. IN PBCHANNEL_OBJECT pBChannel, // @parm
  379. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  380. IN HTAPI_LINE htLine
  381. )
  382. {
  383. DBG_FUNC("BChannelOpen")
  384. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  385. // Holds the result code returned by this function.
  386. PMINIPORT_ADAPTER_OBJECT pAdapter;
  387. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  388. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  389. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  390. DBG_ENTER(pAdapter);
  391. if (!pBChannel->IsOpen)
  392. {
  393. DBG_NOTICE(pAdapter,("Opening BChannel #%d\n",
  394. pBChannel->ObjectID));
  395. /*
  396. // The htLine field is used to associate this BChannel with the
  397. // TAPI Connection Wrapper. Reset all the state information for
  398. // this BChannel.
  399. */
  400. pBChannel->htLine = htLine;
  401. pBChannel->CallClosing = FALSE;
  402. // Don't clear the line state flags that are set by card.c
  403. pBChannel->DevState &= (LINEDEVSTATE_CONNECTED |
  404. LINEDEVSTATE_INSERVICE);
  405. pBChannel->DevStatesMask = 0; // Default to indicate no line events
  406. pBChannel->AddressState = 0;
  407. pBChannel->AddressStatesMask = 0; // Default to indicate no address events
  408. pBChannel->CallState = 0;
  409. pBChannel->CallStateMode = 0;
  410. pBChannel->CallStatesMask = pBChannel->CallStatesCaps;
  411. pBChannel->MediaMode = 0;
  412. pBChannel->MediaModesMask = 0;
  413. pBChannel->TotalRxPackets = 0;
  414. pBChannel->AppSpecificCallInfo = 0;
  415. /*
  416. // Initialize the default BChannel information structure. It may be
  417. // changed later by MiniportSetInformation.
  418. */
  419. pBChannel->WanLinkInfo.MiniportLinkContext = pBChannel;
  420. pBChannel->WanLinkInfo.MaxSendFrameSize = pAdapter->WanInfo.MaxFrameSize;
  421. pBChannel->WanLinkInfo.MaxRecvFrameSize = pAdapter->WanInfo.MaxFrameSize;
  422. pBChannel->WanLinkInfo.SendFramingBits = pAdapter->WanInfo.FramingBits;
  423. pBChannel->WanLinkInfo.RecvFramingBits = pAdapter->WanInfo.FramingBits;
  424. pBChannel->WanLinkInfo.SendACCM = pAdapter->WanInfo.DesiredACCM;
  425. pBChannel->WanLinkInfo.RecvACCM = pAdapter->WanInfo.DesiredACCM;
  426. #if defined(SAMPLE_DRIVER)
  427. // Sample just tells tapi that the line is connected and in service.
  428. TspiLineDevStateHandler(pAdapter, pBChannel, LINEDEVSTATE_CONNECTED);
  429. TspiLineDevStateHandler(pAdapter, pBChannel, LINEDEVSTATE_INSERVICE);
  430. #else // SAMPLE_DRIVER
  431. // TODO - Add code here
  432. TspiLineDevStateHandler(pAdapter, pBChannel, LINEDEVSTATE_CONNECTED);
  433. #endif // SAMPLE_DRIVER
  434. pBChannel->IsOpen = TRUE;
  435. }
  436. else
  437. {
  438. DBG_ERROR(pAdapter,("BChannel #%d already opened\n",
  439. pBChannel->ObjectID));
  440. }
  441. DBG_RETURN(pAdapter, Result);
  442. return (Result);
  443. }
  444. /* @doc INTERNAL BChannel BChannel_c BChannelClose
  445. @func
  446. <f BChannelClose> closes the given B-channel.
  447. */
  448. void BChannelClose(
  449. IN PBCHANNEL_OBJECT pBChannel // @parm
  450. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  451. )
  452. {
  453. DBG_FUNC("BChannelClose")
  454. PMINIPORT_ADAPTER_OBJECT pAdapter;
  455. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  456. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  457. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  458. DBG_ENTER(pAdapter);
  459. if (pBChannel->IsOpen)
  460. {
  461. DBG_NOTICE(pAdapter,("Closing BChannel #%d\n",
  462. pBChannel->ObjectID));
  463. /*
  464. // Make sure call is cleared and B channel is disabled.
  465. */
  466. DChannelCloseCall(pAdapter->pDChannel, pBChannel);
  467. // TODO - Add code here
  468. // Don't clear the line state flags that are set by card.c
  469. pBChannel->DevState &= (LINEDEVSTATE_CONNECTED |
  470. LINEDEVSTATE_INSERVICE);
  471. pBChannel->CallState = 0;
  472. pBChannel->htLine = (HTAPI_LINE)0;
  473. pBChannel->htCall = (HTAPI_CALL)0;
  474. pBChannel->NdisLinkContext = NULL;
  475. pBChannel->IsOpen = FALSE;
  476. }
  477. else
  478. {
  479. DBG_ERROR(pAdapter,("BChannel #%d already closed\n",
  480. pBChannel->ObjectID));
  481. }
  482. DBG_LEAVE(pAdapter);
  483. }
  484. /* @doc INTERNAL BChannel BChannel_c BChannelAddToReceiveQueue
  485. @func
  486. <f BChannelAddToReceiveQueue> adds a buffer to the queue of available
  487. receive buffers associated with this B-channel.
  488. @rdesc
  489. <f BChannelAddToReceiveQueue> returns zero if it is successful.<nl>
  490. Otherwise, a non-zero return value indicates an error condition.
  491. */
  492. NDIS_STATUS BChannelAddToReceiveQueue(
  493. IN PBCHANNEL_OBJECT pBChannel, // @parm
  494. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  495. IN PVOID pReceiveContext, // @parm
  496. // A context value to be passed back to <f TransmitComplete>.
  497. IN PUCHAR BufferPointer, // @parm
  498. // A pointer to the buffer to be transmitted.
  499. IN ULONG BufferSize // @parm
  500. // The size in bytes of the buffer to be transmitted.
  501. )
  502. {
  503. DBG_FUNC("BChannelAddToReceiveQueue")
  504. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  505. // Holds the result code returned by this function.
  506. PMINIPORT_ADAPTER_OBJECT pAdapter;
  507. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  508. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  509. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  510. DBG_ENTER(pAdapter);
  511. ASSERT(pBChannel->IsOpen);
  512. // TODO - Add code here
  513. DBG_RETURN(pAdapter, Result);
  514. return (Result);
  515. }
  516. /* @doc INTERNAL BChannel BChannel_c BChannelAddToTransmitQueue
  517. @func
  518. <f BChannelAddToTransmitQueue> adds a buffer to the queue of buffers
  519. to be transmitted on this B-channel.
  520. @rdesc
  521. <f BChannelAddToTransmitQueue> returns zero if it is successful.<nl>
  522. Otherwise, a non-zero return value indicates an error condition.
  523. */
  524. NDIS_STATUS BChannelAddToTransmitQueue(
  525. IN PBCHANNEL_OBJECT pBChannel, // @parm
  526. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  527. IN PVOID pTransmitContext, // @parm
  528. // A context value to be passed back to <f TransmitComplete>.
  529. IN PUCHAR BufferPointer, // @parm
  530. // A pointer to the buffer to be transmitted.
  531. IN ULONG BufferSize // @parm
  532. // The size in bytes of the buffer to be transmitted.
  533. )
  534. {
  535. DBG_FUNC("BChannelAddToTransmitQueue")
  536. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  537. // Holds the result code returned by this function.
  538. PMINIPORT_ADAPTER_OBJECT pAdapter;
  539. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  540. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  541. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  542. DBG_ENTER(pAdapter);
  543. ASSERT(pBChannel->IsOpen);
  544. // TODO - Add code here
  545. DBG_RETURN(pAdapter, Result);
  546. return (Result);
  547. }