preliminary comment out the self-modifying code for RtlPrefetchMemoryNonTemporal
[reactos.git] / reactos / ntoskrnl / io / mdl.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/mdl.c
6 * PURPOSE: Io manager mdl functions
7 *
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* FUNCTIONS *****************************************************************/
18
19 /*
20 * @implemented
21 */
22 PMDL
23 STDCALL
24 IoAllocateMdl(PVOID VirtualAddress,
25 ULONG Length,
26 BOOLEAN SecondaryBuffer,
27 BOOLEAN ChargeQuota,
28 PIRP Irp)
29 {
30 PMDL Mdl;
31
32 if (ChargeQuota)
33 {
34 // Mdl = ExAllocatePoolWithQuota(NonPagedPool,
35 // MmSizeOfMdl(VirtualAddress,Length));
36 Mdl = ExAllocatePoolWithTag(NonPagedPool,
37 MmSizeOfMdl(VirtualAddress,Length),
38 TAG_MDL);
39 }
40 else
41 {
42 Mdl = ExAllocatePoolWithTag(NonPagedPool,
43 MmSizeOfMdl(VirtualAddress,Length),
44 TAG_MDL);
45 }
46 MmInitializeMdl(Mdl, (char*)VirtualAddress, Length);
47
48 if (Irp)
49 {
50 if (SecondaryBuffer)
51 {
52 ASSERT(Irp->MdlAddress);
53
54 /* FIXME: add to end of list maybe?? */
55 Mdl->Next = Irp->MdlAddress->Next;
56 Irp->MdlAddress->Next = Mdl;
57 }
58 else
59 {
60 /*
61 * What if there's allready an mdl at Irp->MdlAddress?
62 * Is that bad and should we do something about it?
63 */
64 Irp->MdlAddress = Mdl;
65 }
66 }
67
68 return(Mdl);
69 }
70
71 /*
72 * @implemented
73 *
74 * You must IoFreeMdl the slave before freeing the master.
75 *
76 * IoBuildPartialMdl is more similar to MmBuildMdlForNonPagedPool, the difference
77 * is that the former takes the physical addresses from the master MDL, while the
78 * latter - from the known location of the NPP.
79 */
80 VOID
81 STDCALL
82 IoBuildPartialMdl(PMDL SourceMdl,
83 PMDL TargetMdl,
84 PVOID VirtualAddress,
85 ULONG Length)
86 {
87 PPFN_TYPE TargetPages = (PPFN_TYPE)(TargetMdl + 1);
88 PPFN_TYPE SourcePages = (PPFN_TYPE)(SourceMdl + 1);
89 ULONG Count;
90 ULONG Delta;
91
92 DPRINT("VirtualAddress 0x%p, SourceMdl->StartVa 0x%p, SourceMdl->MappedSystemVa 0x%p\n",
93 VirtualAddress, SourceMdl->StartVa, SourceMdl->MappedSystemVa);
94
95 TargetMdl->StartVa = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
96 TargetMdl->ByteOffset = (ULONG_PTR)VirtualAddress - (ULONG_PTR)TargetMdl->StartVa;
97 TargetMdl->ByteCount = Length;
98 TargetMdl->Process = SourceMdl->Process;
99 Delta = (ULONG_PTR)VirtualAddress - ((ULONG_PTR)SourceMdl->StartVa + SourceMdl->ByteOffset);
100 TargetMdl->MappedSystemVa = (char*)SourceMdl->MappedSystemVa + Delta;
101
102 TargetMdl->MdlFlags = SourceMdl->MdlFlags & (MDL_IO_PAGE_READ|MDL_SOURCE_IS_NONPAGED_POOL|MDL_MAPPED_TO_SYSTEM_VA);
103 TargetMdl->MdlFlags |= MDL_PARTIAL;
104
105 Delta = ((ULONG_PTR)TargetMdl->StartVa - (ULONG_PTR)SourceMdl->StartVa) / PAGE_SIZE;
106 Count = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress,Length);
107
108 SourcePages += Delta;
109
110 DPRINT("Delta %d, Count %d\n", Delta, Count);
111
112 memcpy(TargetPages, SourcePages, Count * sizeof(PFN_TYPE));
113
114 }
115
116 /*
117 * @implemented
118 */
119 VOID STDCALL
120 IoFreeMdl(PMDL Mdl)
121 {
122 /*
123 * This unmaps partial mdl's from kernel space but also asserts that non-partial
124 * mdl's isn't still mapped into kernel space.
125 */
126 ASSERT(Mdl);
127 ASSERT_IRQL(DISPATCH_LEVEL);
128
129 MmPrepareMdlForReuse(Mdl);
130
131 ExFreePoolWithTag(Mdl, TAG_MDL);
132 }
133
134
135 /* EOF */