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.

429 lines
13 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. usb8023.h
  5. Author:
  6. ervinp
  7. Environment:
  8. Kernel mode
  9. Revision History:
  10. --*/
  11. /*
  12. * If this flag is defined TRUE, then when an endpoint on the device stalls,
  13. * we will do a full USB port reset
  14. * and then restore the device to a running state.
  15. * Otherwise, we just send the RNDIS Reset message to the control pipe.
  16. */
  17. #define DO_FULL_RESET TRUE
  18. #define DRIVER_SIG '208U'
  19. #define GUARD_WORD 'draG'
  20. #define NUM_BYTES_PROTOCOL_RESERVED_SECTION 16
  21. #define DEFAULT_MULTICAST_SIZE 16
  22. /*
  23. * Total number of our irp/urb packets for sending/receiving
  24. * ethernet frames to/from the device.
  25. */
  26. #define USB_PACKET_POOL_SIZE 32
  27. #define PACKET_BUFFER_SIZE 0x4000
  28. /*
  29. * The USB host controller can typically schedule 2 URBs at a time.
  30. * To keep the hardware busy, keep twice this many read URBs in the pipe.
  31. */
  32. #define NUM_READ_PACKETS (2*2)
  33. /*
  34. * - Ethernet 14-byte Header
  35. */
  36. #define ETHERNET_ADDRESS_LENGTH 6
  37. #pragma pack(1)
  38. typedef struct {
  39. UCHAR Destination[ETHERNET_ADDRESS_LENGTH];
  40. UCHAR Source[ETHERNET_ADDRESS_LENGTH];
  41. USHORT TypeLength; // note: length appears as big-endian in packet.
  42. } ETHERNET_HEADER;
  43. #pragma pack()
  44. #define MINIMUM_ETHERNET_PACKET_SIZE 60 // from e100bex driver
  45. #define MAXIMUM_ETHERNET_PACKET_SIZE (1500+sizeof(ETHERNET_HEADER)) // 1514 == 0x05EA
  46. /*
  47. * This is the size of a read on the control pipe.
  48. * It needs to be large enough for the init-complete message and response to
  49. * OID_GEN_SUPPORTED_LIST.
  50. */
  51. #define MAXIMUM_DEVICE_MESSAGE_SIZE 0x400
  52. typedef struct {
  53. ULONG sig;
  54. LIST_ENTRY adaptersListEntry;
  55. KSPIN_LOCK adapterSpinLock;
  56. PDEVICE_OBJECT physDevObj;
  57. PDEVICE_OBJECT nextDevObj;
  58. /*
  59. * All USB structures and handles must be declared as neutral types in order
  60. * to compile with the NDIS/RNDIS sources.
  61. */
  62. PVOID deviceDesc; // PUSB_DEVICE_DESCRIPTOR
  63. PVOID configDesc; // PUSB_CONFIGURATION_DESCRIPTOR
  64. PVOID configHandle; // USBD_CONFIGURATION_HANDLE
  65. PVOID interfaceInfo; // PUSBD_INTERFACE_INFORMATION
  66. PVOID interfaceInfoMaster; // PUSBD_INTERFACE_INFORMATION
  67. BOOLEAN initialized;
  68. BOOLEAN halting;
  69. BOOLEAN resetting;
  70. BOOLEAN gotPacketFilterIndication;
  71. PVOID readPipeHandle; // USBD_PIPE_HANDLE
  72. PVOID writePipeHandle; // USBD_PIPE_HANDLE
  73. PVOID notifyPipeHandle; // USBD_PIPE_HANDLE
  74. ULONG readPipeLength;
  75. ULONG writePipeLength;
  76. ULONG notifyPipeLength;
  77. UCHAR readPipeEndpointAddr;
  78. UCHAR writePipeEndpointAddr;
  79. UCHAR notifyPipeEndpointAddr;
  80. LIST_ENTRY usbFreePacketPool; // free packet pool
  81. LIST_ENTRY usbPendingReadPackets; // reads down in the USB stack
  82. LIST_ENTRY usbPendingWritePackets; // writes down in the usb stack
  83. LIST_ENTRY usbCompletedReadPackets; // completed read buffers being indicated to NDIS
  84. /*
  85. * Keep statistics on packet states for throttling, etc.
  86. * Some fields are used only to provide history for debugging,
  87. * and we want these for retail as well as debug version.
  88. */
  89. ULONG numFreePackets;
  90. ULONG numActiveReadPackets;
  91. ULONG numActiveWritePackets;
  92. ULONG numIndicatedReadPackets;
  93. ULONG numHardResets;
  94. ULONG numSoftResets;
  95. ULONG numConsecutiveReadFailures;
  96. PVOID notifyIrpPtr;
  97. PVOID notifyUrbPtr;
  98. PUCHAR notifyBuffer;
  99. ULONG notifyBufferCurrentLength;
  100. BOOLEAN notifyStopped;
  101. BOOLEAN cancellingNotify;
  102. KEVENT notifyCancelEvent;
  103. /*
  104. * All NDIS handles must be declared as neutral types
  105. * in order to compile with the USB sources.
  106. */
  107. PVOID ndisAdapterHandle;
  108. PVOID rndisAdapterHandle; // RNDIS_HANDLE
  109. ULONG rndismpMajorVersion;
  110. ULONG rndismpMinorVersion;
  111. ULONG rndismpMaxTransferSize;
  112. ULONG currentPacketFilter;
  113. UCHAR MAC_Address[ETHERNET_ADDRESS_LENGTH];
  114. ULONG dbgCurrentOid;
  115. ULONG readDeficit;
  116. PIO_WORKITEM ioWorkItem;
  117. BOOLEAN workItemOrTimerPending;
  118. KEVENT workItemOrTimerEvent;
  119. KTIMER backoffTimer;
  120. KDPC backoffTimerDPC;
  121. ULONG readReentrancyCount; // used to prevent infinite loop in ReadPipeCompletion()
  122. #if DO_FULL_RESET
  123. BOOLEAN needFullReset;
  124. #endif
  125. #if DBG
  126. BOOLEAN dbgInLowPacketStress;
  127. #endif
  128. #ifdef RAW_TEST
  129. BOOLEAN rawTest;
  130. #endif
  131. } ADAPTEREXT;
  132. typedef struct {
  133. ULONG sig;
  134. LIST_ENTRY listEntry;
  135. /*
  136. * All WDM and USB structures must be declared as neutral types
  137. * in order to compile with the NDIS/RNDIS sources.
  138. */
  139. PVOID irpPtr; // PIRP
  140. PVOID urbPtr; // PURB
  141. PUCHAR dataBuffer;
  142. ULONG dataBufferMaxLength; // Actual size of the data buffer
  143. ULONG dataBufferCurrentLength; // Length of data currently in buffer
  144. PMDL dataBufferMdl; // MDL for this packet's dataBuffer
  145. PMDL ndisSendPktMdl; // Pointer to NDIS' MDL for a packet being sent.
  146. ULONG packetId;
  147. ADAPTEREXT *adapter;
  148. BOOLEAN cancelled;
  149. KEVENT cancelEvent;
  150. PVOID rndisMessageHandle; // RNDIS_HANDLE
  151. #ifdef RAW_TEST
  152. BOOLEAN dataPacket;
  153. ULONG rcvDataOffset;
  154. ULONG rcvByteCount;
  155. #endif
  156. #if DBG
  157. ULONG timeStamp; // Time placed in current queue.
  158. #endif
  159. } USBPACKET;
  160. #define USB_DEVICE_CLASS_CDC 0x02
  161. #define USB_DEVICE_CLASS_DATA 0x0A
  162. /*
  163. * Formats of CDC functional descriptors
  164. */
  165. #pragma pack(1)
  166. struct cdcFunctionDescriptor_CommonHeader {
  167. UCHAR bFunctionLength;
  168. UCHAR bDescriptorType;
  169. UCHAR bDescriptorSubtype;
  170. // ...
  171. };
  172. struct cdcFunctionDescriptor_Ethernet {
  173. UCHAR bFunctionLength;
  174. UCHAR bDescriptorType;
  175. UCHAR bDescriptorSubtype;
  176. UCHAR iMACAddress; // string index of MAC Address string
  177. ULONG bmEthernetStatistics;
  178. USHORT wMaxSegmentSize;
  179. USHORT wNumberMCFilters;
  180. UCHAR bNumberPowerFilters;
  181. };
  182. #pragma pack()
  183. #define CDC_REQUEST_SET_ETHERNET_PACKET_FILTER 0x43
  184. #define CDC_ETHERNET_PACKET_TYPE_PROMISCUOUS (1 << 0)
  185. #define CDC_ETHERNET_PACKET_TYPE_ALL_MULTICAST (1 << 1)
  186. #define CDC_ETHERNET_PACKET_TYPE_DIRECTED (1 << 2)
  187. #define CDC_ETHERNET_PACKET_TYPE_BROADCAST (1 << 3)
  188. #define CDC_ETHERNET_PACKET_TYPE_MULTICAST_ENUMERATED (1 << 4)
  189. enum notifyRequestType {
  190. CDC_NOTIFICATION_NETWORK_CONNECTION = 0x00,
  191. CDC_NOTIFICATION_RESPONSE_AVAILABLE = 0x01,
  192. CDC_NOTIFICATION_AUX_JACK_HOOK_STATE = 0x08,
  193. CDC_NOTIFICATION_RING_DETECT = 0x09,
  194. CDC_NOTIFICATION_SERIAL_STATE = 0x20,
  195. CDC_NOTIFICATION_CALL_STATE_CHANGE = 0x28,
  196. CDC_NOTIFICATION_LINE_STATE_CHANGE = 0x29,
  197. CDC_NOTIFICATION_CONNECTION_SPEED_CHANGE = 0x2A
  198. };
  199. #define CDC_RNDIS_NOTIFICATION 0xA1
  200. #define CDC_RNDIS_RESPONSE_AVAILABLE 0x01
  201. #pragma pack(1)
  202. struct cdcNotification_CommonHeader {
  203. UCHAR bmRequestType;
  204. UCHAR bNotification;
  205. USHORT wValue;
  206. USHORT wIndex;
  207. USHORT wLength;
  208. UCHAR data[0];
  209. };
  210. #pragma pack()
  211. /*
  212. *
  213. ****************************************************************************
  214. */
  215. /*
  216. ****************************************************************************
  217. *
  218. * Native RNDIS codes
  219. *
  220. */
  221. #define NATIVE_RNDIS_SEND_ENCAPSULATED_COMMAND 0x00
  222. #define NATIVE_RNDIS_GET_ENCAPSULATED_RESPONSE 0x01
  223. #define NATIVE_RNDIS_RESPONSE_AVAILABLE 0x01
  224. /*
  225. *
  226. ****************************************************************************
  227. */
  228. #define MAX(a, b) (((a) >= (b)) ? (a) : (b))
  229. #define MIN(a, b) (((a) <= (b)) ? (a) : (b))
  230. #ifndef EXCEPTION_NONCONTINUABLE_EXCEPTION
  231. // from winbase.h
  232. #define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION
  233. #endif
  234. // from ntos\inc\ex.h
  235. NTKERNELAPI VOID NTAPI ExRaiseException(PEXCEPTION_RECORD ExceptionRecord);
  236. /*
  237. * Function prototypes
  238. */
  239. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
  240. ADAPTEREXT *NewAdapter(PDEVICE_OBJECT pdo);
  241. VOID FreeAdapter(ADAPTEREXT *adapter);
  242. VOID EnqueueAdapter(ADAPTEREXT *adapter);
  243. VOID DequeueAdapter(ADAPTEREXT *adapter);
  244. VOID HaltAdapter(ADAPTEREXT *adapter);
  245. PVOID AllocPool(ULONG size);
  246. VOID FreePool(PVOID ptr);
  247. PVOID MemDup(PVOID dataPtr, ULONG length);
  248. VOID DelayMs(ULONG numMillisec);
  249. BOOLEAN GetRegValue(ADAPTEREXT *adapter, PWCHAR wValueName, OUT PULONG valuePtr, BOOLEAN hwKey);
  250. BOOLEAN SetRegValue(ADAPTEREXT *adapter, PWCHAR wValueName, ULONG newValue, BOOLEAN hwKey);
  251. VOID ByteSwap(PUCHAR buf, ULONG len);
  252. BOOLEAN AllocateCommonResources(ADAPTEREXT *adapter);
  253. VOID MyInitializeMdl(PMDL mdl, PVOID buf, ULONG bufLen);
  254. PVOID GetSystemAddressForMdlSafe(PMDL MdlAddress);
  255. ULONG CopyMdlToBuffer(PUCHAR buf, PMDL mdl, ULONG bufLen);
  256. ULONG GetMdlListTotalByteCount(PMDL mdl);
  257. BOOLEAN InitUSB(ADAPTEREXT *adapter);
  258. NTSTATUS GetDeviceDescriptor(ADAPTEREXT *adapter);
  259. NTSTATUS GetConfigDescriptor(ADAPTEREXT *adapter);
  260. NTSTATUS SelectConfiguration(ADAPTEREXT *adapter);
  261. NTSTATUS FindUSBPipeHandles(ADAPTEREXT *adapter);
  262. VOID StartUSBReadLoop(ADAPTEREXT *adapter);
  263. VOID TryReadUSB(ADAPTEREXT *adapter);
  264. USBPACKET *NewPacket(ADAPTEREXT *adapter);
  265. VOID FreePacket(USBPACKET *packet);
  266. VOID EnqueueFreePacket(USBPACKET *packet);
  267. USBPACKET *DequeueFreePacket(ADAPTEREXT *adapter);
  268. VOID EnqueuePendingReadPacket(USBPACKET *packet);
  269. VOID DequeuePendingReadPacket(USBPACKET *packet);
  270. VOID EnqueuePendingWritePacket(USBPACKET *packet);
  271. VOID DequeuePendingWritePacket(USBPACKET *packet);
  272. VOID EnqueueCompletedReadPacket(USBPACKET *packet);
  273. VOID DequeueCompletedReadPacket(USBPACKET *packet);
  274. VOID CancelAllPendingPackets(ADAPTEREXT *adapter);
  275. NTSTATUS SubmitUSBReadPacket(USBPACKET *packet);
  276. NTSTATUS SubmitUSBWritePacket(USBPACKET *packet);
  277. NTSTATUS SubmitNotificationRead(ADAPTEREXT *adapter, BOOLEAN synchronous);
  278. NTSTATUS SubmitPacketToControlPipe(USBPACKET *packet, BOOLEAN synchronous, BOOLEAN simulated);
  279. BOOLEAN RegisterRNDISMicroport(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
  280. VOID IndicateSendStatusToRNdis(USBPACKET *packet, NTSTATUS status);
  281. NTSTATUS KLSIWeirdInit(ADAPTEREXT *adapter);
  282. BOOLEAN KLSIStagePartialPacket(ADAPTEREXT *adapter, USBPACKET *packet);
  283. NTSTATUS KLSISetEthernetPacketFilter(ADAPTEREXT *adapter, USHORT packetFilterMask);
  284. VOID RNDISProcessNotification(ADAPTEREXT *adapter);
  285. NTSTATUS IndicateRndisMessage(USBPACKET *packet, BOOLEAN bIsData);
  286. #ifdef RAW_TEST
  287. PMDL AddDataHeader(IN PMDL pMessageMdl);
  288. VOID FreeDataHeader(IN USBPACKET * packet);
  289. VOID SkipRcvRndisPacketHeader(IN USBPACKET * packet);
  290. VOID UnskipRcvRndisPacketHeader(IN USBPACKET * packet);
  291. #endif
  292. NTSTATUS ReadPacketFromControlPipe(USBPACKET *packet, BOOLEAN synchronous);
  293. VOID AdapterFullResetAndRestore(ADAPTEREXT *adapter);
  294. NTSTATUS GetUSBPortStatus(ADAPTEREXT *adapter, PULONG portStatus);
  295. NTSTATUS ResetPipe(ADAPTEREXT *adapter, PVOID pipeHandle);
  296. NTSTATUS AbortPipe(ADAPTEREXT *adapter, PVOID pipeHandle);
  297. NTSTATUS SimulateRNDISHalt(ADAPTEREXT *adapter);
  298. NTSTATUS SimulateRNDISInit(ADAPTEREXT *adapter);
  299. NTSTATUS SimulateRNDISSetPacketFilter(ADAPTEREXT *adapter);
  300. NTSTATUS SimulateRNDISSetCurrentAddress(ADAPTEREXT *adapter);
  301. VOID ServiceReadDeficit(ADAPTEREXT *adapter);
  302. VOID QueueAdapterWorkItem(ADAPTEREXT *adapter);
  303. VOID AdapterWorkItemCallback(IN PDEVICE_OBJECT devObj, IN PVOID context);
  304. VOID BackoffTimerDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
  305. VOID ProcessWorkItemOrTimerCallback(ADAPTEREXT *adapter);
  306. /*
  307. * The Win98SE kernel does not expose IoWorkItems, so implement them internally.
  308. * This introduces a slight race condition on unload, but there is no fix without externally-implemented workitems.
  309. */
  310. #if SPECIAL_WIN98SE_BUILD
  311. typedef struct _IO_WORKITEM {
  312. WORK_QUEUE_ITEM WorkItem;
  313. PIO_WORKITEM_ROUTINE Routine;
  314. PDEVICE_OBJECT DeviceObject;
  315. PVOID Context;
  316. #if DBG
  317. ULONG Size;
  318. #endif
  319. } IO_WORKITEM, *PIO_WORKITEM;
  320. PIO_WORKITEM MyIoAllocateWorkItem(PDEVICE_OBJECT DeviceObject);
  321. VOID MyIoFreeWorkItem(PIO_WORKITEM IoWorkItem);
  322. VOID MyIoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context);
  323. VOID MyIopProcessWorkItem(IN PVOID Parameter);
  324. #endif
  325. /*
  326. * Externs
  327. */
  328. extern LIST_ENTRY allAdaptersList;
  329. extern KSPIN_LOCK globalSpinLock;