Windows NT 4.0 source code leak
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.

651 lines
14 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ltreq.c
  5. Abstract:
  6. This module contains
  7. Author:
  8. Nikhil Kamkolkar (nikhilk@microsoft.com)
  9. Stephen Hou (stephh@microsoft.com)
  10. Revision History:
  11. 19 Jun 1992 Initial Version (dch@pacvax.pacersoft.com)
  12. Notes: Tab stop: 4
  13. --*/
  14. #define LTREQ_H_LOCALS
  15. #include "ltmain.h"
  16. #include "ltreq.h"
  17. // Define file id for errorlogging
  18. #define FILENUM LTREQ
  19. NDIS_STATUS
  20. LtRequest(
  21. IN NDIS_HANDLE MacBindingHandle,
  22. IN PNDIS_REQUEST NdisRequest
  23. )
  24. /*++
  25. Routine Description:
  26. called by NDIS to query or set card/driver information on a binding
  27. Arguments:
  28. MacBindingHandle : the binding submitting the request
  29. NdisRequest : the request we've been asked to satisfy
  30. Return Values:
  31. NDIS_STATUS_SUCCESS : if completed successfully
  32. NDIS_STATUS_RESET_IN_PROGRESS : if the adapter's in the middle of a reset
  33. NDIS_STATUS_ADAPTER_REMOVED : if the adapter's been closed
  34. NDIS_STATUS_CLOSING : if the binding is closing down
  35. NDIS_STATUS_NOT_SUPPORTED : if we do not support the requested action
  36. --*/
  37. {
  38. NDIS_STATUS Status;
  39. PLT_ADAPTER Adapter = ((PLT_OPEN)MacBindingHandle)->LtAdapter;
  40. PLT_OPEN Open = (PLT_OPEN)MacBindingHandle;
  41. if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS)
  42. {
  43. return(NDIS_STATUS_RESET_IN_PROGRESS);
  44. }
  45. switch (NdisRequest->RequestType)
  46. {
  47. case NdisRequestSetInformation:
  48. case NdisRequestQueryInformation:
  49. // increment count since we'll be in the binding with the request
  50. LtReferenceBinding(Open,&Status);
  51. if (Status == NDIS_STATUS_SUCCESS)
  52. {
  53. if (NdisRequest->RequestType == NdisRequestSetInformation)
  54. {
  55. Status = LtReqSetInformation(
  56. Adapter,
  57. Open,
  58. NdisRequest->DATA.SET_INFORMATION.Oid,
  59. NdisRequest->DATA.SET_INFORMATION.InformationBuffer,
  60. NdisRequest->DATA.SET_INFORMATION.InformationBufferLength,
  61. &(NdisRequest->DATA.SET_INFORMATION.BytesRead),
  62. &(NdisRequest->DATA.SET_INFORMATION.BytesNeeded));
  63. }
  64. else
  65. {
  66. Status = LtReqQueryInformation(
  67. Adapter,
  68. Open,
  69. NdisRequest->DATA.QUERY_INFORMATION.Oid,
  70. NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
  71. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
  72. &(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten),
  73. &(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded),
  74. FALSE);
  75. }
  76. // completed the request for the binding; outa there
  77. LtDeReferenceBinding(Open);
  78. }
  79. break;
  80. default:
  81. // Unkown request
  82. Status = NDIS_STATUS_NOT_SUPPORTED;
  83. break;
  84. }
  85. return(Status);
  86. }
  87. NDIS_STATUS
  88. LtReqQueryGlobalStatistics(
  89. IN NDIS_HANDLE MacAdapterContext,
  90. IN PNDIS_REQUEST NdisRequest
  91. )
  92. /*++
  93. Routine Description:
  94. called by NDIS to query or set global card/driver information
  95. Arguments:
  96. MacAdapterContext : the adapter the request is submitted on
  97. NdisRequest : the request we've been asked to satisfy
  98. Return Values:
  99. NDIS_STATUS_SUCCESS : if completed successfully
  100. NDIS_STATUS_RESET_IN_PROGRESS : if the adapter's in the middle of a reset
  101. NDIS_STATUS_ADAPTER_REMOVED : if the adapter's been closed
  102. NDIS_STATUS_CLOSING : if the binding is closing down
  103. NDIS_STATUS_NOT_SUPPORTED : if we do not support the requested action
  104. --*/
  105. {
  106. NDIS_STATUS Status;
  107. PLT_ADAPTER Adapter = MacAdapterContext;
  108. if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS)
  109. {
  110. return(NDIS_STATUS_RESET_IN_PROGRESS);
  111. }
  112. switch (NdisRequest->RequestType)
  113. {
  114. case NdisRequestQueryStatistics:
  115. LtReferenceAdapter(Adapter,&Status);
  116. if (Status != NDIS_STATUS_SUCCESS)
  117. break;
  118. Status = LtReqQueryInformation(
  119. Adapter,
  120. NULL,
  121. NdisRequest->DATA.QUERY_INFORMATION.Oid,
  122. NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
  123. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
  124. &(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten),
  125. &(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded),
  126. TRUE);
  127. LtDeReferenceAdapter(Adapter);
  128. break;
  129. default:
  130. Status = NDIS_STATUS_NOT_SUPPORTED;
  131. break;
  132. }
  133. return(Status);
  134. }
  135. STATIC
  136. NDIS_STATUS
  137. LtReqSetInformation(
  138. IN PLT_ADAPTER Adapter,
  139. IN PLT_OPEN Open,
  140. IN NDIS_OID Oid,
  141. IN PVOID InformationBuffer,
  142. IN INT InformationBufferLength,
  143. IN PUINT BytesRead,
  144. IN PUINT BytesNeeded
  145. )
  146. /*++
  147. Routine Description:
  148. performs a set operation for a single OID.
  149. Arguments:
  150. Adapter : The adapter that the set is for
  151. Open : The binding that the set is for
  152. Oid : The OID to set
  153. InformationBuffer : Holds the data to be set
  154. InformationBufferLength : The length of InformationBuffer
  155. BytesRead : If the call is successful, returns the number
  156. of bytes read from InformationBuffer
  157. BytesNeeded : If there is not enough data in InformationBuffer
  158. to satisfy the request, returns the amount of
  159. storage needed.
  160. Return Value:
  161. NDIS_STATUS_SUCCESS : if successful
  162. NDIS_STATUS_INVALID_OID : if the oid is not supported
  163. NDIS_STATUS_INVALID_DATA : if InformationBuffer contains bad data
  164. NDIS_STATUS_INVALID_LENGTH : if the InformationBufferLength is incorrect
  165. --*/
  166. {
  167. ULONG PacketFilter, NewLookAhead;
  168. NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
  169. //
  170. // Now check for the most common OIDs
  171. //
  172. DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO,
  173. ("LtReqSetInformation: setting OID - 0x%.8lx\n", Oid));
  174. switch (Oid)
  175. {
  176. case OID_GEN_CURRENT_PACKET_FILTER:
  177. // Localtalk only supports Directed and broadcast packets.
  178. // And the Lt firmware does not support PROMISCUSOUS mode.
  179. // so return NDIS_STATUS_NOT_SUPPORTED for these packet filters.
  180. if (InformationBufferLength != 4)
  181. {
  182. StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
  183. break;
  184. }
  185. NdisMoveMemory(
  186. (PVOID)&PacketFilter,
  187. InformationBuffer,
  188. sizeof(ULONG));
  189. DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO,
  190. ("LtReqSetInformation: Requested packet filter is %x\n", PacketFilter));
  191. if (PacketFilter == NDIS_PACKET_TYPE_BROADCAST ||
  192. PacketFilter == NDIS_PACKET_TYPE_DIRECTED ||
  193. PacketFilter == (NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED))
  194. {
  195. NdisAcquireSpinLock(&Adapter->Lock);
  196. Adapter->GlobalPacketFilter |= PacketFilter;
  197. Open->CurrentPacketFilter = PacketFilter;
  198. NdisReleaseSpinLock(&Adapter->Lock);
  199. *BytesRead = InformationBufferLength;
  200. }
  201. else
  202. {
  203. StatusToReturn = NDIS_STATUS_INVALID_DATA;
  204. }
  205. break;
  206. case OID_GEN_CURRENT_LOOKAHEAD:
  207. if (InformationBufferLength != 4)
  208. {
  209. StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
  210. break;
  211. }
  212. NdisMoveMemory(
  213. (PVOID)&NewLookAhead,
  214. InformationBuffer,
  215. sizeof(ULONG));
  216. DBGPRINT(DBG_COMP_REQ,DBG_LEVEL_INFO,
  217. ("LtReqSetInformation: Requested Lookahead size is %d\n", NewLookAhead));
  218. if ((NewLookAhead > LT_MAX_INDICATE_SIZE) ||
  219. (NewLookAhead < LT_MIN_INDICATE_SIZE))
  220. {
  221. StatusToReturn = NDIS_STATUS_INVALID_DATA;
  222. break;
  223. }
  224. NdisAcquireSpinLock(&Adapter->Lock);
  225. // valid lookahead size, so set it
  226. Open->CurrentLookAheadSize = NewLookAhead;
  227. // adjust the global lookaheadsize
  228. if (Adapter->GlobalLookAheadSize < NewLookAhead)
  229. {
  230. Adapter->GlobalLookAheadSize = NewLookAhead;
  231. }
  232. else
  233. {
  234. LtReqAdjustLookAhead(
  235. &Adapter->GlobalLookAheadSize,
  236. &Adapter->OpenBindings);
  237. }
  238. NdisReleaseSpinLock(&Adapter->Lock);
  239. *BytesRead = 4;
  240. break;
  241. default:
  242. StatusToReturn = NDIS_STATUS_INVALID_OID;
  243. break;
  244. }
  245. return(StatusToReturn);
  246. }
  247. LtReqQueryInformation(
  248. IN PLT_ADAPTER Adapter,
  249. IN PLT_OPEN Open,
  250. IN NDIS_OID Oid,
  251. IN PVOID InformationBuffer,
  252. IN INT InformationBufferLength,
  253. IN PUINT BytesWritten,
  254. IN PUINT BytesNeeded,
  255. IN BOOLEAN Global
  256. )
  257. /*++
  258. Routine Description:
  259. performs a query operation for a single OID.
  260. Arguments:
  261. Adapter : The adapter that the query is for
  262. Open : The binding that the query is for
  263. Oid : The OID to query
  264. InformationBuffer : Holds the result of the query.
  265. InformationBufferLength : The length of InformationBuffer.
  266. BytesWritten : If the call is successful, returns the
  267. number of bytes written to InformationBuffer
  268. BytesNeeded : If there is not enough room in InformationBuffer
  269. to satisfy the request, returns the amount of
  270. storage needed
  271. Global : TRUE if the request originated from the adapter.
  272. FALSE if the request came from a binding
  273. Return Value:
  274. NDIS_STATUS_SUCCESS : if successful
  275. NDIS_STATUS_INVALID_OID : if the query is on an OID we do not support
  276. NDIS_STATUS_BUFFER_TOO_SHORT: if InformationBufferLength is too small to
  277. hold the information returned
  278. --*/
  279. {
  280. UINT OidIndex;
  281. ULONG GenericUlong;
  282. USHORT GenericUshort;
  283. PVOID SourceBuffer = &GenericUlong;
  284. UINT SourceBufferLength = sizeof(ULONG);
  285. PNDIS_OID SupportedOidArray = LtProtocolSupportedOids;
  286. UINT SupportedOids = (sizeof(LtProtocolSupportedOids)/sizeof(ULONG));
  287. static UCHAR VendorDescription[] = LT_VENDOR_DESCR;
  288. static UCHAR VendorId[3] = LT_VENDOR_ID;
  289. if (Global)
  290. {
  291. SupportedOidArray = LtGlobalSupportedOids;
  292. SupportedOids = sizeof(LtGlobalSupportedOids)/sizeof(ULONG);
  293. }
  294. //
  295. // Check that the OID is valid.
  296. //
  297. for (OidIndex=0; OidIndex < SupportedOids; OidIndex++)
  298. {
  299. if (Oid == SupportedOidArray[OidIndex])
  300. {
  301. break;
  302. }
  303. }
  304. if (OidIndex == SupportedOids)
  305. {
  306. *BytesWritten = 0;
  307. return(NDIS_STATUS_INVALID_OID);
  308. }
  309. switch (Oid)
  310. {
  311. case OID_GEN_SUPPORTED_LIST:
  312. SourceBuffer = SupportedOidArray;
  313. SourceBufferLength = SupportedOids * sizeof(ULONG);
  314. break;
  315. case OID_GEN_HARDWARE_STATUS:
  316. GenericUlong = NdisHardwareStatusReady;
  317. if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS)
  318. {
  319. GenericUlong = NdisHardwareStatusReset;
  320. }
  321. break;
  322. case OID_GEN_MEDIA_SUPPORTED:
  323. GenericUlong = NdisMediumLocalTalk;
  324. break;
  325. case OID_GEN_MEDIA_IN_USE:
  326. GenericUlong = NdisMediumLocalTalk;
  327. // if no binding exists then media is not in use
  328. if (Global && Adapter->OpenCount == 0)
  329. {
  330. SourceBufferLength = 0;
  331. }
  332. break;
  333. case OID_GEN_MAXIMUM_LOOKAHEAD:
  334. GenericUlong = LT_MAX_INDICATE_SIZE;
  335. break;
  336. case OID_GEN_MAXIMUM_FRAME_SIZE:
  337. GenericUlong = LT_MAXIMUM_PACKET_SIZE;
  338. break;
  339. case OID_GEN_LINK_SPEED:
  340. GenericUlong = LT_LINK_SPEED;
  341. break;
  342. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  343. GenericUlong = LT_MAXIMUM_PACKET_SIZE;
  344. break;
  345. case OID_GEN_RECEIVE_BUFFER_SPACE:
  346. // BUGBUG: need to determine number of recv buffers or in this case the
  347. // amount of space for receives
  348. GenericUlong = LT_MAXIMUM_PACKET_SIZE * 5;
  349. break;
  350. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  351. GenericUlong = 1;
  352. break;
  353. case OID_GEN_RECEIVE_BLOCK_SIZE:
  354. // BUGBUG: need to determine number of recv buffers
  355. GenericUlong = 5;
  356. break;
  357. case OID_GEN_VENDOR_ID:
  358. SourceBuffer = VendorId;
  359. SourceBufferLength = sizeof(VendorId);
  360. break;
  361. case OID_GEN_VENDOR_DESCRIPTION:
  362. SourceBuffer = VendorDescription;
  363. SourceBufferLength = sizeof(VendorDescription);
  364. break;
  365. case OID_GEN_CURRENT_PACKET_FILTER:
  366. GenericUlong = Open->CurrentPacketFilter;
  367. if (Global)
  368. {
  369. GenericUlong = Adapter->GlobalPacketFilter;
  370. }
  371. break;
  372. case OID_GEN_CURRENT_LOOKAHEAD:
  373. GenericUlong = Open->CurrentLookAheadSize;
  374. if (Global)
  375. {
  376. GenericUlong = Adapter->GlobalLookAheadSize;
  377. }
  378. break;
  379. case OID_GEN_DRIVER_VERSION:
  380. GenericUshort = (LT_MAJOR_VERSION << 8) + LT_MINOR_VERSION;
  381. SourceBuffer = &GenericUshort;
  382. SourceBufferLength = sizeof(USHORT);
  383. break;
  384. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  385. GenericUlong = LT_MAXIMUM_PACKET_SIZE;
  386. break;
  387. case OID_GEN_XMIT_OK:
  388. case OID_GEN_RCV_OK:
  389. case OID_GEN_XMIT_ERROR:
  390. case OID_GEN_RCV_ERROR:
  391. case OID_GEN_RCV_NO_BUFFER:
  392. OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
  393. ASSERT(OidIndex < GM_ARRAY_SIZE);
  394. GenericUlong = Adapter->GeneralMandatory[OidIndex];
  395. break;
  396. case OID_GEN_DIRECTED_BYTES_XMIT:
  397. case OID_GEN_BROADCAST_BYTES_XMIT:
  398. case OID_GEN_DIRECTED_BYTES_RCV:
  399. case OID_GEN_BROADCAST_BYTES_RCV:
  400. OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
  401. ASSERT(OidIndex < GM_ARRAY_SIZE);
  402. SourceBuffer = &Adapter->GeneralOptionalByteCount[OidIndex / 2];
  403. SourceBufferLength = sizeof(LARGE_INTEGER);
  404. break;
  405. case OID_GEN_DIRECTED_FRAMES_XMIT:
  406. case OID_GEN_BROADCAST_FRAMES_XMIT:
  407. case OID_GEN_DIRECTED_FRAMES_RCV:
  408. case OID_GEN_BROADCAST_FRAMES_RCV:
  409. OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
  410. ASSERT(OidIndex < GO_COUNT_ARRAY_SIZE);
  411. GenericUlong = Adapter->GeneralOptionalFrameCount[OidIndex / 2];
  412. break;
  413. case OID_GEN_RCV_CRC_ERROR:
  414. case OID_GEN_TRANSMIT_QUEUE_LENGTH:
  415. OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
  416. ASSERT(OidIndex < GO_ARRAY_SIZE);
  417. GenericUlong = Adapter->GeneralOptional[OidIndex - GO_ARRAY_START];
  418. break;
  419. case OID_GEN_MAC_OPTIONS:
  420. GenericUlong = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA;
  421. break;
  422. case OID_LTALK_CURRENT_NODE_ID:
  423. SourceBuffer = &GenericUshort;
  424. GenericUshort = Adapter->NodeId;
  425. SourceBufferLength = 2;
  426. break;
  427. case OID_LTALK_IN_BROADCASTS:
  428. case OID_LTALK_IN_LENGTH_ERRORS:
  429. OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
  430. ASSERT (OidIndex < MM_ARRAY_SIZE);
  431. GenericUlong = Adapter->MediaMandatory[OidIndex];
  432. break;
  433. case OID_LTALK_OUT_NO_HANDLERS:
  434. case OID_LTALK_DEFERS:
  435. OidIndex = (Oid & LT_OID_INDEX_MASK) - 1;
  436. ASSERT (OidIndex < MO_ARRAY_SIZE);
  437. GenericUlong = Adapter->MediaOptional[OidIndex];
  438. break;
  439. default:
  440. // should never get here
  441. ASSERT(FALSE);
  442. break;
  443. }
  444. if ((INT)SourceBufferLength > InformationBufferLength)
  445. {
  446. *BytesNeeded = SourceBufferLength;
  447. return(NDIS_STATUS_BUFFER_TOO_SHORT);
  448. }
  449. NdisMoveMemory(
  450. InformationBuffer,
  451. SourceBuffer,
  452. SourceBufferLength);
  453. *BytesWritten = SourceBufferLength;
  454. return(NDIS_STATUS_SUCCESS);
  455. }
  456. STATIC
  457. VOID
  458. LtReqAdjustLookAhead(
  459. OUT PUINT GlobalLookAheadSize,
  460. IN PLIST_ENTRY OpenBindings
  461. )
  462. /*++
  463. Routine Description:
  464. called by LtReqSetInformation to adjust the global lookahead size when
  465. the previously largest lookahead size (on a binding) is adjusted
  466. THIS ROUTINE IS CALLED WITH THE SPINLOCK HELD
  467. Arguments:
  468. GlobalLookAheadSize : the global lookahead param we're adjusting
  469. OpenBindings : the list of bindings we need to traverse
  470. Return Value:
  471. none
  472. --*/
  473. {
  474. PLT_OPEN Binding;
  475. PLIST_ENTRY p = OpenBindings->Flink;
  476. UINT MaxLookAheadSize = 0;
  477. while(p != OpenBindings)
  478. {
  479. Binding = CONTAINING_RECORD(
  480. p,
  481. LT_OPEN,
  482. Linkage);
  483. if (Binding->CurrentLookAheadSize > MaxLookAheadSize)
  484. {
  485. MaxLookAheadSize = Binding->CurrentLookAheadSize;
  486. }
  487. p = p->Flink;
  488. }
  489. *GlobalLookAheadSize = MaxLookAheadSize;
  490. }