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.

538 lines
14 KiB

  1. /*
  2. (C) Copyright 1999
  3. All rights reserved.
  4. Portions of this software are:
  5. (C) Copyright 1995 TriplePoint, Inc. -- http://www.TriplePoint.com
  6. License to use this software is granted under the same terms
  7. outlined in the Microsoft Windows Device Driver Development Kit.
  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 Port Port_c
  12. @module Port.c |
  13. This module implements the interface to the <t PORT_OBJECT>.
  14. @comm
  15. The sample does not use this interface, but it is anticipated that it would
  16. be used to maintain information associated with each physical ISDN line.
  17. Assuming that each card may have multiple ISDN lines plugged into it.
  18. @head3 Contents |
  19. @index class,mfunc,func,msg,mdata,struct,enum | Port_c
  20. @end
  21. */
  22. #define __FILEID__ PORT_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 9x wants this code locked down!
  27. # pragma NDIS_LDATA
  28. #endif
  29. DBG_STATIC ULONG g_PortInstanceCounter = 0;
  30. // Keeps track of how many <t PORT_OBJECT>s are created.
  31. /* @doc EXTERNAL INTERNAL Port Port_c g_PortParameters
  32. @topic 5.5 Port Parameters |
  33. This section describes the registry parameters read into the
  34. <t PORT_OBJECT>.
  35. @globalv PARAM_TABLE | g_PortParameters |
  36. This table defines the registry based parameters to be assigned to data
  37. members of the <t PORT_OBJECT>.
  38. <f Note>:
  39. If you add any registry based data members to <t PORT_OBJECT>
  40. you will need to modify <f PortReadParameters> and add the parameter
  41. definitions to the <f g_PortParameters> table.
  42. @flag <f IsdnSwitchType> (OPTIONAL) |
  43. This DWORD parameter allows you to identify the switch type a particular
  44. Port is connected to. The ISDN installation wizard should set this up
  45. during installation.<nl>
  46. <tab><f Default Value:><tab><tab>0x0001<nl>
  47. <tab><f Valid Range N:><tab><tab>0x0001 <lt>= N <lt>= 0x8000 (bit field)<nl>
  48. @flag <f IsdnNumBChannels> (OPTIONAL) |
  49. This DWORD parameter allows you to control how many <t BCHANNEL_OBJECT>s
  50. will be allocated for the card. This should include all the channels on
  51. all the ports of this adapter.<nl>
  52. <tab><f Default Value:><tab><tab>2<nl>
  53. <tab><f Valid Range N:><tab><tab>2 <lt>= N <lt>= 32<nl>
  54. */
  55. DBG_STATIC PARAM_TABLE g_PortParameters[] =
  56. {
  57. PARAM_ENTRY(PORT_OBJECT,
  58. SwitchType, PARAM_SwitchType,
  59. FALSE, NdisParameterInteger, 0,
  60. 0x0001, 0x0001, 0x8000),
  61. PARAM_ENTRY(PORT_OBJECT,
  62. NumChannels, PARAM_NumBChannels,
  63. FALSE, NdisParameterInteger, 0,
  64. 2, 2, 32),
  65. /* The last entry must be an empty string! */
  66. { { 0 } }
  67. };
  68. DBG_STATIC NDIS_STRING g_PortPrefix
  69. = INIT_STRING_CONST(PARAM_PORT_PREFIX);
  70. /* @doc INTERNAL Port Port_c PortReadParameters
  71. @func
  72. <f PortReadParameters> reads the Port parameters from the registry
  73. and initializes the associated data members. This should only be called
  74. by <f PortCreate>.
  75. <f Note>:
  76. If you add any registry based data members to <t PORT_OBJECT>
  77. you will need to modify <f PortReadParameters> and add the parameter
  78. definitions to the <f g_PortParameters> table.
  79. @rdesc
  80. <f PortReadParameters> returns zero if it is successful.<nl>
  81. Otherwise, a non-zero return value indicates an error condition.
  82. */
  83. DBG_STATIC NDIS_STATUS PortReadParameters(
  84. IN PPORT_OBJECT pPort // @parm
  85. // A pointer to the <t PORT_OBJECT> returned by <f PortCreate>.
  86. )
  87. {
  88. DBG_FUNC("PortReadParameters")
  89. NDIS_STATUS Status;
  90. // Status result returned from an NDIS function call.
  91. PMINIPORT_ADAPTER_OBJECT pAdapter;
  92. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  93. ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
  94. pAdapter = GET_ADAPTER_FROM_PORT(pPort);
  95. DBG_ENTER(pAdapter);
  96. /*
  97. // Parse the registry parameters.
  98. */
  99. Status = ParamParseRegistry(
  100. pAdapter->MiniportAdapterHandle,
  101. pAdapter->WrapperConfigurationContext,
  102. (PUCHAR)pPort,
  103. g_PortParameters
  104. );
  105. DBG_NOTICE(pAdapter,("PortPrefixLen=%d:%d:%ls\n",
  106. g_PortPrefix.Length, g_PortPrefix.MaximumLength, g_PortPrefix.Buffer));
  107. if (Status == NDIS_STATUS_SUCCESS)
  108. {
  109. /*
  110. // Make sure the parameters are valid.
  111. */
  112. if (pPort->TODO)
  113. {
  114. DBG_ERROR(pAdapter,("Invalid parameter\n"
  115. ));
  116. NdisWriteErrorLogEntry(
  117. pAdapter->MiniportAdapterHandle,
  118. NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
  119. 3,
  120. pPort->TODO,
  121. __FILEID__,
  122. __LINE__
  123. );
  124. Status = NDIS_STATUS_FAILURE;
  125. }
  126. else
  127. {
  128. /*
  129. // Finish setting up data members based on registry settings.
  130. */
  131. }
  132. }
  133. DBG_RETURN(pAdapter, Status);
  134. return (Status);
  135. }
  136. /* @doc INTERNAL Port Port_c PortCreateObjects
  137. @func
  138. <f PortCreateObjects> calls the create routines for all the objects
  139. contained in <t PORT_OBJECT>. This should only be called
  140. by <f PortCreate>.
  141. <f Note>:
  142. If you add any new objects to <t PORT_OBJECT> you will need
  143. to modify <f PortCreateObjects> and <f PortDestroyObjects> so they
  144. will get created and destroyed properly.
  145. @rdesc
  146. <f PortCreateObjects> returns zero if it is successful.<nl>
  147. Otherwise, a non-zero return value indicates an error condition.
  148. */
  149. DBG_STATIC NDIS_STATUS PortCreateObjects(
  150. IN PPORT_OBJECT pPort // @parm
  151. // A pointer to the <t PORT_OBJECT> returned by <f PortCreate>.
  152. )
  153. {
  154. DBG_FUNC("PortCreateObjects")
  155. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  156. // Holds the result code returned by this function.
  157. PMINIPORT_ADAPTER_OBJECT pAdapter;
  158. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  159. ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
  160. pAdapter = GET_ADAPTER_FROM_PORT(pPort);
  161. DBG_ENTER(pAdapter);
  162. // TODO - Add code here
  163. DBG_RETURN(pAdapter, Result);
  164. return (Result);
  165. }
  166. /* @doc INTERNAL Port Port_c PortCreate
  167. @func
  168. <f PortCreate> allocates memory for a <t PORT_OBJECT> and then
  169. initializes the data members to their starting state.
  170. If successful, <p ppPort> will be set to point to the newly created
  171. <t PORT_OBJECT>. Otherwise, <p ppPort> will be set to NULL.
  172. @comm
  173. This function should be called only once when the Miniport is loaded.
  174. Before the Miniport is unloaded, <f PortDestroy> must be called to
  175. release the <t PORT_OBJECT> created by this function.
  176. @rdesc
  177. <f PortCreate> returns zero if it is successful.<nl>
  178. Otherwise, a non-zero return value indicates an error condition.
  179. */
  180. NDIS_STATUS PortCreate(
  181. OUT PPORT_OBJECT * ppPort, // @parm
  182. // Points to a caller-defined memory location to which this function
  183. // writes the virtual address of the allocated <t PORT_OBJECT>.
  184. IN PCARD_OBJECT pCard // @parm
  185. // A pointer to the <t CARD_OBJECT> returned by <f CardCreate>.
  186. )
  187. {
  188. DBG_FUNC("PortCreate")
  189. PPORT_OBJECT pPort;
  190. // Pointer to our newly allocated object.
  191. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  192. // Holds the result code returned by this function.
  193. PMINIPORT_ADAPTER_OBJECT pAdapter;
  194. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  195. ASSERT(pCard && pCard->ObjectType == CARD_OBJECT_TYPE);
  196. pAdapter = GET_ADAPTER_FROM_CARD(pCard);
  197. DBG_ENTER(pAdapter);
  198. /*
  199. // Make sure the caller's object pointer is NULL to begin with.
  200. // It will be set later only if everything is successful.
  201. */
  202. *ppPort = NULL;
  203. /*
  204. // Allocate memory for the object.
  205. */
  206. Result = ALLOCATE_OBJECT(pPort, pAdapter->MiniportAdapterHandle);
  207. if (Result == NDIS_STATUS_SUCCESS)
  208. {
  209. /*
  210. // Zero everything to begin with.
  211. // Then set the object type and assign a unique ID .
  212. */
  213. pPort->ObjectType = PORT_OBJECT_TYPE;
  214. pPort->ObjectID = ++g_PortInstanceCounter;
  215. /*
  216. // Initialize the member variables to their default settings.
  217. */
  218. pPort->pCard = pCard;
  219. // TODO - Add code here
  220. /*
  221. // Parse the registry parameters.
  222. */
  223. Result = PortReadParameters(pPort);
  224. /*
  225. // If all goes well, we are ready to create the sub-components.
  226. */
  227. if (Result == NDIS_STATUS_SUCCESS)
  228. {
  229. Result = PortCreateObjects(pPort);
  230. }
  231. if (Result == NDIS_STATUS_SUCCESS)
  232. {
  233. /*
  234. // All is well, so return the object pointer to the caller.
  235. */
  236. *ppPort = pPort;
  237. }
  238. else
  239. {
  240. /*
  241. // Something went wrong, so let's make sure everything is
  242. // cleaned up.
  243. */
  244. PortDestroy(pPort);
  245. }
  246. }
  247. DBG_RETURN(pAdapter, Result);
  248. return (Result);
  249. }
  250. /* @doc INTERNAL Port Port_c PortDestroyObjects
  251. @func
  252. <f PortDestroyObjects> calls the destroy routines for all the objects
  253. contained in <t PORT_OBJECT>. This should only be called by
  254. <f PortDestroy>.
  255. <f Note>:
  256. If you add any new objects to <t PPORT_OBJECT> you will need to
  257. modify <f PortCreateObjects> and <f PortDestroyObjects> so they
  258. will get created and destroyed properly.
  259. */
  260. DBG_STATIC void PortDestroyObjects(
  261. IN PPORT_OBJECT pPort // @parm
  262. // A pointer to the <t PORT_OBJECT> instance.
  263. )
  264. {
  265. DBG_FUNC("PortDestroyObjects")
  266. PMINIPORT_ADAPTER_OBJECT pAdapter;
  267. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  268. ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
  269. pAdapter = GET_ADAPTER_FROM_PORT(pPort);
  270. DBG_ENTER(pAdapter);
  271. // TODO - Add code here
  272. DBG_LEAVE(pAdapter);
  273. }
  274. /* @doc INTERNAL Port Port_c PortDestroy
  275. @func
  276. <f PortDestroy> frees the memory for this <t PORT_OBJECT>.
  277. All memory allocated by <f PortCreate> will be released back to the
  278. OS.
  279. */
  280. void PortDestroy(
  281. IN PPORT_OBJECT pPort // @parm
  282. // A pointer to the <t PORT_OBJECT> returned by <f PortCreate>.
  283. )
  284. {
  285. DBG_FUNC("PortDestroy")
  286. PMINIPORT_ADAPTER_OBJECT pAdapter;
  287. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  288. if (pPort)
  289. {
  290. ASSERT(pPort->ObjectType == PORT_OBJECT_TYPE);
  291. pAdapter = GET_ADAPTER_FROM_PORT(pPort);
  292. DBG_ENTER(pAdapter);
  293. // TODO - Add code here
  294. /*
  295. // Release all objects allocated within this object.
  296. */
  297. PortDestroyObjects(pPort);
  298. /*
  299. // Make sure we fail the ASSERT if we see this object again.
  300. */
  301. pPort->ObjectType = 0;
  302. FREE_OBJECT(pPort);
  303. DBG_LEAVE(pAdapter);
  304. }
  305. }
  306. /* @doc INTERNAL Port Port_c PortOpen
  307. @func
  308. <f PortOpen> makes the Port connection ready to transmit and
  309. receive data.
  310. @rdesc
  311. <f PortOpen> returns zero if it is successful.<nl>
  312. Otherwise, a non-zero return value indicates an error condition.
  313. */
  314. NDIS_STATUS PortOpen(
  315. IN PPORT_OBJECT pPort, // @parm
  316. // A pointer to the <t PORT_OBJECT> associated with this request.
  317. IN PBCHANNEL_OBJECT pBChannel // @parm
  318. // A pointer to the <t BCHANNEL_OBJECT> to be associated with this
  319. // Port.
  320. )
  321. {
  322. DBG_FUNC("PortOpen")
  323. NDIS_STATUS Result = NDIS_STATUS_SUCCESS;
  324. // Holds the result code returned by this function.
  325. PMINIPORT_ADAPTER_OBJECT pAdapter;
  326. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  327. ASSERT(pBChannel);
  328. ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
  329. pAdapter = GET_ADAPTER_FROM_PORT(pPort);
  330. DBG_ENTER(pAdapter);
  331. if (!pPort->IsOpen)
  332. {
  333. DBG_NOTICE(pAdapter,("Opening Port #%d\n",
  334. pPort->ObjectID));
  335. // TODO - Add code here
  336. pPort->IsOpen = TRUE;
  337. }
  338. else
  339. {
  340. DBG_ERROR(pAdapter,("Port #%d already opened\n",
  341. pPort->ObjectID));
  342. }
  343. DBG_RETURN(pAdapter, Result);
  344. return (Result);
  345. }
  346. /* @doc INTERNAL Port Port_c PortClose
  347. @func
  348. <f PortClose> closes the given B-channel.
  349. */
  350. void PortClose(
  351. IN PPORT_OBJECT pPort // @parm
  352. // A pointer to the <t PORT_OBJECT> associated with this request.
  353. )
  354. {
  355. DBG_FUNC("PortClose")
  356. PMINIPORT_ADAPTER_OBJECT pAdapter;
  357. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  358. ASSERT(pPort && pPort->ObjectType == PORT_OBJECT_TYPE);
  359. pAdapter = GET_ADAPTER_FROM_PORT(pPort);
  360. DBG_ENTER(pAdapter);
  361. if (pPort->IsOpen)
  362. {
  363. DBG_NOTICE(pAdapter,("Closing Port #%d\n",
  364. pPort->ObjectID));
  365. // TODO - Add code here
  366. pPort->IsOpen = FALSE;
  367. }
  368. else
  369. {
  370. DBG_ERROR(pAdapter,("Port #%d already closed\n",
  371. pPort->ObjectID));
  372. }
  373. DBG_LEAVE(pAdapter);
  374. }