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.

1353 lines
31 KiB

  1. /* ++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. wceusbsh.h
  5. Abstract:
  6. Main entrypoint for Windows CE USB Serial Host driver, for
  7. ... Windows CE USB sync devices:
  8. SL11, Socket CF cards, HP Jornada, COMPAQ iPAQ, Casio Cassiopeia, etc.
  9. ... cables using the Anchor AN27x0 chipset (i.e. EZ-Link)
  10. ... ad-hoc USB NULL Modem Class
  11. Environment:
  12. kernel mode only
  13. Author:
  14. Jeff Midkiff (jeffmi)
  15. Revision History:
  16. 07-15-99 : rev 1.00 ActiveSync 3.1 initial release
  17. 04-20-00 : rev 1.01 Cedar 3.0 Platform Builder
  18. 09-20-00 : rev 1.02 finally have some hardware
  19. Notes:
  20. o) WCE Devices currently do not handle remote wake, nor can we put the device in power-off state when not used, etc.
  21. o) Pageable Code sections are marked as follows:
  22. PAGEWCE0 - useable only during init/deinit
  23. PAGEWCE1 - useable during normal runtime
  24. -- */
  25. #if !defined(_WCEUSBSH_H_)
  26. #define _WCEUSBSH_H_
  27. #include <wdm.h>
  28. #include <usbdi.h>
  29. #include <usbdlib.h>
  30. #include <ntddser.h>
  31. #define DRV_NAME "WCEUSBSH"
  32. #include "errlog.h"
  33. #include "perf.h"
  34. #include "debug.h"
  35. //
  36. // Instantiate the GUID
  37. //
  38. #if !defined(FAR)
  39. #define FAR
  40. #endif
  41. #include <initguid.h>
  42. /* 25dbce51-6c8f-4a72-8a6d-b54c2b4fc835 */
  43. DEFINE_GUID( GUID_WCE_SERIAL_USB, 0x25dbce51, 0x6c8f, 0x4a72, 0x8a, 0x6d, 0xb5, 0x4c, 0x2b, 0x4f, 0xc8, 0x35);
  44. #define WCEUSB_POOL_TAG 'HECW'
  45. //
  46. // Max times we let a pipe take STATUS_DEVICE_DATA_ERROR
  47. // before we shoot it in the head. This is registry configurable.
  48. // Make the default large enough for (somewhat) working hardware to recover.
  49. // I choose 100 because I know the error queuing code has handled queue depths of this size,
  50. // and COMPAQ/INTEL has known USB function chipset bugs and requested a huge recovery window.
  51. //
  52. #define DEFAULT_MAX_PIPE_DEVICE_ERRORS 100
  53. //
  54. // The max times we take a class/vendor specific command error on EP0.
  55. // This number can NOT change since
  56. // a) commands on EP0 should never fail unless the device is bad
  57. // b) ActiveSync retries commands (e.g. SET_DTR) this many times,
  58. // so we need a way to inform the user that device is hosed.
  59. //
  60. #define MAX_EP0_DEVICE_ERRORS 2
  61. extern ULONG g_ulMaxPipeErrors;
  62. #include "remlock.h"
  63. // TRUE - OS = Win98
  64. // FALSE - OS = WinNT
  65. extern BOOLEAN g_isWin9x;
  66. // do we expose a COMx: port. The default is NO,
  67. // since this is only for debug purposes
  68. extern BOOLEAN g_ExposeComPort;
  69. #ifdef POOL_TAGGING
  70. #undef ExAllocatePool
  71. #undef ExAllocatePoolWithQuota
  72. #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a, b, WCEUSB_POOL_TAG)
  73. #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a, b, WCEUSBSH_POOL_TAG)
  74. #endif
  75. extern LONG g_NumDevices;
  76. //typedef struct _DEVICE_EXTENSION *PDEVICE_EXTENSION;
  77. //
  78. // Emulation of the bit mask on the MODEM STATUS REGISTER.
  79. //
  80. #define SERIAL_MSR_DCTS 0x0001
  81. #define SERIAL_MSR_DDSR 0x0002
  82. #define SERIAL_MSR_DRI 0x0004
  83. #define SERIAL_MSR_DDCD 0x0008
  84. #define SERIAL_MSR_CTS 0x0010
  85. #define SERIAL_MSR_DSR 0x0020
  86. #define SERIAL_MSR_RI 0x0040
  87. #define SERIAL_MSR_DCD 0x0080
  88. //
  89. // Maximum char length for dos device name
  90. //
  91. #define DOS_NAME_MAX 80
  92. //
  93. // Maximum length for symbolic link
  94. //
  95. #define SYMBOLIC_NAME_LENGTH 128
  96. //
  97. // This define gives the default Object directory
  98. // that we should use to insert the symbolic links
  99. // between the NT device name and namespace used by
  100. // that object directory.
  101. //
  102. //#define DEFAULT_DIRECTORY L"DosDevices"
  103. //
  104. // PNP_STATE_Xxx flags
  105. //
  106. typedef enum _PNP_STATE {
  107. PnPStateInitialized,
  108. PnPStateAttached,
  109. PnPStateStarted,
  110. PnPStateRemovePending,
  111. PnPStateSupriseRemove,
  112. PnPStateStopPending,
  113. PnPStateStopped,
  114. PnPStateRemoved,
  115. PnPStateMax = PnPStateRemoved,
  116. } PNP_STATE, *PPNP_STATE;
  117. #define MILLISEC_TO_100NANOSEC(x) ((ULONGLONG) ((-(x)) * 10000))
  118. // default timeouts for pending items, in msec
  119. #define DEFAULT_CTRL_TIMEOUT 500
  120. #define DEFAULT_BULK_TIMEOUT 1000
  121. #define DEFAULT_PENDING_TIMEOUT DEFAULT_BULK_TIMEOUT
  122. #define WORK_ITEM_COMPLETE (0xFFFFFFFF)
  123. //
  124. // Work Item
  125. //
  126. typedef struct _WCE_WORK_ITEM {
  127. //
  128. // owning list this packet belongs on
  129. //
  130. LIST_ENTRY ListEntry;
  131. //
  132. // owning Device for this work item
  133. //
  134. PDEVICE_OBJECT DeviceObject;
  135. //
  136. // Context
  137. //
  138. PVOID Context;
  139. //
  140. // Flags
  141. //
  142. ULONG Flags;
  143. //
  144. // The work item
  145. //
  146. WORK_QUEUE_ITEM Item;
  147. } WCE_WORK_ITEM, *PWCE_WORK_ITEM;
  148. //
  149. // Where in the DeviceMap section of the registry serial port entries
  150. // should appear
  151. //
  152. #define SERIAL_DEVICE_MAP L"SERIALCOMM"
  153. //
  154. // COMM Port Context
  155. //
  156. typedef struct _COMPORT_INFO {
  157. //
  158. // Com Port number
  159. // read/written to from registry
  160. //
  161. ULONG PortNumber;
  162. //
  163. // (ones-based) instance number of device driver
  164. //
  165. ULONG Instance;
  166. //
  167. // number of successful Create calls on device
  168. //
  169. ULONG OpenCnt;
  170. //
  171. // True if a serial port symbolic link has been
  172. // created and should be removed upon deletion.
  173. //
  174. BOOLEAN SerialSymbolicLink;
  175. //
  176. // Symbolic link name -- e.g., \\DosDevices\COMx
  177. //
  178. UNICODE_STRING SerialPortName;
  179. //
  180. // written to SERIALCOMM -- e.g., COMx
  181. //
  182. UNICODE_STRING SerialCOMMname;
  183. } COM_INFO, *PCOMPORT_INFO;
  184. #define WCE_SERIAL_PORT_TYPE GUID_WCE_SERIAL_USB.Data2
  185. #if DBG
  186. #define ASSERT_SERIAL_PORT( _SP ) \
  187. { \
  188. ASSERT( WCE_SERIAL_PORT_TYPE == _SP.Type); \
  189. }
  190. #else
  191. #define ASSERT_SERIAL_PORT( _SP )
  192. #endif
  193. //
  194. // Serial Port Interface
  195. //
  196. typedef struct _SERIAL_PORT_INTERFACE {
  197. USHORT Type;
  198. //
  199. // exposed COMx information
  200. //
  201. COM_INFO Com;
  202. //
  203. // "named" (via SERIAL_BAUD_Xxx bitmask)
  204. // baud rates for this device
  205. //
  206. ULONG SupportedBauds;
  207. //
  208. // current baud rate
  209. //
  210. SERIAL_BAUD_RATE CurrentBaud;
  211. //
  212. // line control reg: StopBits, Parity, Wordlen
  213. //
  214. SERIAL_LINE_CONTROL LineControl;
  215. //
  216. // Handshake and control Flow control settings
  217. //
  218. SERIAL_HANDFLOW HandFlow;
  219. //
  220. // RS-232 Serial Interface Lines
  221. //
  222. ULONG RS232Lines;
  223. //
  224. // Emulation of Modem Status Register (MSR)
  225. //
  226. USHORT ModemStatus;
  227. //
  228. // pending set/clear DTR/RTS command, etc. in progress
  229. //
  230. PIRP ControlIrp;
  231. //
  232. // timeout controls for device
  233. //
  234. SERIAL_TIMEOUTS Timeouts;
  235. //
  236. // Special Chars: EOF, ERR, BREAK, EVENT, XON, XOFF
  237. //
  238. SERIAL_CHARS SpecialChars;
  239. //
  240. // Wait Mask
  241. //
  242. ULONG WaitMask; // Flag to determine if the occurence of SERIAL_EV_ should be noticed
  243. ULONG HistoryMask; // history of SERIAL_EV_
  244. PIRP CurrentWaitMaskIrp; // current wait mask Irp
  245. //
  246. // Fake Rx/Tx buffer size.
  247. //
  248. SERIAL_QUEUE_SIZE FakeQueueSize;
  249. //
  250. // Current number of Tx characters buffered.
  251. //
  252. ULONG CharsInWriteBuf;
  253. } SERIAL_PORT_INTERFACE, *PSERIAL_PORT_INTERFACE;
  254. //
  255. // Unique error log values
  256. //
  257. #define ERR_COMM_SYMLINK 1
  258. #define ERR_SERIALCOMM 2
  259. #define ERR_GET_DEVICE_DESCRIPTOR 3
  260. #define ERR_SELECT_INTERFACE 4
  261. #define ERR_CONFIG_DEVICE 5
  262. #define ERR_RESET_WORKER 6
  263. #define ERR_MAX_READ_PIPE_DEVICE_ERRORS 7
  264. #define ERR_MAX_WRITE_PIPE_DEVICE_ERRORS 8
  265. #define ERR_MAX_INT_PIPE_DEVICE_ERRORS 9
  266. #define ERR_USB_READ_BUFF_OVERRUN 10
  267. #define ERR_NO_USBREAD_BUFF 11
  268. #define ERR_NO_RING_BUFF 12
  269. #define ERR_NO_DEVICE_OBJ 13
  270. #define ERR_NO_READ_PIPE_RESET 14
  271. #define ERR_NO_WRITE_PIPE_RESET 15
  272. #define ERR_NO_INT_PIPE_RESET 16
  273. #define ERR_NO_CREATE_FILE 17
  274. #define ERR_NO_DTR 18
  275. #define ERR_NO_RTS 19
  276. //
  277. // NULL Modem USB Class
  278. //
  279. #define USB_NULL_MODEM_CLASS 0xFF
  280. #define DEFAULT_ALTERNATE_SETTING 0
  281. extern ULONG g_ulAlternateSetting;
  282. //
  283. // On a 300MHz MP machine it takes ~73 msec to
  284. // cancel a pending USB Read Irp from the USB stack.
  285. // On a P90 is takes ~14 ms (no SpinLock contention).
  286. // With a default timeout of 1000 msec you have a hard time connecting via
  287. // ActiveSync to CEPC using INT endpoints, and NT RAS ping times out a lot,
  288. // both due to app's timing.
  289. // However, you can easily connect with 100, 250, 500, 2000, etc. msec.
  290. // Note: with 100 msec reads take longer than normal since we timeout at almost 10x/sec
  291. //
  292. #define DEFAULT_INT_PIPE_TIMEOUT 1280
  293. extern LONG g_lIntTimout;
  294. //
  295. // USB COMM constants
  296. //
  297. #define WCEUSB_VENDOR_COMMAND 0
  298. #define WCEUSB_CLASS_COMMAND 1
  299. // Abstract Control Model defines
  300. #define USB_COMM_SET_CONTROL_LINE_STATE 0x0022
  301. // Control Line State - sent to device on default control pipe
  302. #define USB_COMM_DTR 0x0001
  303. #define USB_COMM_RTS 0x0002
  304. // Serial State Notification masks
  305. #define USB_COMM_DATA_READY_MASK 0X0001
  306. #define USB_COMM_MODEM_STATUS_MASK 0X0006
  307. // Serial State Notification bits - read from device on int pipe
  308. #define USB_COMM_CTS 0x0002
  309. #define USB_COMM_DSR 0x0004
  310. //
  311. // state machine defines for Irps that can pend in the USB stack
  312. //
  313. #define IRP_STATE_INVALID 0x0000
  314. #define IRP_STATE_START 0x0001
  315. #define IRP_STATE_PENDING 0x0002
  316. #define IRP_STATE_COMPLETE 0x0004
  317. #define IRP_STATE_CANCELLED 0x0008
  318. //
  319. // The following macros are used to initialize, set
  320. // and clear references in IRPs that are used by
  321. // this driver. The reference is stored in the fourth
  322. // argument of the irp, which is never used by any operation
  323. // accepted by this driver.
  324. //
  325. #define IRP_REF_RX_BUFFER (0x00000001)
  326. #define IRP_REF_CANCEL (0x00000002)
  327. #define IRP_REF_TOTAL_TIMER (0x00000004)
  328. #define IRP_REF_INTERVAL_TIMER (0x00000008)
  329. #define IRP_INIT_REFERENCE(Irp) { \
  330. IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4 = NULL; \
  331. }
  332. #define IRP_SET_REFERENCE(Irp,RefType) \
  333. do { \
  334. LONG _refType = (RefType); \
  335. PUINT_PTR _arg4 = (PVOID)&IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4; \
  336. *_arg4 |= _refType; \
  337. } while (0)
  338. #define IRP_CLEAR_REFERENCE(Irp,RefType) \
  339. do { \
  340. LONG _refType = (RefType); \
  341. PUINT_PTR _arg4 = (PVOID)&IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4; \
  342. *_arg4 &= ~_refType; \
  343. } while (0)
  344. #define IRP_REFERENCE_COUNT(Irp) \
  345. ((UINT_PTR)((IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4)))
  346. //
  347. // Priority increment for app's thread when completing
  348. // USB Serial I/O (IoCompleteRequest). Used mainly for pumpimg up
  349. // serial events & read completions.
  350. //
  351. //#define IO_WCEUSBS_INCREMENT 6
  352. //
  353. // These values are used by the routines that can be used
  354. // to complete a read (other than interval timeout) to indicate
  355. // to the interval timeout that it should complete.
  356. //
  357. #define SERIAL_COMPLETE_READ_CANCEL ((LONG)-1)
  358. #define SERIAL_COMPLETE_READ_TOTAL ((LONG)-2)
  359. #define SERIAL_COMPLETE_READ_COMPLETE ((LONG)-3)
  360. //
  361. // flags for work items
  362. //
  363. #define WORK_ITEM_RESET_READ_PIPE (0x00000001)
  364. #define WORK_ITEM_RESET_WRITE_PIPE (0x00000002)
  365. #define WORK_ITEM_RESET_INT_PIPE (0x00000004)
  366. #define WORK_ITEM_ABORT_READ_PIPE (0x00000010)
  367. #define WORK_ITEM_ABORT_WRITE_PIPE (0x00000020)
  368. #define WORK_ITEM_ABORT_INT_PIPE (0x00000040)
  369. typedef struct _DEVICE_EXTENSION *PDEVICE_EXTENSION;
  370. //
  371. // Common Read/Write USB Packet
  372. //
  373. typedef struct _USB_PACKET {
  374. //
  375. // owning list this packet belongs on (Read, Write, PacketPool)
  376. //
  377. LIST_ENTRY ListEntry;
  378. //
  379. // owning Device for this read/write
  380. //
  381. PDEVICE_EXTENSION DeviceExtension;
  382. //
  383. // Irp this packet belongs with.
  384. //
  385. PIRP Irp;
  386. //
  387. // Read/Write Timeout Value
  388. //
  389. LARGE_INTEGER Timeout;
  390. //
  391. // Read/Write Timer Object
  392. //
  393. KTIMER TimerObj;
  394. //
  395. // Read/Write TimerDPC Object
  396. //
  397. KDPC TimerDPCObj;
  398. //
  399. // Read/Write DPC Routine
  400. //
  401. PKDEFERRED_ROUTINE TimerDPCRoutine;
  402. //
  403. // Status
  404. //
  405. NTSTATUS Status;
  406. //
  407. // Urb for this write N.B.: size is variable, so leave last
  408. // may not need it becase the Irp has a pointer to the Urb
  409. //
  410. URB Urb;
  411. } USB_PACKET, *PUSB_PACKET;
  412. //
  413. // Note: the SL11 is now pushing faster transfer rates,
  414. // and we were getting USBD_STATUS_BUFFER_OVERRUN with a 1024 USB Read Buffer.
  415. //
  416. // Note: ActiveSync can burst up to 6 IP packets at 1500 bytes each, so we have a Read Buffer
  417. // to accomodate it (9000 bytes). Since all allocs are paged based and any space remaining inside that page is lost,
  418. // then just round up to the next page size i.e., 3 (4k) pages.
  419. // Note: we have hardcoded the page size here for x86 in case this driver ever makes it
  420. // onto another platform (e.g. Alpha).
  421. //
  422. #if !defined (USE_RING_BUFF)
  423. #define USB_READBUFF_SIZE (4096 * 3)
  424. #else
  425. #define USB_READBUFF_SIZE (4096)
  426. #define RINGBUFF_SIZE (USB_READBUFF_SIZE * 3)
  427. #define RINGBUFF_HIGHWATER_MARK (RINGBUFF_SIZE/2)
  428. //
  429. // Ring Buffer to cache USB Reads.
  430. // Reads occur at the head.
  431. // Writes occur at the tail.
  432. // Both Head & Tail move in the same direction.
  433. //
  434. typedef struct _RING_BUFF {
  435. ULONG Size; // in bytes
  436. ULONG CharsInBuff;
  437. PUCHAR pBase;
  438. PUCHAR pHead;
  439. PUCHAR pTail;
  440. } RING_BUFF, *PRING_BUFF;
  441. #endif // USE_RING_BUFF
  442. //
  443. // PipeInfo->MaximumTransferSize
  444. //
  445. #define DEFAULT_PIPE_MAX_TRANSFER_SIZE USB_READBUFF_SIZE
  446. typedef struct _USB_PIPE {
  447. USBD_PIPE_HANDLE hPipe;
  448. ULONG MaxPacketSize;
  449. UCHAR wIndex;
  450. LONG ResetOrAbortPending;
  451. LONG ResetOrAbortFailed;
  452. } USB_PIPE, *PUSB_PIPE;
  453. typedef struct _DEVICE_EXTENSION {
  454. ///////////////////////////////////////////////////////////
  455. //
  456. // WDM Interface
  457. //
  458. //
  459. // Device Extension's global SpinLock.
  460. // No major need for multiple locks since all paths basically need to sync to the same data.
  461. //
  462. KSPIN_LOCK ControlLock;
  463. REMOVE_LOCK RemoveLock;
  464. //
  465. // Back pointer to our DeviceObject
  466. //
  467. PDEVICE_OBJECT DeviceObject;
  468. //
  469. // Device just below us in the device stack
  470. //
  471. PDEVICE_OBJECT NextDevice;
  472. //
  473. // Our Physical Device Object
  474. //
  475. PDEVICE_OBJECT PDO;
  476. //
  477. // Our Device PnP State
  478. //
  479. PNP_STATE PnPState;
  480. //
  481. // is the device removed
  482. //
  483. ULONG DeviceRemoved;
  484. //
  485. // is the device stopped
  486. //
  487. ULONG AcceptingRequests;
  488. //
  489. // open/close state
  490. //
  491. ULONG DeviceOpened;
  492. #ifdef DELAY_RXBUFF
  493. //
  494. // used to emulate RX buffer
  495. //
  496. ULONG StartUsbRead;
  497. #endif
  498. #ifdef POWER
  499. // The CE devices do not yet handle power, let the bus driver manage
  500. //
  501. // SystemWake from devcaps
  502. //
  503. SYSTEM_POWER_STATE SystemWake;
  504. //
  505. // DeviceWake from devcaps
  506. //
  507. DEVICE_POWER_STATE DevicePowerState;
  508. #endif
  509. //
  510. // User visible name \\DosDevices\WCEUSBSHx, where x = 001, 002, ...
  511. // Open as CreateFile("\\\\.\\WCEUSBSH001", ... )
  512. //
  513. CHAR DosDeviceName[DOS_NAME_MAX];
  514. //
  515. // (kernel) Device Name -- e.g., \\Devices\WCEUSBSHx
  516. //
  517. UNICODE_STRING DeviceName;
  518. //
  519. // True if a symbolic link has been
  520. // created to the kernel namspace and should be removed upon deletion.
  521. //
  522. BOOLEAN SymbolicLink;
  523. //
  524. // String where we keep the symbolic link that is returned to us when we
  525. // register our device (IoRegisterDeviceInterface) with the Plug and Play manager.
  526. // The string looks like \\??\\USB#Vid_0547&Pid_2720#Inst_0#{GUID}
  527. //
  528. UNICODE_STRING DeviceClassSymbolicName;
  529. //
  530. // Pointer to our Serial Port Interface
  531. //
  532. SERIAL_PORT_INTERFACE SerialPort;
  533. ///////////////////////////////////////////////////////////
  534. //
  535. // USB Interface ...
  536. //
  537. //
  538. // USB Device descriptor for this device
  539. //
  540. USB_DEVICE_DESCRIPTOR DeviceDescriptor;
  541. //
  542. // USBD configuration
  543. //
  544. USBD_CONFIGURATION_HANDLE ConfigurationHandle;
  545. //
  546. // index of USB interface we are using
  547. //
  548. UCHAR UsbInterfaceNumber;
  549. //
  550. // USBD Pipe Handles
  551. //
  552. USB_PIPE ReadPipe;
  553. USB_PIPE WritePipe;
  554. //
  555. // FIFO size in bytes
  556. // written to PipeInfo->MaximumTransferSize
  557. //
  558. ULONG MaximumTransferSize;
  559. //
  560. // USB Packet (_USB_PACKET) Pool
  561. //
  562. NPAGED_LOOKASIDE_LIST PacketPool;
  563. //
  564. // Pending USB Packet Lists
  565. // We queue packets, not Irps. We allocate a packet from PacketPool,
  566. // then put it on it's R or W pending queue (list). When the I/O completes
  567. // then remove the packet from it's pending list & place back in
  568. // PacketPool. The list is processed FIFO, so the most recent packet is at the tail.
  569. // If a Timer fires then we remove the packet from the pending R/W
  570. // list, cancel the Irp, and put packet back in PacketPool.
  571. // The list is protected by grabbing the extension's global spinlock.
  572. //
  573. LIST_ENTRY PendingReadPackets; // ListHead
  574. ULONG PendingReadCount;
  575. LIST_ENTRY PendingWritePackets; // ListHead
  576. LONG PendingWriteCount;
  577. //
  578. // N-Paged LookAside Lists
  579. //
  580. NPAGED_LOOKASIDE_LIST BulkTransferUrbPool;
  581. NPAGED_LOOKASIDE_LIST PipeRequestUrbPool;
  582. NPAGED_LOOKASIDE_LIST VendorRequestUrbPool;
  583. //
  584. // These events are signalled for waiters (e.g. AbortPipes) when a packet list is empty
  585. //
  586. KEVENT PendingDataOutEvent; // PendingWritePackets drained
  587. ULONG PendingDataOutCount;
  588. //
  589. // Work Item context
  590. //
  591. NPAGED_LOOKASIDE_LIST WorkItemPool;
  592. LIST_ENTRY PendingWorkItems; // ListHead
  593. // remove lock
  594. LONG PendingWorkItemsCount;
  595. KEVENT PendingWorkItemsEvent;
  596. ///////////////////////////////////////////////////
  597. //
  598. // support for buffered reads & polling the USBD stack
  599. //
  600. PIRP UsbReadIrp; // Irp for read requests to USBD
  601. PURB UsbReadUrb; // Urb for read requests to USBD
  602. //
  603. // USB Read state machine
  604. //
  605. ULONG UsbReadState;
  606. //
  607. // Used to signal canceled USB read Irp.
  608. // Note that this could get signalled before the
  609. // PendingDataIn event.
  610. //
  611. KEVENT UsbReadCancelEvent;
  612. //
  613. // This is the USB read buffer which gets sent down the USB stack,
  614. // not a ring-buffer for user.
  615. //
  616. PUCHAR UsbReadBuff; // buffer for read requests
  617. ULONG UsbReadBuffSize;
  618. ULONG UsbReadBuffIndex; // current zero based index into read buffer
  619. ULONG UsbReadBuffChars; // current number of characters buffered
  620. KEVENT PendingDataInEvent; // signals PendingReadCount hit zero
  621. #if defined (USE_RING_BUFF)
  622. //
  623. // Ring Buffer
  624. //
  625. RING_BUFF RingBuff;
  626. #endif
  627. //
  628. // Current Read Irp which is pending from User
  629. //
  630. PIRP UserReadIrp;
  631. //
  632. // Read queue for pending user Read requests
  633. //
  634. LIST_ENTRY UserReadQueue;
  635. //
  636. // This value holds the number of characters desired for a
  637. // particular read. It is initially set by read length in the (UserReadIrp)
  638. // IRP. It is decremented each time more characters are placed
  639. // into the "users" buffer by the code that reads characters
  640. // out of the USB read buffer into the users buffer. If the
  641. // read buffer is exhausted by the read, and the reads buffer
  642. // is given to the isr to fill, this value is becomes meaningless.
  643. //
  644. ULONG NumberNeededForRead;
  645. //
  646. // Timer for timeout on total read request
  647. //
  648. KTIMER ReadRequestTotalTimer;
  649. //
  650. // Timer for timeout on the interval
  651. //
  652. KTIMER ReadRequestIntervalTimer;
  653. //
  654. // Relative time set by the read code which holds the time value
  655. // used for read interval timing. We keep it in the extension
  656. // so that the interval timer dpc routine determine if the
  657. // interval time has passed for the IO.
  658. //
  659. LARGE_INTEGER IntervalTime;
  660. //
  661. // This holds the system time when we last time we had
  662. // checked that we had actually read characters. Used
  663. // for interval timing.
  664. //
  665. LARGE_INTEGER LastReadTime;
  666. //
  667. // This dpc is fired off if the timer for the total timeout
  668. // for the read expires. It will execute a dpc routine that
  669. // will cause the current read to complete.
  670. //
  671. KDPC TotalReadTimeoutDpc;
  672. //
  673. // This dpc is fired off if the timer for the interval timeout
  674. // expires. If no more characters have been read then the
  675. // dpc routine will cause the read to complete. However, if
  676. // more characters have been read then the dpc routine will
  677. // resubmit the timer.
  678. //
  679. KDPC IntervalReadTimeoutDpc;
  680. //
  681. // This holds a count of the number of characters read
  682. // the last time the interval timer dpc fired. It
  683. // is a long (rather than a ulong) since the other read
  684. // completion routines use negative values to indicate
  685. // to the interval timer that it should complete the read
  686. // if the interval timer DPC was lurking in some DPC queue when
  687. // some other way to complete occurs.
  688. //
  689. LONG CountOnLastRead;
  690. //
  691. // This is a count of the number of characters read by the
  692. // isr routine. It is *ONLY* written at isr level. We can
  693. // read it at dispatch level.
  694. //
  695. ULONG ReadByIsr;
  696. ///////////////////////////////////////////////////
  697. //
  698. // support for interrupt endpoints
  699. //
  700. USB_PIPE IntPipe;
  701. ULONG IntState; // state machine for starting reads from completion routine
  702. PIRP IntIrp; // Irp for Int reads
  703. PURB IntUrb; // Urb for Int Irp
  704. // remove lock
  705. ULONG PendingIntCount;
  706. KEVENT PendingIntEvent;
  707. KEVENT IntCancelEvent;
  708. PUCHAR IntBuff; // buffer for notifications
  709. // Value in 100 nanosec units to timeout USB reads
  710. // Used in conjunction with the INT endpoint
  711. LARGE_INTEGER IntReadTimeOut;
  712. #if DBG
  713. LARGE_INTEGER LastIntReadTime;
  714. #endif
  715. //
  716. // device error counters
  717. //
  718. ULONG ReadDeviceErrors;
  719. ULONG WriteDeviceErrors;
  720. ULONG IntDeviceErrors;
  721. ULONG EP0DeviceErrors;
  722. //
  723. // perf counters ~ SERIALPERF_STATS.
  724. //
  725. ULONG TtlWriteRequests;
  726. ULONG TtlWriteBytes; // TTL bytes written for user
  727. ULONG TtlReadRequests;
  728. ULONG TtlReadBytes; // TTL bytes read for user
  729. ULONG TtlUSBReadRequests;
  730. ULONG TtlUSBReadBytes; // TTL bytes indicatid up from USB
  731. ULONG TtlUSBReadBuffOverruns; // TTL USB read buffer overruns
  732. #if defined (USE_RING_BUFF)
  733. ULONG TtlRingBuffOverruns; // TTL ring buffer overruns
  734. #endif
  735. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  736. #define FIXUP_RAW_IRP( _pirp, _deviceObject ) \
  737. { \
  738. PIO_STACK_LOCATION _irpSp; \
  739. ASSERT( _pirp ); \
  740. ASSERT( _deviceObject ); \
  741. _pirp->CurrentLocation--; \
  742. _irpSp = IoGetNextIrpStackLocation( _pirp ); \
  743. ASSERT( _irpSp ); \
  744. _pirp->Tail.Overlay.CurrentStackLocation = _irpSp; \
  745. _irpSp->MajorFunction = IRP_MJ_READ; \
  746. _irpSp->DeviceObject = _deviceObject; \
  747. _irpSp->Parameters.Others.Argument1 = 0; \
  748. _irpSp->Parameters.Others.Argument2 = 0; \
  749. _irpSp->Parameters.Others.Argument3 = 0; \
  750. _irpSp->Parameters.Others.Argument4 = 0; \
  751. }
  752. /***************************************************
  753. P R O T O S
  754. ***************************************************/
  755. //
  756. // common.c
  757. //
  758. NTSTATUS
  759. QueryRegistryParameters(
  760. IN PUNICODE_STRING RegistryPath
  761. );
  762. VOID
  763. ReleaseSlot(
  764. IN LONG Slot
  765. );
  766. NTSTATUS
  767. AcquireSlot(
  768. OUT PULONG PSlot
  769. );
  770. NTSTATUS
  771. CreateDevObjAndSymLink(
  772. IN PDRIVER_OBJECT PDrvObj,
  773. IN PDEVICE_OBJECT PPDO,
  774. IN PDEVICE_OBJECT *PpDevObj,
  775. IN PCHAR PDevName
  776. );
  777. NTSTATUS
  778. DeleteDevObjAndSymLink(
  779. IN PDEVICE_OBJECT DeviceObject
  780. );
  781. VOID
  782. SetPVoidLocked(
  783. IN OUT PVOID *PDest,
  784. IN OUT PVOID Src,
  785. IN PKSPIN_LOCK PSpinLock
  786. );
  787. typedef
  788. VOID
  789. (*PWCE_WORKER_THREAD_ROUTINE)(
  790. IN PWCE_WORK_ITEM Context
  791. );
  792. NTSTATUS
  793. QueueWorkItem(
  794. IN PDEVICE_OBJECT PDevObj,
  795. IN PWCE_WORKER_THREAD_ROUTINE WorkerRoutine,
  796. IN PVOID Context,
  797. IN ULONG Flags
  798. );
  799. VOID
  800. DequeueWorkItem(
  801. IN PDEVICE_OBJECT PDevObj,
  802. IN PWCE_WORK_ITEM PWorkItem
  803. );
  804. NTSTATUS
  805. WaitForPendingItem(
  806. IN PDEVICE_OBJECT PDevObj,
  807. IN PKEVENT PPendingEvent,
  808. IN PULONG PPendingCount
  809. );
  810. BOOLEAN
  811. CanAcceptIoRequests(
  812. IN PDEVICE_OBJECT DeviceObject,
  813. IN BOOLEAN AcquireLock,
  814. IN BOOLEAN CheckOpened
  815. );
  816. BOOLEAN
  817. IsWin9x(
  818. VOID
  819. );
  820. VOID
  821. LogError(
  822. IN PDRIVER_OBJECT DriverObject,
  823. IN PDEVICE_OBJECT DeviceObject OPTIONAL,
  824. IN ULONG SequenceNumber,
  825. IN UCHAR MajorFunctionCode,
  826. IN UCHAR RetryCount,
  827. IN ULONG UniqueErrorValue,
  828. IN NTSTATUS FinalStatus,
  829. IN NTSTATUS SpecificIOStatus,
  830. IN ULONG LengthOfInsert1,
  831. IN PWCHAR Insert1,
  832. IN ULONG LengthOfInsert2,
  833. IN PWCHAR Insert2
  834. );
  835. #if DBG
  836. PCHAR
  837. PnPMinorFunctionString (
  838. UCHAR MinorFunction
  839. );
  840. #endif
  841. //
  842. // comport.c
  843. //
  844. LONG
  845. GetFreeComPortNumber(
  846. VOID
  847. );
  848. VOID
  849. ReleaseCOMPort(
  850. LONG comPortNumber
  851. );
  852. NTSTATUS
  853. DoSerialPortNaming(
  854. IN PDEVICE_EXTENSION PDevExt,
  855. IN LONG ComPortNumber
  856. );
  857. VOID
  858. UndoSerialPortNaming(
  859. IN PDEVICE_EXTENSION PDevExt
  860. );
  861. //
  862. // int.c
  863. //
  864. NTSTATUS
  865. AllocUsbInterrupt(
  866. IN PDEVICE_EXTENSION DeviceExtension
  867. );
  868. NTSTATUS
  869. UsbInterruptRead(
  870. IN PDEVICE_EXTENSION DeviceExtension
  871. );
  872. NTSTATUS
  873. CancelUsbInterruptIrp(
  874. IN PDEVICE_OBJECT PDevObj
  875. );
  876. //
  877. // pnp.c
  878. //
  879. NTSTATUS
  880. Pnp(
  881. IN PDEVICE_OBJECT PDevObj,
  882. IN PIRP PIrp
  883. );
  884. NTSTATUS
  885. Power(
  886. IN PDEVICE_OBJECT DeviceObject,
  887. IN PIRP Irp
  888. );
  889. NTSTATUS
  890. StopIo(
  891. IN PDEVICE_OBJECT DeviceObject
  892. );
  893. NTSTATUS
  894. CleanUpPacketList(
  895. IN PDEVICE_OBJECT DeviceObject,
  896. IN PLIST_ENTRY PListHead,
  897. IN PKEVENT PEvent
  898. );
  899. //
  900. // read.c
  901. //
  902. NTSTATUS
  903. AllocUsbRead(
  904. IN PDEVICE_EXTENSION PDevExt
  905. );
  906. NTSTATUS
  907. UsbRead(
  908. IN PDEVICE_EXTENSION PDevExt,
  909. IN BOOLEAN UseTimeout
  910. );
  911. NTSTATUS
  912. CancelUsbReadIrp(
  913. IN PDEVICE_OBJECT PDevObj
  914. );
  915. NTSTATUS
  916. Read(
  917. IN PDEVICE_OBJECT PDevObj,
  918. IN PIRP PIrp
  919. );
  920. VOID
  921. ReadTimeout(
  922. IN PKDPC PDpc,
  923. IN PVOID DeferredContext,
  924. IN PVOID SystemContext1,
  925. IN PVOID SystemContext2
  926. );
  927. VOID
  928. IntervalReadTimeout(
  929. IN PKDPC PDpc,
  930. IN PVOID DeferredContext,
  931. IN PVOID SystemContext1,
  932. IN PVOID SystemContext2
  933. );
  934. //
  935. // serioctl.c
  936. //
  937. NTSTATUS
  938. SerialIoctl(
  939. PDEVICE_OBJECT PDevObj,
  940. PIRP PIrp
  941. );
  942. NTSTATUS
  943. SerialResetDevice(
  944. IN PDEVICE_EXTENSION PDevExt,
  945. IN PIRP Irp,
  946. IN BOOLEAN ClearDTR
  947. );
  948. VOID
  949. ProcessSerialWaits(
  950. IN PDEVICE_EXTENSION PDevExt
  951. );
  952. NTSTATUS
  953. SerialPurgeRxClear(
  954. IN PDEVICE_OBJECT PDevObj,
  955. IN BOOLEAN CancelRead
  956. );
  957. //
  958. // usbio.c
  959. //
  960. NTSTATUS
  961. UsbSubmitSyncUrb(
  962. IN PDEVICE_OBJECT PDevObj,
  963. IN PURB PUrb,
  964. IN BOOLEAN Configuration,
  965. IN LONG TimeOut
  966. );
  967. NTSTATUS
  968. UsbClassVendorCommand(
  969. IN PDEVICE_OBJECT PDevObj,
  970. IN UCHAR Request,
  971. IN USHORT Value,
  972. IN USHORT Index,
  973. IN PVOID Buffer,
  974. IN OUT PULONG BufferLen,
  975. IN BOOLEAN Read,
  976. IN ULONG Class
  977. );
  978. NTSTATUS
  979. UsbReadWritePacket(
  980. IN PDEVICE_EXTENSION PDevExt,
  981. IN PIRP PIrp,
  982. IN PIO_COMPLETION_ROUTINE CompletionRoutine,
  983. IN LARGE_INTEGER Timeout,
  984. IN PKDEFERRED_ROUTINE TimeoutRoutine,
  985. IN BOOLEAN Read
  986. );
  987. VOID
  988. UsbBuildTransferUrb(
  989. PURB Urb,
  990. PUCHAR Buffer,
  991. ULONG Length,
  992. IN USBD_PIPE_HANDLE PipeHandle,
  993. IN BOOLEAN Read
  994. );
  995. #define RESET TRUE
  996. #define ABORT FALSE
  997. NTSTATUS
  998. UsbResetOrAbortPipe(
  999. IN PDEVICE_OBJECT PDevObj,
  1000. IN PUSB_PIPE PPipe,
  1001. IN BOOLEAN Reset
  1002. );
  1003. VOID
  1004. UsbResetOrAbortPipeWorkItem(
  1005. IN PWCE_WORK_ITEM PWorkItem
  1006. );
  1007. //
  1008. // usbutils.c
  1009. //
  1010. NTSTATUS
  1011. UsbGetDeviceDescriptor(
  1012. IN PDEVICE_OBJECT PDevObj
  1013. );
  1014. NTSTATUS
  1015. UsbConfigureDevice(
  1016. IN PDEVICE_OBJECT PDevObj
  1017. );
  1018. //
  1019. // utils.c
  1020. //
  1021. typedef
  1022. NTSTATUS
  1023. (*PSTART_ROUTINE)( // StartRoutine
  1024. IN PDEVICE_EXTENSION
  1025. );
  1026. typedef
  1027. VOID
  1028. (*PGET_NEXT_ROUTINE) ( // GetNextIrpRoutine
  1029. IN PIRP *CurrentOpIrp,
  1030. IN PLIST_ENTRY QueueToProcess,
  1031. OUT PIRP *NewIrp,
  1032. IN BOOLEAN CompleteCurrent,
  1033. PDEVICE_EXTENSION Extension
  1034. );
  1035. VOID
  1036. TryToCompleteCurrentIrp(
  1037. IN PDEVICE_EXTENSION PDevExt,
  1038. IN NTSTATUS StatusToUse,
  1039. IN PIRP *PpCurrentOpIrp,
  1040. IN PLIST_ENTRY PQueue OPTIONAL,
  1041. IN PKTIMER PIntervalTimer OPTIONAL,
  1042. IN PKTIMER PTotalTimer OPTIONAL,
  1043. IN PSTART_ROUTINE Starter OPTIONAL,
  1044. IN PGET_NEXT_ROUTINE PGetNextIrp OPTIONAL,
  1045. IN LONG RefType,
  1046. IN BOOLEAN Complete,
  1047. IN KIRQL IrqlForRelease
  1048. );
  1049. VOID
  1050. RecycleIrp(
  1051. IN PDEVICE_OBJECT PDevOjb,
  1052. IN PIRP PIrp
  1053. );
  1054. NTSTATUS
  1055. ManuallyCancelIrp(
  1056. IN PDEVICE_OBJECT PDevObj,
  1057. IN PIRP PIrp
  1058. );
  1059. VOID
  1060. CalculateTimeout(
  1061. IN OUT PLARGE_INTEGER PTimeOut,
  1062. IN ULONG Length,
  1063. IN ULONG Multiplier,
  1064. IN ULONG Constant
  1065. );
  1066. //
  1067. // wceusbsh.c
  1068. //
  1069. NTSTATUS
  1070. DriverEntry(
  1071. IN PDRIVER_OBJECT PDrvObj,
  1072. IN PUNICODE_STRING PRegistryPath
  1073. );
  1074. NTSTATUS
  1075. AddDevice(
  1076. IN PDRIVER_OBJECT PDrvObj,
  1077. IN PDEVICE_OBJECT PPDO
  1078. );
  1079. VOID
  1080. KillAllPendingUserReads(
  1081. IN PDEVICE_OBJECT PDevObj,
  1082. IN PLIST_ENTRY PQueueToClean,
  1083. IN PIRP *PpCurrentOpIrp
  1084. );
  1085. VOID
  1086. UsbFreeReadBuffer(
  1087. IN PDEVICE_OBJECT PDevObj
  1088. );
  1089. //
  1090. // write.c
  1091. //
  1092. NTSTATUS
  1093. Write(
  1094. IN PDEVICE_OBJECT PDevObj,
  1095. PIRP PIrp
  1096. );
  1097. #endif // _WCEUSBSH_H_
  1098. // EOF