xref: /reactos/drivers/storage/class/cdrom/scratch.h (revision 3088717b)
1 /*++
2 
3 Copyright (C) Microsoft Corporation. All rights reserved.
4 
5 Module Name:
6 
7     mmc.h
8 
9 Abstract:
10 
11     Functions/macros for using the scratch buffer and scratch request/SRB
12     in the serial I/O queue context
13 
14 Author:
15 
16 Environment:
17 
18     kernel mode only
19 
20 Notes:
21 
22 
23 Revision History:
24 
25 --*/
26 
27 #ifndef __SCRATCH_H__
28 #define __SCRATCH_H__
29 
30 
31 _IRQL_requires_max_(APC_LEVEL)
32 VOID
33 ScratchBuffer_Deallocate(
34     _Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension
35     );
36 
37 _IRQL_requires_max_(APC_LEVEL)
38 BOOLEAN
39 ScratchBuffer_Allocate(
40     _Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension
41     );
42 
43 VOID
44 ScratchBuffer_ResetItems(
45     _Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension,
46     _In_ BOOLEAN                 ResetRequestHistory
47     );
48 
49 _IRQL_requires_max_(APC_LEVEL)
50 VOID
51 ScratchBuffer_SetupSrb(
52     _Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension,
53     _In_opt_ WDFREQUEST             OriginalRequest,
54     _In_ ULONG                      MaximumTransferLength,
55     _In_ BOOLEAN                    GetDataFromDevice
56     );
57 
58 VOID
59 ScratchBuffer_SetupReadWriteSrb(
60     _Inout_ PCDROM_DEVICE_EXTENSION     DeviceExtension,
61     _In_    WDFREQUEST                  OriginalRequest,
62     _In_    LARGE_INTEGER               StartingOffset,
63     _In_    ULONG                       RequiredLength,
64     _Inout_updates_bytes_(RequiredLength) UCHAR* DataBuffer,
65     _In_    BOOLEAN                     IsReadRequest,
66     _In_    BOOLEAN                     UsePartialMdl
67     );
68 
69 NTSTATUS
70 ScratchBuffer_SendSrb(
71     _Inout_     PCDROM_DEVICE_EXTENSION DeviceExtension,
72     _In_        BOOLEAN                 SynchronousSrb,
73     _When_(SynchronousSrb, _Pre_null_)
74     _When_(!SynchronousSrb, _In_opt_)
75                 PSRB_HISTORY_ITEM       *SrbHistoryItem
76     );
77 
78 NTSTATUS
79 ScratchBuffer_PerformNextReadWrite(
80     _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
81     _In_ BOOLEAN                  FirstTry
82     );
83 
84 #if DBG
85     #define ScratchBuffer_BeginUse(context) ScratchBuffer_BeginUseX((context), __FILE__, __LINE__)
86 #else
87     #define ScratchBuffer_BeginUse(context) ScratchBuffer_BeginUseX((context), NULL, (ULONG)-1)
88 #endif
89 
ScratchBuffer_BeginUseX(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension,_In_opt_ LPCSTR File,ULONG Line)90 FORCEINLINE VOID ScratchBuffer_BeginUseX(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_opt_ LPCSTR File, ULONG Line)
91 {
92     // NOTE: these are not "real" locks.  They are simply to help
93     //       avoid multiple uses of the scratch buffer. Thus, it
94     //       is not critical to have atomic operations here.
95     PVOID tmp = InterlockedCompareExchangePointer((PVOID)&(DeviceExtension->ScratchContext.ScratchInUse), (PVOID)-1, NULL);
96     NT_ASSERT(tmp == NULL);
97     UNREFERENCED_PARAMETER(tmp); //defensive coding, avoid PREFAST warning.
98     DeviceExtension->ScratchContext.ScratchInUseFileName = File;
99     DeviceExtension->ScratchContext.ScratchInUseLineNumber = Line;
100     ScratchBuffer_ResetItems(DeviceExtension, TRUE);
101     RequestClearSendTime(DeviceExtension->ScratchContext.ScratchRequest);
102     return;
103 }
ScratchBuffer_EndUse(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)104 FORCEINLINE VOID ScratchBuffer_EndUse(_Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension)
105 {
106     // NOTE: these are not "real" locks.  They are simply to help
107     //       avoid multiple uses of the scratch buffer.  Thus, it
108     //       is not critical to have atomic operations here.
109 
110     // On lock release, we erase ScratchInUseFileName and ScratchInUseLineNumber _before_ releasing ScratchInUse,
111     // because otherwise we may erase these after the lock has been acquired again by another thread. We store the
112     // old values of ScratchInUseFileName and ScratchInUseLineNumber in local variables to facilitate debugging,
113     // if the ASSERT at the end of the function is hit.
114     PCSTR  scratchInUseFileName;
115     ULONG  scratchInUseLineNumber;
116     PVOID  tmp;
117 
118     scratchInUseFileName = DeviceExtension->ScratchContext.ScratchInUseFileName;
119     scratchInUseLineNumber = DeviceExtension->ScratchContext.ScratchInUseLineNumber;
120     UNREFERENCED_PARAMETER(scratchInUseFileName);
121     UNREFERENCED_PARAMETER(scratchInUseLineNumber);
122     DeviceExtension->ScratchContext.ScratchInUseFileName = NULL;
123     DeviceExtension->ScratchContext.ScratchInUseLineNumber = 0;
124 
125     //
126     // If we have used the PartialMdl in the scratch context we should notify MM that we will be reusing it
127     // otherwise it may leak System VA if some one below us has mapped the same.
128     //
129 
130     if (DeviceExtension->ScratchContext.PartialMdlIsBuilt != FALSE)
131     {
132         MmPrepareMdlForReuse(DeviceExtension->ScratchContext.PartialMdl);
133         DeviceExtension->ScratchContext.PartialMdlIsBuilt = FALSE;
134     }
135 
136     tmp = InterlockedCompareExchangePointer((PVOID)&(DeviceExtension->ScratchContext.ScratchInUse), NULL, (PVOID)-1);
137     NT_ASSERT(tmp == ((PVOID)-1));
138     UNREFERENCED_PARAMETER(tmp); //defensive coding, avoid PREFAST warning.
139     return;
140 }
141 
142 VOID
143 CompressSrbHistoryData(
144     _Inout_  PSRB_HISTORY   RequestHistory
145     );
146 
147 VOID
148 ValidateSrbHistoryDataPresumptions(
149     _In_     SRB_HISTORY const* RequestHistory
150     );
151 
152 _IRQL_requires_max_(APC_LEVEL)
153 NTSTATUS
154 ScratchBuffer_ExecuteCdbEx(
155     _Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension,
156     _In_opt_ WDFREQUEST             OriginalRequest,
157     _In_ ULONG                      TransferSize,
158     _In_ BOOLEAN                    GetDataFromDevice,
159     _In_ PCDB                       Cdb,
160     _In_ UCHAR                      OprationLength,
161     _In_ ULONG                      TimeoutValue
162     );
163 
_IRQL_requires_max_(APC_LEVEL)164 _IRQL_requires_max_(APC_LEVEL)
165 FORCEINLINE // __REACTOS__
166 NTSTATUS
167 ScratchBuffer_ExecuteCdb(
168     _Inout_ PCDROM_DEVICE_EXTENSION DeviceExtension,
169     _In_opt_ WDFREQUEST             OriginalRequest,
170     _In_ ULONG                      TransferSize,
171     _In_ BOOLEAN                    GetDataFromDevice,
172     _In_ PCDB                       Cdb,
173     _In_ UCHAR                      OprationLength
174     )
175 {
176     return ScratchBuffer_ExecuteCdbEx(DeviceExtension,
177                                       OriginalRequest,
178                                       TransferSize,
179                                       GetDataFromDevice,
180                                       Cdb,
181                                       OprationLength,
182                                       0);
183 }
184 
185 KDEFERRED_ROUTINE ScratchBuffer_ReadWriteTimerRoutine;
186 
187 #endif //__SCRATCH_H__
188