1 /* $Id: mdl.c,v 1.16 2004/08/01 07:24:57 hbirr Exp $
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 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/pool.h>
16 #include <internal/mm.h>
19 #include <internal/debug.h>
21 /* GLOBALS *******************************************************************/
23 #define TAG_MDL TAG('M', 'D', 'L', ' ')
25 /* FUNCTIONS *****************************************************************/
32 IoAllocateMdl(PVOID VirtualAddress
,
34 BOOLEAN SecondaryBuffer
,
42 // Mdl = ExAllocatePoolWithQuota(NonPagedPool,
43 // MmSizeOfMdl(VirtualAddress,Length));
44 Mdl
= ExAllocatePoolWithTag(NonPagedPool
,
45 MmSizeOfMdl(VirtualAddress
,Length
),
50 Mdl
= ExAllocatePoolWithTag(NonPagedPool
,
51 MmSizeOfMdl(VirtualAddress
,Length
),
54 MmInitializeMdl(Mdl
, (char*)VirtualAddress
, Length
);
60 assert(Irp
->MdlAddress
);
62 /* FIXME: add to end of list maybe?? */
63 Mdl
->Next
= Irp
->MdlAddress
->Next
;
64 Irp
->MdlAddress
->Next
= Mdl
;
69 * What if there's allready an mdl at Irp->MdlAddress?
70 * Is that bad and should we do something about it?
72 Irp
->MdlAddress
= Mdl
;
82 * You must IoFreeMdl the slave before freeing the master.
84 * IoBuildPartialMdl is more similar to MmBuildMdlForNonPagedPool, the difference
85 * is that the former takes the physical addresses from the master MDL, while the
86 * latter - from the known location of the NPP.
90 IoBuildPartialMdl(PMDL SourceMdl
,
95 PPFN_TYPE TargetPages
= (PPFN_TYPE
)(TargetMdl
+ 1);
96 PPFN_TYPE SourcePages
= (PPFN_TYPE
)(SourceMdl
+ 1);
100 DPRINT("VirtualAddress %x, SourceMdl->StartVa %x, SourceMdl->MappedSystemVa %x\n",
101 VirtualAddress
, SourceMdl
->StartVa
, SourceMdl
->MappedSystemVa
);
103 TargetMdl
->StartVa
= (PVOID
)PAGE_ROUND_DOWN(VirtualAddress
);
104 TargetMdl
->ByteOffset
= (ULONG_PTR
)VirtualAddress
- (ULONG_PTR
)TargetMdl
->StartVa
;
105 TargetMdl
->ByteCount
= Length
;
106 TargetMdl
->Process
= SourceMdl
->Process
;
107 Delta
= (ULONG_PTR
)VirtualAddress
- ((ULONG_PTR
)SourceMdl
->StartVa
+ SourceMdl
->ByteOffset
);
108 TargetMdl
->MappedSystemVa
= SourceMdl
->MappedSystemVa
+ Delta
;
110 TargetMdl
->MdlFlags
= SourceMdl
->MdlFlags
& (MDL_IO_PAGE_READ
|MDL_SOURCE_IS_NONPAGED_POOL
|MDL_MAPPED_TO_SYSTEM_VA
);
111 TargetMdl
->MdlFlags
|= MDL_PARTIAL
;
113 Delta
= ((ULONG_PTR
)TargetMdl
->StartVa
- (ULONG_PTR
)SourceMdl
->StartVa
) / PAGE_SIZE
;
114 Count
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress
,Length
);
116 SourcePages
+= Delta
;
118 DPRINT("Delta %d, Count %d\n", Delta
, Count
);
120 memcpy(TargetPages
, SourcePages
, Count
* sizeof(PFN_TYPE
));
131 * This unmaps partial mdl's from kernel space but also asserts that non-partial
132 * mdl's isn't still mapped into kernel space.
134 MmPrepareMdlForReuse(Mdl
);