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.

979 lines
32 KiB

  1. /****************************************************************************
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. USBSER.H
  5. Abstract:
  6. This header file is used for the Legacy USB Modem Driver
  7. Environment:
  8. Kernel mode & user mode
  9. Notes:
  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13. PURPOSE.
  14. Copyright (c) 1998 Microsoft Corporation. All Rights Reserved.
  15. Revision History:
  16. 12/23/97 : created
  17. Author:
  18. Tom Green
  19. ****************************************************************************/
  20. #ifndef __USBSER_H__
  21. #define __USBSER_H__
  22. #ifdef DRIVER
  23. // Various definitions
  24. #define NAME_MAX 80
  25. #define MILLISECONDS_TIMEOUT(x) ((ULONGLONG) ((-x) * 10000))
  26. #define NOTIFICATION_BUFF_SIZE 10
  27. #define MAXIMUM_TRANSFER_SIZE (8 * 1024)
  28. #define RX_BUFF_SIZE (16 * 1024)
  29. #define USB_RX_BUFF_SIZE (RX_BUFF_SIZE / 4)
  30. #define LOW_WATER_MARK (USB_RX_BUFF_SIZE * 3)
  31. #define DEVICE_STATE_UNKNOWN 0x0000
  32. #define DEVICE_STATE_STARTED 0x0001
  33. #define DEVICE_STATE_STOPPED 0x0002
  34. #define DEVICE_STATE_REMOVED 0x0003
  35. // device capabilities
  36. #define DEVICE_CAP_VERSION 0x0001
  37. #define DEVICE_CAP_UNUSED_PARAM ((ULONG) -1)
  38. // these describe bits in the modem status register
  39. #define SERIAL_MSR_DCTS 0x0001
  40. #define SERIAL_MSR_DDSR 0x0002
  41. #define SERIAL_MSR_TERI 0x0004
  42. #define SERIAL_MSR_DDCD 0x0008
  43. #define SERIAL_MSR_CTS 0x0010
  44. #define SERIAL_MSR_DSR 0x0020
  45. #define SERIAL_MSR_RI 0x0040
  46. #define SERIAL_MSR_DCD 0x0080
  47. //
  48. // These masks define access to the line status register. The line
  49. // status register contains information about the status of data
  50. // transfer. The first five bits deal with receive data and the
  51. // last two bits deal with transmission. An interrupt is generated
  52. // whenever bits 1 through 4 in this register are set.
  53. //
  54. //
  55. // This bit is the data ready indicator. It is set to indicate that
  56. // a complete character has been received. This bit is cleared whenever
  57. // the receive buffer register has been read.
  58. //
  59. #define SERIAL_LSR_DR 0x01
  60. //
  61. // This is the overrun indicator. It is set to indicate that the receive
  62. // buffer register was not read befor a new character was transferred
  63. // into the buffer. This bit is cleared when this register is read.
  64. //
  65. #define SERIAL_LSR_OE 0x02
  66. //
  67. // This is the parity error indicator. It is set whenever the hardware
  68. // detects that the incoming serial data unit does not have the correct
  69. // parity as defined by the parity select in the line control register.
  70. // This bit is cleared by reading this register.
  71. //
  72. #define SERIAL_LSR_PE 0x04
  73. //
  74. // This is the framing error indicator. It is set whenever the hardware
  75. // detects that the incoming serial data unit does not have a valid
  76. // stop bit. This bit is cleared by reading this register.
  77. //
  78. #define SERIAL_LSR_FE 0x08
  79. //
  80. // This is the break interrupt indicator. It is set whenever the data
  81. // line is held to logic 0 for more than the amount of time it takes
  82. // to send one serial data unit. This bit is cleared whenever the
  83. // this register is read.
  84. //
  85. #define SERIAL_LSR_BI 0x10
  86. //
  87. // This is the transmit holding register empty indicator. It is set
  88. // to indicate that the hardware is ready to accept another character
  89. // for transmission. This bit is cleared whenever a character is
  90. // written to the transmit holding register.
  91. //
  92. #define SERIAL_LSR_THRE 0x20
  93. //
  94. // This bit is the transmitter empty indicator. It is set whenever the
  95. // transmit holding buffer is empty and the transmit shift register
  96. // (a non-software accessable register that is used to actually put
  97. // the data out on the wire) is empty. Basically this means that all
  98. // data has been sent. It is cleared whenever the transmit holding or
  99. // the shift registers contain data.
  100. //
  101. #define SERIAL_LSR_TEMT 0x40
  102. //
  103. // This bit indicates that there is at least one error in the fifo.
  104. // The bit will not be turned off until there are no more errors
  105. // in the fifo.
  106. //
  107. #define SERIAL_LSR_FIFOERR 0x80
  108. //
  109. // Serial naming values
  110. //
  111. //
  112. // Maximum length for symbolic link
  113. //
  114. #define SYMBOLIC_NAME_LENGTH 128
  115. //
  116. // This define gives the default Object directory
  117. // that we should use to insert the symbolic links
  118. // between the NT device name and namespace used by
  119. // that object directory.
  120. #define DEFAULT_DIRECTORY L"DosDevices"
  121. //
  122. // Where in the DeviceMap section of the registry serial port entries
  123. // should appear
  124. //
  125. #define SERIAL_DEVICE_MAP L"SERIALCOMM"
  126. // performance info for modem driver
  127. typedef struct _PERF_INFO
  128. {
  129. BOOLEAN PerfModeEnabled;
  130. ULONG BytesPerSecond;
  131. } PERF_INFO, *PPERF_INFO;
  132. #define SANITY_CHECK ((ULONG) 'ENAS')
  133. #else
  134. #include <winioctl.h>
  135. #endif
  136. // IOCTL info, needs to be visible for application
  137. #define USBSER_IOCTL_INDEX 0x0800
  138. #define GET_DRIVER_LOG CTL_CODE(FILE_DEVICE_UNKNOWN, \
  139. USBSER_IOCTL_INDEX + 0, \
  140. METHOD_BUFFERED, \
  141. FILE_ANY_ACCESS)
  142. #define GET_IRP_HIST CTL_CODE(FILE_DEVICE_UNKNOWN, \
  143. USBSER_IOCTL_INDEX + 1, \
  144. METHOD_BUFFERED, \
  145. FILE_ANY_ACCESS)
  146. #define GET_PATH_HIST CTL_CODE(FILE_DEVICE_UNKNOWN, \
  147. USBSER_IOCTL_INDEX + 2, \
  148. METHOD_BUFFERED, \
  149. FILE_ANY_ACCESS)
  150. #define GET_ERROR_LOG CTL_CODE(FILE_DEVICE_UNKNOWN, \
  151. USBSER_IOCTL_INDEX + 3, \
  152. METHOD_BUFFERED, \
  153. FILE_ANY_ACCESS)
  154. #define GET_ATTACHED_DEVICES CTL_CODE(FILE_DEVICE_UNKNOWN, \
  155. USBSER_IOCTL_INDEX + 4, \
  156. METHOD_BUFFERED, \
  157. FILE_ANY_ACCESS)
  158. #define SET_IRP_HIST_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, \
  159. USBSER_IOCTL_INDEX + 5, \
  160. METHOD_BUFFERED, \
  161. FILE_ANY_ACCESS)
  162. #define SET_PATH_HIST_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, \
  163. USBSER_IOCTL_INDEX + 6, \
  164. METHOD_BUFFERED, \
  165. FILE_ANY_ACCESS)
  166. #define SET_ERROR_LOG_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, \
  167. USBSER_IOCTL_INDEX + 7, \
  168. METHOD_BUFFERED, \
  169. FILE_ANY_ACCESS)
  170. #define GET_DRIVER_INFO CTL_CODE(FILE_DEVICE_UNKNOWN, \
  171. USBSER_IOCTL_INDEX + 8, \
  172. METHOD_BUFFERED, \
  173. FILE_ANY_ACCESS)
  174. #define ENABLE_PERF_TIMING CTL_CODE(FILE_DEVICE_UNKNOWN, \
  175. USBSER_IOCTL_INDEX + 9, \
  176. METHOD_BUFFERED, \
  177. FILE_ANY_ACCESS)
  178. #define DISABLE_PERF_TIMING CTL_CODE(FILE_DEVICE_UNKNOWN, \
  179. USBSER_IOCTL_INDEX + 10, \
  180. METHOD_BUFFERED, \
  181. FILE_ANY_ACCESS)
  182. #define GET_PERF_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, \
  183. USBSER_IOCTL_INDEX + 11, \
  184. METHOD_BUFFERED, \
  185. FILE_ANY_ACCESS)
  186. #define SET_DEBUG_TRACE_LEVEL CTL_CODE(FILE_DEVICE_UNKNOWN, \
  187. USBSER_IOCTL_INDEX + 12, \
  188. METHOD_BUFFERED, \
  189. FILE_ANY_ACCESS)
  190. #ifdef DRIVER
  191. // info about the driver, initialized in DriverEntry routine
  192. PCHAR DriverName;
  193. PCHAR DriverVersion;
  194. ULONG Usbser_Debug_Trace_Level;
  195. ULONG UsbSerSerialDebugLevel;
  196. KSPIN_LOCK GlobalSpinLock;
  197. //
  198. // Count of how many times the paged code has been locked
  199. //
  200. ULONG PAGEUSBSER_Count;
  201. //
  202. // Handle to the locked paged code
  203. //
  204. PVOID PAGEUSBSER_Handle;
  205. //
  206. // Pointer to funcion
  207. //
  208. PVOID PAGEUSBSER_Function;
  209. typedef struct _READ_CONTEXT
  210. {
  211. PURB Urb;
  212. PDEVICE_OBJECT DeviceObject;
  213. PIRP Irp;
  214. } READ_CONTEXT, *PREAD_CONTEXT;
  215. // device extension for driver instance, used to store needed data
  216. typedef struct _DEVICE_EXTENSION
  217. {
  218. PDEVICE_OBJECT PhysDeviceObject; // physical device object
  219. PDEVICE_OBJECT StackDeviceObject; // stack device object
  220. CHAR LinkName[NAME_MAX]; // string name of symbolic link
  221. PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; // device descriptor for device
  222. USBD_CONFIGURATION_HANDLE ConfigurationHandle; // configuration of USB device
  223. USBD_PIPE_HANDLE DataInPipe; // pipe for reading data
  224. USBD_PIPE_HANDLE DataOutPipe; // pipe for writing data
  225. USBD_PIPE_HANDLE NotificationPipe; // pipe for getting notifications from the device
  226. ULONG IRPCount; // number of IRPs that passed through this device object
  227. LARGE_INTEGER ByteCount; // number of bytes of data passed through this device object
  228. ULONG Instance; // instance of device
  229. BOOLEAN IsDevice; // is this a device or "global" device object
  230. BOOLEAN PerfTimerEnabled; // enable perf timing
  231. LARGE_INTEGER BytesXfered; // byte count for perf
  232. LARGE_INTEGER ElapsedTime; // elapsed time for perf
  233. LARGE_INTEGER TimerStart; // timer start for perf
  234. DEVICE_CAPABILITIES DeviceCapabilities;
  235. ULONG PowerDownLevel;
  236. DEVICE_POWER_STATE CurrentDevicePowerState;
  237. PIRP PowerIrp;
  238. BOOLEAN SelfPowerIrp;
  239. KEVENT SelfRequestedPowerIrpEvent;
  240. //
  241. // Nota Bene: Locking hierarchy is acquire ControlLock *then*
  242. // acquire CancelSpinLock. We don't want to stall other
  243. // drivers waiting for the cancel spin lock
  244. //
  245. KSPIN_LOCK ControlLock; // protect extension
  246. ULONG CurrentBaud; // current baud rate
  247. SERIAL_TIMEOUTS Timeouts; // timeout controls for device
  248. ULONG IsrWaitMask; // determine if occurence of events should be noticed
  249. SERIAL_LINE_CONTROL LineControl; // current value of line control reg
  250. SERIAL_HANDFLOW HandFlow; // Handshake and control flow settings
  251. SERIALPERF_STATS PerfStats; // performance stats
  252. SERIAL_CHARS SpecialChars; // special characters
  253. ULONG DTRRTSState; // keep track of the current state of these lines
  254. ULONG SupportedBauds; // "named" baud rates for device
  255. UCHAR EscapeChar; // for LsrmstInsert IOCTL
  256. USHORT FakeModemStatus; // looks like status register on modem
  257. USHORT FakeLineStatus; // looks like line status register
  258. USHORT RxMaxPacketSize; // max packet size fo the in data pipe
  259. PIRP NotifyIrp; // Irp for notify reads
  260. PURB NotifyUrb; // Urb for notify Irp
  261. PIRP ReadIrp; // Irp for read requests
  262. PURB ReadUrb; // Urb for read requests
  263. KEVENT ReadEvent; // used to cancel a read Irp
  264. ULONG CharsInReadBuff; // current number of characters buffered
  265. ULONG CurrentReadBuffPtr; // pointer into read buffer
  266. BOOLEAN AcceptingRequests; // is the device stopped or removed
  267. PIRP CurrentMaskIrp; // current set or wait mask Irp
  268. ULONG HistoryMask; // store mask events here
  269. ULONG OpenCnt; // number of create calls on device
  270. PUCHAR NotificationBuff; // buffer for notifications
  271. PUCHAR ReadBuff; // circular buffer for read requests
  272. PUCHAR USBReadBuff; // buffer to get data from device
  273. UCHAR CommInterface; // index of communications interface
  274. ULONG RxQueueSize; // fake read buffer size
  275. ULONG ReadInterlock; // state machine for starting reads from completion routine
  276. BOOLEAN ReadInProgress;
  277. ULONG DeviceState; // current state of enumeration
  278. //
  279. // True if a symbolic link has been created and should be
  280. // removed upon deletion.
  281. //
  282. BOOLEAN CreatedSymbolicLink;
  283. //
  284. // Symbolic link name -- e.g., \\DosDevices\COMx
  285. //
  286. UNICODE_STRING SymbolicLinkName;
  287. //
  288. // Dos Name -- e.g., COMx
  289. //
  290. UNICODE_STRING DosName;
  291. //
  292. // Device Name -- e.g., \\Devices\UsbSerx
  293. //
  294. UNICODE_STRING DeviceName;
  295. //
  296. // Current Read Irp which is pending
  297. //
  298. PIRP CurrentReadIrp;
  299. //
  300. // Current Write Irp which is pending
  301. //
  302. PIRP CurrentWriteIrp;
  303. //
  304. // Read queue
  305. //
  306. LIST_ENTRY ReadQueue;
  307. //
  308. // This value holds the number of characters desired for a
  309. // particular read. It is initially set by read length in the
  310. // IRP. It is decremented each time more characters are placed
  311. // into the "users" buffer buy the code that reads characters
  312. // out of the typeahead buffer into the users buffer. If the
  313. // typeahead buffer is exhausted by the read, and the reads buffer
  314. // is given to the isr to fill, this value is becomes meaningless.
  315. //
  316. ULONG NumberNeededForRead;
  317. //
  318. // Timer for timeout on total read request
  319. //
  320. KTIMER ReadRequestTotalTimer;
  321. //
  322. // Timer for timeout on the interval
  323. //
  324. KTIMER ReadRequestIntervalTimer;
  325. //
  326. // This is the kernal timer structure used to handle
  327. // total time request timing.
  328. //
  329. KTIMER WriteRequestTotalTimer;
  330. //
  331. // This value is set by the read code to hold the time value
  332. // used for read interval timing. We keep it in the extension
  333. // so that the interval timer dpc routine determine if the
  334. // interval time has passed for the IO.
  335. //
  336. LARGE_INTEGER IntervalTime;
  337. //
  338. // This holds the value that we use to determine if we should use
  339. // the long interval delay or the short interval delay.
  340. //
  341. LARGE_INTEGER CutOverAmount;
  342. //
  343. // This holds the system time when we last time we had
  344. // checked that we had actually read characters. Used
  345. // for interval timing.
  346. //
  347. LARGE_INTEGER LastReadTime;
  348. //
  349. // This points the the delta time that we should use to
  350. // delay for interval timing.
  351. //
  352. PLARGE_INTEGER IntervalTimeToUse;
  353. //
  354. // These two values hold the "constant" time that we should use
  355. // to delay for the read interval time.
  356. //
  357. LARGE_INTEGER ShortIntervalAmount;
  358. LARGE_INTEGER LongIntervalAmount;
  359. //
  360. // This dpc is fired off if the timer for the total timeout
  361. // for the read expires. It will execute a dpc routine that
  362. // will cause the current read to complete.
  363. //
  364. //
  365. KDPC TotalReadTimeoutDpc;
  366. //
  367. // This dpc is fired off if the timer for the interval timeout
  368. // expires. If no more characters have been read then the
  369. // dpc routine will cause the read to complete. However, if
  370. // more characters have been read then the dpc routine will
  371. // resubmit the timer.
  372. //
  373. KDPC IntervalReadTimeoutDpc;
  374. //
  375. // This dpc is fired off if the timer for the total timeout
  376. // for the write expires. It will execute a dpc routine that
  377. // will cause the current write to complete.
  378. //
  379. //
  380. KDPC TotalWriteTimeoutDpc;
  381. //
  382. // This keeps a total of the number of characters that
  383. // are in all of the "write" irps that the driver knows
  384. // about. It is only accessed with the cancel spinlock
  385. // held.
  386. //
  387. ULONG TotalCharsQueued;
  388. //
  389. // This holds a count of the number of characters read
  390. // the last time the interval timer dpc fired. It
  391. // is a long (rather than a ulong) since the other read
  392. // completion routines use negative values to indicate
  393. // to the interval timer that it should complete the read
  394. // if the interval timer DPC was lurking in some DPC queue when
  395. // some other way to complete occurs.
  396. //
  397. LONG CountOnLastRead;
  398. //
  399. // This is a count of the number of characters read by the
  400. // isr routine. It is *ONLY* written at isr level. We can
  401. // read it at dispatch level.
  402. //
  403. ULONG ReadByIsr;
  404. //
  405. // If non-NULL, means this write timed out and we should correct the
  406. // return value in the completion routine.
  407. //
  408. PIRP TimedOutWrite;
  409. //
  410. // If TRUE, that means we need to insert LSRMST
  411. //
  412. BOOLEAN EscapeSeen;
  413. //
  414. // Holds data that needs to be pushed such as LSRMST data
  415. //
  416. LIST_ENTRY ImmediateReadQueue;
  417. //
  418. // Pending wait-wake irp
  419. //
  420. PIRP PendingWakeIrp;
  421. //
  422. // True if WaitWake needs to be sent down before a powerdown
  423. //
  424. BOOLEAN SendWaitWake;
  425. //
  426. // SystemWake from devcaps
  427. //
  428. SYSTEM_POWER_STATE SystemWake;
  429. //
  430. // DeviceWake from devcaps
  431. //
  432. DEVICE_POWER_STATE DeviceWake;
  433. //
  434. // Count of Writes pending in the lower USB levels
  435. //
  436. ULONG PendingWriteCount;
  437. //
  438. // Counters and events to drain USB requests
  439. //
  440. KEVENT PendingDataInEvent;
  441. KEVENT PendingDataOutEvent;
  442. KEVENT PendingNotifyEvent;
  443. KEVENT PendingFlushEvent;
  444. ULONG PendingDataInCount;
  445. ULONG PendingDataOutCount;
  446. ULONG PendingNotifyCount;
  447. ULONG SanityCheck;
  448. // selective suspend support
  449. PIRP PendingIdleIrp;
  450. PUSB_IDLE_CALLBACK_INFO IdleCallbackInfo;
  451. PIO_WORKITEM IoWorkItem;
  452. IO_STATUS_BLOCK StatusBlock;
  453. #ifdef SPINLOCK_TRACKING
  454. LONG CancelSpinLockCount;
  455. LONG SpinLockCount;
  456. LONG WaitingOnCancelSpinLock;
  457. LONG WaitingOnSpinLock;
  458. #endif
  459. #ifdef WMI_SUPPORT
  460. //
  461. // WMI Information
  462. //
  463. WMILIB_CONTEXT WmiLibInfo;
  464. //
  465. // Name to use as WMI identifier
  466. //
  467. UNICODE_STRING WmiIdentifier;
  468. #endif
  469. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  470. typedef struct _USBSER_IMMEDIATE_READ_PACKET {
  471. //
  472. // List of packets
  473. //
  474. LIST_ENTRY ImmediateReadQueue;
  475. //
  476. // Length of data
  477. //
  478. ULONG BufferLen;
  479. //
  480. // Buffer itself, leave last in struct
  481. //
  482. UCHAR Buffer;
  483. } USBSER_IMMEDIATE_READ_PACKET, *PUSBSER_IMMEDIATE_READ_PACKET;
  484. typedef struct _USBSER_WRITE_PACKET {
  485. //
  486. // Device extension for this write
  487. //
  488. PDEVICE_EXTENSION DeviceExtension;
  489. //
  490. // Irp this packet belongs with
  491. //
  492. PIRP Irp;
  493. //
  494. // Write timer
  495. //
  496. KTIMER WriteTimer;
  497. //
  498. // Timeout value
  499. //
  500. LARGE_INTEGER WriteTimeout;
  501. //
  502. // TimerDPC
  503. //
  504. KDPC TimerDPC;
  505. //
  506. // Status
  507. //
  508. NTSTATUS Status;
  509. //
  510. // Urb for this write N.B.: size is variable, so leave last
  511. //
  512. URB Urb;
  513. } USBSER_WRITE_PACKET, *PUSBSER_WRITE_PACKET;
  514. typedef NTSTATUS (*PUSBSER_START_ROUTINE)(IN PDEVICE_EXTENSION);
  515. typedef VOID (*PUSBSER_GET_NEXT_ROUTINE) (IN PIRP *CurrentOpIrp,
  516. IN PLIST_ENTRY QueueToProcess,
  517. OUT PIRP *NewIrp,
  518. IN BOOLEAN CompleteCurrent,
  519. PDEVICE_EXTENSION Extension);
  520. NTSTATUS
  521. DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
  522. NTSTATUS
  523. UsbSer_Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  524. NTSTATUS
  525. UsbSer_Create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  526. NTSTATUS
  527. UsbSer_Close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  528. NTSTATUS
  529. UsbSer_Write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  530. NTSTATUS
  531. UsbSer_Read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  532. VOID
  533. UsbSer_Unload(IN PDRIVER_OBJECT DriverObject);
  534. NTSTATUS
  535. UsbSer_PnPAddDevice(IN PDRIVER_OBJECT DriverObject,
  536. IN PDEVICE_OBJECT PhysicalDeviceObject);
  537. NTSTATUS
  538. UsbSer_PnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  539. NTSTATUS
  540. UsbSer_Power(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  541. NTSTATUS
  542. UsbSer_SystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  543. NTSTATUS
  544. UsbSer_Cleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  545. NTSTATUS
  546. UsbSerMajorNotSupported(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  547. NTSTATUS
  548. UsbSerStartOrQueue(IN PDEVICE_EXTENSION PDevExt, IN PIRP PIrp,
  549. IN PLIST_ENTRY PQueue, IN PIRP *PPCurrentIrp,
  550. IN PUSBSER_START_ROUTINE Starter);
  551. VOID
  552. UsbSerCancelQueued(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp);
  553. NTSTATUS
  554. UsbSerStartRead(IN PDEVICE_EXTENSION PDevExt);
  555. VOID
  556. UsbSerCancelCurrentRead(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp);
  557. BOOLEAN
  558. UsbSerGrabReadFromRx(IN PVOID Context);
  559. VOID
  560. UsbSerTryToCompleteCurrent(IN PDEVICE_EXTENSION PDevExt,
  561. IN KIRQL IrqlForRelease, IN NTSTATUS StatusToUse,
  562. IN PIRP *PpCurrentOpIrp,
  563. IN PLIST_ENTRY PQueue OPTIONAL,
  564. IN PKTIMER PIntervalTimer OPTIONAL,
  565. IN PKTIMER PTotalTimer OPTIONAL,
  566. IN PUSBSER_START_ROUTINE Starter OPTIONAL,
  567. IN PUSBSER_GET_NEXT_ROUTINE PGetNextIrp OPTIONAL,
  568. IN LONG RefType, IN BOOLEAN Complete);
  569. VOID
  570. UsbSerReadTimeout(IN PKDPC PDpc, IN PVOID DeferredContext,
  571. IN PVOID SystemContext1, IN PVOID SystemContext2);
  572. VOID
  573. UsbSerIntervalReadTimeout(IN PKDPC PDpc, IN PVOID DeferredContext,
  574. IN PVOID SystemContext1, IN PVOID SystemContext2);
  575. VOID
  576. UsbSerKillPendingIrps(PDEVICE_OBJECT PDevObj);
  577. VOID
  578. UsbSerCompletePendingWaitMasks(IN PDEVICE_EXTENSION DeviceExtension);
  579. VOID
  580. UsbSerKillAllReadsOrWrites(IN PDEVICE_OBJECT PDevObj,
  581. IN PLIST_ENTRY PQueueToClean,
  582. IN PIRP *PpCurrentOpIrp);
  583. VOID
  584. UsbSerRestoreModemSettings(PDEVICE_OBJECT PDevObj);
  585. VOID
  586. UsbSerProcessEmptyTransmit(IN PDEVICE_EXTENSION PDevExt);
  587. VOID
  588. UsbSerWriteTimeout(IN PKDPC Dpc, IN PVOID DeferredContext,
  589. IN PVOID SystemContext1, IN PVOID SystemContext2);
  590. NTSTATUS
  591. UsbSerGiveWriteToUsb(IN PDEVICE_EXTENSION PDevExt, IN PIRP PIrp,
  592. IN LARGE_INTEGER TotalTime);
  593. VOID
  594. UsbSerCancelWaitOnMask(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp);
  595. NTSTATUS
  596. UsbSerWriteComplete(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
  597. IN PUSBSER_WRITE_PACKET PPacket);
  598. NTSTATUS
  599. UsbSerFlush(IN PDEVICE_OBJECT PDevObj, PIRP PIrp);
  600. NTSTATUS
  601. UsbSerTossWMIRequest(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
  602. IN ULONG GuidIndex);
  603. NTSTATUS
  604. UsbSerSystemControlDispatch(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp);
  605. NTSTATUS
  606. UsbSerSetWmiDataItem(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
  607. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  608. IN ULONG DataItemId,
  609. IN ULONG BufferSize, IN PUCHAR PBuffer);
  610. NTSTATUS
  611. UsbSerSetWmiDataBlock(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
  612. IN ULONG GuidIndex, IN ULONG InstanceIndex,
  613. IN ULONG BufferSize,
  614. IN PUCHAR PBuffer);
  615. NTSTATUS
  616. UsbSerQueryWmiDataBlock(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
  617. IN ULONG GuidIndex,
  618. IN ULONG InstanceIndex,
  619. IN ULONG InstanceCount,
  620. IN OUT PULONG InstanceLengthArray,
  621. IN ULONG OutBufferSize,
  622. OUT PUCHAR PBuffer);
  623. NTSTATUS
  624. UsbSerQueryWmiRegInfo(IN PDEVICE_OBJECT PDevObj, OUT PULONG PRegFlags,
  625. OUT PUNICODE_STRING PInstanceName,
  626. OUT PUNICODE_STRING *PRegistryPath,
  627. OUT PUNICODE_STRING MofResourceName,
  628. OUT PDEVICE_OBJECT *Pdo);
  629. //
  630. // The following three macros are used to initialize, set
  631. // and clear references in IRPs that are used by
  632. // this driver. The reference is stored in the fourth
  633. // argument of the irp, which is never used by any operation
  634. // accepted by this driver.
  635. //
  636. #define USBSER_REF_RXBUFFER (0x00000001)
  637. #define USBSER_REF_CANCEL (0x00000002)
  638. #define USBSER_REF_TOTAL_TIMER (0x00000004)
  639. #define USBSER_REF_INT_TIMER (0x00000008)
  640. #ifdef SPINLOCK_TRACKING
  641. #define ACQUIRE_CANCEL_SPINLOCK(DEVEXT, IRQL) \
  642. { \
  643. ASSERT(DEVEXT->SpinLockCount == 0); \
  644. DEVEXT->WaitingOnCancelSpinLock++; \
  645. IoAcquireCancelSpinLock(IRQL); \
  646. DEVEXT->CancelSpinLockCount++; \
  647. DEVEXT->WaitingOnCancelSpinLock--; \
  648. ASSERT(DEVEXT->CancelSpinLockCount == 1); \
  649. }
  650. #define RELEASE_CANCEL_SPINLOCK(DEVEXT, IRQL) \
  651. { \
  652. DEVEXT->CancelSpinLockCount--; \
  653. ASSERT(DEVEXT->CancelSpinLockCount == 0); \
  654. IoReleaseCancelSpinLock(IRQL); \
  655. }
  656. #define ACQUIRE_SPINLOCK(DEVEXT, LOCK, IRQL) \
  657. { \
  658. DEVEXT->WaitingOnSpinLock++; \
  659. KeAcquireSpinLock(LOCK, IRQL); \
  660. DEVEXT->SpinLockCount++; \
  661. DEVEXT->WaitingOnSpinLock--; \
  662. ASSERT(DEVEXT->SpinLockCount == 1); \
  663. }
  664. #define RELEASE_SPINLOCK(DEVEXT, LOCK, IRQL) \
  665. { \
  666. DEVEXT->SpinLockCount--; \
  667. ASSERT(DEVEXT->SpinLockCount == 0); \
  668. KeReleaseSpinLock(LOCK, IRQL); \
  669. }
  670. #else
  671. #define ACQUIRE_CANCEL_SPINLOCK(DEVEXT, IRQL) IoAcquireCancelSpinLock(IRQL)
  672. #define RELEASE_CANCEL_SPINLOCK(DEVEXT, IRQL) IoReleaseCancelSpinLock(IRQL)
  673. #define ACQUIRE_SPINLOCK(DEVEXT, LOCK, IRQL) KeAcquireSpinLock(LOCK, IRQL)
  674. #define RELEASE_SPINLOCK(DEVEXT, LOCK, IRQL) KeReleaseSpinLock(LOCK, IRQL)
  675. #endif
  676. #define USBSER_INIT_REFERENCE(Irp) { \
  677. IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4 = NULL; \
  678. }
  679. #define USBSER_SET_REFERENCE(Irp,RefType) \
  680. do { \
  681. LONG _refType = (RefType); \
  682. PUINT_PTR _arg4 = (PVOID)&IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4; \
  683. *_arg4 |= _refType; \
  684. } while (0)
  685. #define USBSER_CLEAR_REFERENCE(Irp,RefType) \
  686. do { \
  687. LONG _refType = (RefType); \
  688. PUINT_PTR _arg4 = (PVOID)&IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4; \
  689. *_arg4 &= ~_refType; \
  690. } while (0)
  691. #define USBSER_REFERENCE_COUNT(Irp) \
  692. ((UINT_PTR)((IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4)))
  693. //
  694. // These values are used by the routines that can be used
  695. // to complete a read (other than interval timeout) to indicate
  696. // to the interval timeout that it should complete.
  697. //
  698. #define SERIAL_COMPLETE_READ_CANCEL ((LONG)-1)
  699. #define SERIAL_COMPLETE_READ_TOTAL ((LONG)-2)
  700. #define SERIAL_COMPLETE_READ_COMPLETE ((LONG)-3)
  701. #if DBG
  702. #define USBSERDUMPRD ((ULONG)0x00000001)
  703. #define USBSERDUMPWR ((ULONG)0x00000002)
  704. #define USBSERCOMPEV ((ULONG)0x00000004)
  705. #define USBSERTRACETM ((ULONG)0x00100000)
  706. #define USBSERTRACECN ((ULONG)0x00200000)
  707. #define USBSERTRACEPW ((ULONG)0x00400000)
  708. #define USBSERTRACERD ((ULONG)0x01000000)
  709. #define USBSERTRACEWR ((ULONG)0x02000000)
  710. #define USBSERTRACEIOC ((ULONG)0x04000000)
  711. #define USBSERTRACEOTH ((ULONG)0x08000000)
  712. #define USBSERBUGCHECK ((ULONG)0x80000000)
  713. #define USBSERTRACE ((ULONG)0x0F700000)
  714. #define USBSERDBGALL ((ULONG)0xFFFFFFFF)
  715. extern ULONG UsbSerSerialDebugLevel;
  716. #define UsbSerSerialDump(LEVEL, STRING) \
  717. do { \
  718. ULONG _level = (LEVEL); \
  719. if (UsbSerSerialDebugLevel & _level) { \
  720. DbgPrint("UsbSer: "); \
  721. DbgPrint STRING; \
  722. } \
  723. if (_level == USBSERBUGCHECK) { \
  724. ASSERT(FALSE); \
  725. } \
  726. } while (0)
  727. #else
  728. #define UsbSerSerialDump(LEVEL,STRING) do {;} while (0)
  729. #endif // DBG
  730. #define USBSER_VENDOR_COMMAND 0
  731. #define USBSER_CLASS_COMMAND 1
  732. #endif // DRIVER
  733. #endif // __USBSER_H__