Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. cmnbuf.c
  5. Abstract:
  6. Code to manage common buffer -- hardware addressable memory
  7. a common buffer block looks like this
  8. start ------------ <- address returned from the hal
  9. padding
  10. ------------ <- address returned to the miniport
  11. mp data
  12. ------------ <- ptr to header
  13. header
  14. end ------------
  15. Environment:
  16. kernel mode only
  17. Notes:
  18. Revision History:
  19. 6-20-99 : created
  20. --*/
  21. #include "common.h"
  22. // paged functions
  23. #ifdef ALLOC_PRAGMA
  24. #pragma alloc_text(PAGE, USBPORT_HalAllocateCommonBuffer)
  25. #endif
  26. // non paged functions
  27. PUSBPORT_COMMON_BUFFER
  28. USBPORT_HalAllocateCommonBuffer(
  29. PDEVICE_OBJECT FdoDeviceObject,
  30. ULONG NumberOfBytes
  31. )
  32. /*++
  33. Routine Description:
  34. Allocates common buffer directly from the hal.
  35. The common buffer is passed to the miniport, we
  36. always allocate a multiple of PAGE_SIZE so the
  37. always starts on a page_boundry. This ensures
  38. proper alignement of the TDs used by the miniport
  39. Arguments:
  40. DeviceObject - DeviceObject of the controller to stop
  41. Return Value:
  42. returns Virtual Address of common buffer or NULL if
  43. unsuccessful.
  44. --*/
  45. {
  46. PDEVICE_EXTENSION devExt;
  47. PUSBPORT_COMMON_BUFFER header;
  48. PUCHAR virtualAddress, mpBuffer, baseVa;
  49. PHYSICAL_ADDRESS logicalAddress;
  50. ULONG headerLength;
  51. ULONG n, basePhys, mpBufferPhys, pageCount, extra;
  52. PAGED_CODE();
  53. LOGENTRY(NULL, FdoDeviceObject, LOG_XFERS, 'acm>', 0, 0, NumberOfBytes);
  54. GET_DEVICE_EXT(devExt, FdoDeviceObject);
  55. ASSERT_FDOEXT(devExt);
  56. // NULL initialize the return value in case the allocation fails
  57. //
  58. header = NULL;
  59. headerLength = sizeof(USBPORT_COMMON_BUFFER);
  60. // compute number min of pages we will need to satisfy
  61. // the request
  62. n = NumberOfBytes+headerLength;
  63. pageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, n);
  64. #if DBG
  65. {
  66. ULONG pc;
  67. // compute number of pages we will need
  68. pc = n / PAGE_SIZE;
  69. if ((n % PAGE_SIZE)) {
  70. pc++;
  71. }
  72. USBPORT_ASSERT(pc == pageCount);
  73. }
  74. #endif
  75. extra = (pageCount*PAGE_SIZE)-n;
  76. n = (pageCount*PAGE_SIZE);
  77. USBPORT_KdPrint((1,"'ALLOC(%d) extra %d bytes\n", n, extra));
  78. virtualAddress =
  79. HalAllocateCommonBuffer(devExt->Fdo.AdapterObject,
  80. n,
  81. &logicalAddress,
  82. TRUE);
  83. #if DBG
  84. if (virtualAddress == NULL) {
  85. USBPORT_KdPrint((0,"'HalAllocateCommonBuffer failed\n"));
  86. USBPORT_KdPrint((0,"'alloced bytes %d\n"));
  87. DEBUG_BREAK();
  88. }
  89. #endif
  90. if (virtualAddress != NULL) {
  91. devExt->Fdo.StatCommonBufferBytes += n;
  92. basePhys = logicalAddress.LowPart & ~(PAGE_SIZE-1);
  93. baseVa = PAGE_ALIGN(virtualAddress);
  94. // hal should have given us a page aligned address since
  95. // we asked for a multiple of PAGE_SIZE,
  96. // i trust NT but not Win9x
  97. USBPORT_ASSERT(virtualAddress == baseVa);
  98. // client ptrs
  99. mpBuffer = baseVa;
  100. mpBufferPhys = basePhys;
  101. header = (PUSBPORT_COMMON_BUFFER) (mpBuffer+NumberOfBytes+extra);
  102. USBPORT_ASSERT(n == NumberOfBytes+extra+headerLength);
  103. // USB controllers only support 32 bit phys addresses
  104. // for control structures
  105. USBPORT_ASSERT(logicalAddress.HighPart == 0);
  106. #if DBG
  107. RtlFillMemory(virtualAddress, n, 'x');
  108. #endif
  109. // init the header
  110. header->Sig = SIG_CMNBUF;
  111. header->Flags = 0;
  112. header->TotalLength = n;
  113. header->LogicalAddress = logicalAddress;
  114. header->VirtualAddress = virtualAddress;
  115. header->BaseVa = baseVa;
  116. header->BasePhys = basePhys;
  117. header->MiniportLength = NumberOfBytes+extra;
  118. header->MiniportVa = mpBuffer;
  119. header->MiniportPhys = mpBufferPhys;
  120. // zero the client part
  121. RtlZeroMemory(header->MiniportVa, header->MiniportLength);
  122. }
  123. LOGENTRY(NULL, FdoDeviceObject, LOG_XFERS, 'acm<', mpBuffer, mpBufferPhys, header);
  124. return header;
  125. }
  126. VOID
  127. USBPORT_HalFreeCommonBuffer(
  128. PDEVICE_OBJECT FdoDeviceObject,
  129. PUSBPORT_COMMON_BUFFER CommonBuffer
  130. )
  131. /*++
  132. Routine Description:
  133. Free a common buffer for the miniport
  134. Arguments:
  135. Return Value:
  136. returns Virtual Address of common buffer or NULL if
  137. unsuccessful.
  138. --*/
  139. {
  140. PDEVICE_EXTENSION devExt;
  141. GET_DEVICE_EXT(devExt, FdoDeviceObject);
  142. ASSERT_FDOEXT(devExt);
  143. USBPORT_ASSERT(CommonBuffer != NULL);
  144. ASSERT_COMMON_BUFFER(CommonBuffer);
  145. LOGENTRY(NULL, FdoDeviceObject, LOG_XFERS, 'hFCB',
  146. CommonBuffer, CommonBuffer->TotalLength,
  147. CommonBuffer->MiniportVa);
  148. devExt->Fdo.StatCommonBufferBytes -=
  149. CommonBuffer->TotalLength;
  150. HalFreeCommonBuffer(devExt->Fdo.AdapterObject,
  151. CommonBuffer->TotalLength,
  152. CommonBuffer->LogicalAddress,
  153. CommonBuffer->MiniportVa,
  154. TRUE);
  155. }
  156. PUCHAR
  157. USBPORTSVC_MapHwPhysicalToVirtual(
  158. HW_32BIT_PHYSICAL_ADDRESS HwPhysicalAddress,
  159. PDEVICE_DATA DeviceData,
  160. PENDPOINT_DATA EndpointData
  161. )
  162. /*++
  163. Routine Description:
  164. given a physical address return the corresponding
  165. virtual address.
  166. Arguments:
  167. if the phys address is associated with an endpoint
  168. the endpoint is passed in.
  169. Return Value:
  170. Virtual Address, NULL if not found
  171. --*/
  172. {
  173. PDEVICE_EXTENSION devExt;
  174. PUCHAR virtualAddress;
  175. PHCD_ENDPOINT endpoint;
  176. ULONG offset;
  177. PDEVICE_OBJECT fdoDeviceObject;
  178. DEVEXT_FROM_DEVDATA(devExt, DeviceData);
  179. ASSERT_FDOEXT(devExt);
  180. fdoDeviceObject = devExt->HcFdoDeviceObject;
  181. LOGENTRY(NULL, fdoDeviceObject, LOG_XFERS, 'mapP', HwPhysicalAddress, 0,
  182. EndpointData);
  183. if (EndpointData == NULL) {
  184. TEST_TRAP();
  185. } else {
  186. PUSBPORT_COMMON_BUFFER cb;
  187. ENDPOINT_FROM_EPDATA(endpoint, EndpointData);
  188. ASSERT_ENDPOINT(endpoint);
  189. cb = endpoint->CommonBuffer;
  190. // mask off base physical address
  191. offset = HwPhysicalAddress - cb->BasePhys;
  192. virtualAddress = cb->BaseVa+offset;
  193. LOGENTRY(NULL, fdoDeviceObject, LOG_XFERS, 'mpPV', HwPhysicalAddress, offset,
  194. cb->BaseVa);
  195. USBPORT_ASSERT(HwPhysicalAddress >= cb->BasePhys &&
  196. HwPhysicalAddress < cb->BasePhys+cb->MiniportLength);
  197. LOGENTRY(NULL, fdoDeviceObject, LOG_XFERS, 'mapV', HwPhysicalAddress, 0,
  198. virtualAddress);
  199. return virtualAddress;
  200. }
  201. // probably a bug in the miniport
  202. DEBUG_BREAK();
  203. return NULL;
  204. }