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.

544 lines
14 KiB

  1. //
  2. // Differnt level of WDM supports may use different API
  3. //
  4. // e.g. MmGetSystemAddressForMdl (win9x)
  5. // Return NULL for Win9x; bugcheck for Win2000 if NULL would have returned.
  6. //
  7. // MmGetSystemAddressForMdlSafe (win2000)
  8. // Not supported in Win9x or Millen
  9. //
  10. // This is defined in SOURCES file.
  11. #define NUM_BUF_ATTACHED_THEN_ISOCH 4 // number of buffers attached before streaming and also as the water mark.
  12. //
  13. // These definition and macros are used to calculate the picture numbers.
  14. // With OHCI spec, the data is returned with the 16bit Cycle time, which includes
  15. // 3 bits of SecondCount and 13 bits of the CycleCount. This "timer" will wrap in 8 seconds.
  16. //
  17. #define TIME_PER_CYCLE 1250 // One 1394 cycle; unit = 100 nsec
  18. #define CYCLES_PER_SECOND 8000
  19. #define MAX_SECOND_COUNTS 7 // The returned CycleTime contains 3 bits of SecondCount; that is 0..7
  20. #define MAX_CYCLES (MAX_SECOND_COUNTS + 1) * CYCLES_PER_SECOND // 0..MAX_CYCLES-1
  21. #define MAX_CYCLES_TIME (MAX_CYCLES * TIME_PER_CYCLE) // unit = 100nsec
  22. #define VALIDATE_CYCLE_COUNTS(CT) ASSERT(CT.CL_SecondCount <= 7 && CT.CL_CycleCount < CYCLES_PER_SECOND && CT.CL_CycleOffset == 0);
  23. #define CALCULATE_CYCLE_COUNTS(CT) (CT.CL_SecondCount * CYCLES_PER_SECOND + CT.CL_CycleCount);
  24. #define CALCULATE_DELTA_CYCLE_COUNT(prev, now) ((now > prev) ? now - prev : now + MAX_CYCLES - prev)
  25. //
  26. // Return avg time per frame in the unit of 100 nsec;
  27. // for calculation accuracy using only integer calculation,
  28. // we should do do multimplcation before division.
  29. // That is why the application can request to get numerator and denominator separately.
  30. //
  31. #define GET_AVG_TIME_PER_FRAME(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? (1001000/3) : FRAME_TIME_PAL)
  32. #define GET_AVG_TIME_PER_FRAME_NUM(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 1001000 : 400000)
  33. #define GET_AVG_TIME_PER_FRAME_DENOM(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 3 : 1)
  34. #define GET_NUM_PACKETS_PER_FRAME(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 4004/15 /* 100100/375 */ : MAX_SRC_PACKETS_PER_PAL_FRAME)
  35. #define GET_NUM_PACKETS_PER_FRAME_NUM(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 4004 : MAX_SRC_PACKETS_PER_PAL_FRAME)
  36. #define GET_NUM_PACKETS_PER_FRAME_DENOM(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 15 : 1)
  37. //
  38. // Structure used to keep track of and to perform stream data queuing
  39. //
  40. typedef struct _AVC_STREAM_DATA_STRUCT {
  41. ULONG SizeOfThisPacket;
  42. //
  43. // Frame size is calculated based on
  44. // CIP_DBS * 4 * (CIP_FN==0? 1 : (CIP_FN==1 ? 2 : (CIP_FN==2 ? 4 : 8)))
  45. //
  46. ULONG SourcePacketSize;
  47. //
  48. // Frame size is calculated based on
  49. // SourcePacketSize * SRC_PACKETS_PER_***
  50. //
  51. ULONG FrameSize;
  52. //
  53. // Current stream time
  54. //
  55. LONGLONG CurrentStreamTime;
  56. ULONG LastCycleCount; // Used only for MPEG2TS stream
  57. //
  58. // Statistic of the frame information since last start stream
  59. // PictureNumber = FramesProcessed + FramesDropped + cndSRBCancelled.
  60. //
  61. LONGLONG PictureNumber;
  62. LONGLONG FramesProcessed; // Frame made it to 1394 serial bus.
  63. LONGLONG FramesDropped;
  64. #if DBG
  65. LONGLONG FramesAttached;
  66. #endif
  67. LONGLONG cntFrameCancelled;
  68. //
  69. // Count number of Data IRP received
  70. //
  71. LONGLONG cntDataReceived;
  72. //
  73. // Count and list for the attach list
  74. //
  75. LONG cntDataAttached;
  76. LIST_ENTRY DataAttachedListHead;
  77. //
  78. // Count and list for the SRB list
  79. //
  80. LONG cntDataQueued; // Used only with SRB_WRITE_DATA
  81. LIST_ENTRY DataQueuedListHead; // Used only with SRB_WRITE_DATA
  82. //
  83. // Count and list for the detach list
  84. //
  85. LONG cntDataDetached;
  86. LIST_ENTRY DataDetachedListHead;
  87. //
  88. // Lock to serialize attach and detach of list
  89. //
  90. KSPIN_LOCK DataListLock;
  91. //
  92. // Memory blocked allocated at passive level for queuing data IOs.
  93. //
  94. PBYTE pMemoryBlock;
  95. //
  96. // Signalled when there is no more attach frame; mainoy used to guarantee that all
  97. // data attached are transmitted before isoch is stopped for transmitting data
  98. // from PC to AVC device.
  99. //
  100. KEVENT hNoAttachEvent;
  101. } AVC_STREAM_DATA_STRUCT, * PAVC_STREAM_DATA_STRUCT;
  102. typedef struct DEVICE_EXTENSION;
  103. //
  104. // An AVC stream extension is created per stream opened. This will be returned to the caller,
  105. // when it will be used as the context (like a HANDLE) for subsequent call.
  106. // The allocation will include
  107. //
  108. // AVC_STREAM_EXTENSION
  109. // AV1394_FORMAT_INFO
  110. // AV_CLIENT_REQ
  111. //
  112. typedef struct _AVC_STREAM_EXTENSION {
  113. ULONG SizeOfThisPacket;
  114. //
  115. // This driver's device extension
  116. //
  117. struct DEVICE_EXTENSION * pDevExt;
  118. //
  119. // Data flow direction
  120. //
  121. KSPIN_DATAFLOW DataFlow; // Determine in or output pin
  122. //
  123. // Holds state
  124. //
  125. KSSTATE StreamState;
  126. //
  127. // This flag indicate if isoch is TALK/LISTEN or STOPPED
  128. //
  129. BOOLEAN IsochIsActive; // Close associated with StreamState
  130. //
  131. // Abstrction i/oPCR of an AVC device and PC itself as a plug handles
  132. // Connection handle is used when two plugs are connected.
  133. //
  134. HANDLE hPlugRemote; // Target (DVCR,D-VHS) device plug;
  135. HANDLE hPlugLocal; //.Local i/oPCR;
  136. HANDLE hConnect; // Connect two plugs
  137. //
  138. // Structure for specifing an AVC stream
  139. //
  140. PAVCSTRM_FORMAT_INFO pAVCStrmFormatInfo;
  141. //
  142. // Structure for data flow control (IsochActive, IOQueues..etc)
  143. //
  144. PAVC_STREAM_DATA_STRUCT pAVCStrmDataStruc;
  145. //
  146. // Synchronizing setting stream control and processing data
  147. //
  148. KMUTEX hMutexControl;
  149. //
  150. // Synchronize sharing the below AV_61883_REQUEST structure
  151. // Since all the stream control are synchronouse so we can use the same
  152. // AV61883Req structure to issue 61883 request
  153. //
  154. KMUTEX hMutexAVReq;
  155. PIRP pIrpAVReq;
  156. AV_61883_REQUEST AVReq;
  157. //
  158. // Counter used to indicate starting of an work item to cancel
  159. //
  160. LONG lAbortToken;
  161. //
  162. // Hold the work item
  163. //
  164. #ifdef USE_WDM110 // Win2000 code base
  165. PIO_WORKITEM pIoWorkItem;
  166. #else
  167. WORK_QUEUE_ITEM IoWorkItem;
  168. #endif
  169. //
  170. // TO signal that an work item is completed.
  171. //
  172. KEVENT hAbortDoneEvent;
  173. //
  174. // Cached plug state (these are dynamic values)
  175. //
  176. CMP_GET_PLUG_STATE RemotePlugState;
  177. #ifdef NT51_61883
  178. //
  179. // Cyclic cycle count of last DV frame
  180. //
  181. ULONG CycleCount16bits;
  182. #endif // NT51_61883
  183. //
  184. // Keep track of the last system time when the stream time was updated.
  185. // This is used to calibrate the current stream time when it is queries.
  186. //
  187. ULONGLONG LastSystemTime;
  188. //
  189. // Discontinuity is introduced when traistioning from RUN->PAUSE->RUN.
  190. // The stream time will not increment in PAUSE state but system time (1394 CycleTime) does.
  191. //
  192. BOOL b1stNewFrameFromPauseState;
  193. } AVC_STREAM_EXTENSION, *PAVC_STREAM_EXTENSION;
  194. //
  195. // Valid data entry states for a data request and they
  196. // can be Or'ed to show their code path.
  197. //
  198. // Examples of different possible code path:
  199. //
  200. // (A) Attached -> Pending -> Callback -> Completed
  201. // (B) Callback -> Attached -> Completed
  202. // (C) Attached -> Cancelled -> Completed
  203. //
  204. enum DATA_ENTRY_STATE {
  205. DE_PREPARED = 0x01,
  206. DE_IRP_LOWER_ATTACHED_COMPLETED = 0x02,
  207. DE_IRP_UPPER_PENDING_COMPLETED = 0x04,
  208. DE_IRP_LOWER_CALLBACK_COMPLETED = 0x08,
  209. DE_IRP_UPPER_COMPLETED = 0x10,
  210. DE_IRP_ERROR = 0x20,
  211. DE_IRP_CANCELLED = 0x40,
  212. };
  213. #define IsStateSet(state, bitmask) ((state & (bitmask)) == bitmask)
  214. //
  215. // This is the data entry used to attach a frame
  216. //
  217. typedef struct _AVCSTRM_DATA_ENTRY {
  218. LIST_ENTRY ListEntry;
  219. //
  220. // Keep track of data entry state
  221. //
  222. enum DATA_ENTRY_STATE State;
  223. //
  224. // IRP from client of upper layer
  225. //
  226. PIRP pIrpUpper;
  227. //
  228. // Clock provider information
  229. //
  230. BOOL ClockProvider; // Client is a clock provider?
  231. HANDLE ClockHandle; // This is used only if !ClockProvider; it is possible that there is no clock used.
  232. //
  233. // Contain information about this streaming buffer
  234. //
  235. PKSSTREAM_HEADER StreamHeader;
  236. //
  237. // Frame buffer
  238. //
  239. PVOID FrameBuffer;
  240. //
  241. // Stream extension (Context) of the stream of this frame
  242. //
  243. PAVC_STREAM_EXTENSION pAVCStrmExt;
  244. #if DBG
  245. //
  246. // Add debug related info here
  247. //
  248. LONGLONG FrameNumber;
  249. #endif
  250. //
  251. // 61883 CIP frame structure
  252. //
  253. struct _CIP_FRAME * Frame;
  254. //
  255. // IRP used to send to 61883 (lower layer) for AV request, such as attach and release
  256. //
  257. PIRP pIrpLower;
  258. //
  259. // Use to send 61883 AV data request
  260. //
  261. AV_61883_REQUEST AVReq;
  262. } AVCSTRM_DATA_ENTRY, *PAVCSTRM_DATA_ENTRY;
  263. //
  264. // To open a stream.
  265. // A context is created and return to the caller. This context is need for all
  266. // stream operation.
  267. //
  268. NTSTATUS
  269. AVCStreamOpen(
  270. IN PIRP pIrp, // The Irp from its client
  271. IN struct DEVICE_EXTENSION * pDevExt,
  272. IN OUT AVCSTRM_OPEN_STRUCT * pOpenStruct
  273. );
  274. // To Close a stram.
  275. NTSTATUS
  276. AVCStreamClose(
  277. IN PIRP pIrp, // The Irp from its client
  278. IN struct DEVICE_EXTENSION * pDevExt,
  279. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  280. );
  281. //
  282. // Process stream control
  283. //
  284. NTSTATUS
  285. AVCStreamControlGetState(
  286. IN PIRP pIrp, // The Irp from its client
  287. IN struct DEVICE_EXTENSION * pDevExt,
  288. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  289. OUT KSSTATE * pKSState
  290. );
  291. NTSTATUS
  292. AVCStreamControlSetState(
  293. IN PIRP pIrp, // The Irp from its client
  294. IN struct DEVICE_EXTENSION * pDevExt,
  295. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  296. IN KSSTATE KSState
  297. );
  298. NTSTATUS
  299. AVCStreamControlGetProperty(
  300. IN PIRP pIrp, // The Irp from its client
  301. IN struct DEVICE_EXTENSION * pDevExt,
  302. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  303. IN PSTREAM_PROPERTY_DESCRIPTOR pSPD // BUGBUG StreamClass specific
  304. );
  305. NTSTATUS
  306. AVCStreamControlSetProperty(
  307. IN PIRP pIrp, // The Irp from its client
  308. IN struct DEVICE_EXTENSION * pDevExt,
  309. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  310. IN PSTREAM_PROPERTY_DESCRIPTOR pSPD // BUGBUG StreamClass specific
  311. );
  312. // Process SRB_READ/WRITE_DATA; this is the only IRPs that will operate asychronously
  313. // with. and STATUS_PENDING is returned.
  314. NTSTATUS
  315. AVCStreamRead(
  316. IN PIRP pIrpUpper,
  317. IN struct DEVICE_EXTENSION * pDevExt,
  318. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  319. IN AVCSTRM_BUFFER_STRUCT * pBufferStruct
  320. );
  321. NTSTATUS
  322. AVCStreamWrite(
  323. IN PIRP pIrpUpper,
  324. IN struct DEVICE_EXTENSION * pDevExt,
  325. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  326. IN AVCSTRM_BUFFER_STRUCT * pBufferStruct
  327. );
  328. /*
  329. This will stop streaming and cancel all pending data irps. This is typically used
  330. to cancel all Irps. To cancel a single Irp, use IoCancelIrp().
  331. */
  332. NTSTATUS
  333. AVCStreamAbortStreaming(
  334. IN PIRP pIrp, // The Irp from its client
  335. IN struct DEVICE_EXTENSION * pDevExt,
  336. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  337. );
  338. /*
  339. Process surprise removal of a device
  340. */
  341. NTSTATUS
  342. AVCStreamSurpriseRemoval(
  343. IN struct DEVICE_EXTENSION * pDevExt
  344. );
  345. ////////////////////////////////
  346. // AvcUtil.c function prototypes
  347. ////////////////////////////////
  348. ULONGLONG
  349. GetSystemTime(
  350. )
  351. ;
  352. NTSTATUS
  353. AVCStrmAttachFrameCR(
  354. IN PDEVICE_OBJECT DeviceObject,
  355. IN PIRP pIrp,
  356. IN PAVCSTRM_DATA_ENTRY pDataEntry
  357. );
  358. VOID
  359. AVCStrmFormatAttachFrame(
  360. IN KSPIN_DATAFLOW DataFlow,
  361. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  362. IN AVCSTRM_FORMAT AVCStrmFormat,
  363. IN PAV_61883_REQUEST pAVReq,
  364. IN PAVCSTRM_DATA_ENTRY pDataEntry,
  365. IN ULONG ulSourcePacketSize, // Packet length in bytes
  366. IN ULONG ulFrameSize, // Buffer size; may contain one or multiple source packets
  367. IN PIRP pIrpUpper,
  368. IN PKSSTREAM_HEADER StreamHeader,
  369. IN PVOID FrameBuffer
  370. );
  371. NTSTATUS
  372. AVCStrmGetPlugHandle(
  373. IN PDEVICE_OBJECT DeviceObject,
  374. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  375. );
  376. NTSTATUS
  377. AVCStrmGetPlugState(
  378. IN PDEVICE_OBJECT DeviceObject,
  379. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  380. );
  381. NTSTATUS
  382. AVCStrmGetConnectionProperty(
  383. IN struct DEVICE_EXTENSION * pDevExt,
  384. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  385. PSTREAM_PROPERTY_DESCRIPTOR pSPD,
  386. PULONG pulActualBytesTransferred
  387. );
  388. NTSTATUS
  389. AVCStrmGetDroppedFramesProperty(
  390. IN struct DEVICE_EXTENSION * pDevExt,
  391. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  392. PSTREAM_PROPERTY_DESCRIPTOR pSPD,
  393. PULONG pulBytesTransferred
  394. );
  395. NTSTATUS
  396. AVCStrmMakeConnection(
  397. IN PDEVICE_OBJECT DeviceObject,
  398. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  399. );
  400. NTSTATUS
  401. AVCStrmBreakConnection(
  402. IN PDEVICE_OBJECT DeviceObject,
  403. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  404. );
  405. NTSTATUS
  406. AVCStrmStartIsoch(
  407. IN PDEVICE_OBJECT DeviceObject,
  408. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  409. );
  410. NTSTATUS
  411. AVCStrmStopIsoch(
  412. IN PDEVICE_OBJECT DeviceObject,
  413. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  414. );
  415. VOID
  416. AVCStrmWaitUntilAttachedAreCompleted(
  417. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  418. );
  419. NTSTATUS
  420. AVCStrmAllocateQueues(
  421. IN struct DEVICE_EXTENSION * pDevExt,
  422. IN PAVC_STREAM_EXTENSION pAVCStrmExt,
  423. IN KSPIN_DATAFLOW DataFlow,
  424. IN PAVC_STREAM_DATA_STRUCT pDataStruc,
  425. PAVCSTRM_FORMAT_INFO pAVCStrmFormatInfo
  426. );
  427. NTSTATUS
  428. AVCStrmFreeQueues(
  429. IN PAVC_STREAM_DATA_STRUCT pDataStruc
  430. );
  431. NTSTATUS
  432. AVCStrmCancelIO(
  433. IN PDEVICE_OBJECT DeviceObject,
  434. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  435. );
  436. NTSTATUS
  437. AVCStrmValidateFormat(
  438. PAVCSTRM_FORMAT_INFO pAVCFormatInfo
  439. );
  440. void
  441. AVCStrmAbortStreamingWorkItemRoutine(
  442. #ifdef USE_WDM110 // Win2000 code base
  443. // Extra parameter if using WDM10
  444. PDEVICE_OBJECT DeviceObject,
  445. #endif
  446. IN PAVC_STREAM_EXTENSION pAVCStrmExt
  447. );