|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1990 Microsoft Corporation
4:
5: Module Name:
6:
7: packet.c
8:
9: Abstract:
10:
11:
12: Author:
13:
14:
15: Environment:
16:
17: Kernel mode only.
18:
19: Notes:
20:
21:
22: Future:
23:
24:
25:
26: Revision History:
27:
28: --*/
29:
30: #include "stdarg.h"
31: #include "ntddk.h"
32: #include "ntiologc.h"
33: #include "ndis.h"
34:
35: #include "debug.h"
36: #include "packet.h"
37:
38:
39:
40: NTSTATUS
41: PacketRead(
42: IN PDEVICE_OBJECT DeviceObject,
43: IN PIRP Irp
44: )
45:
46: /*++
47:
48: Routine Description:
49:
50: This is the dispatch routine for create/open and close requests.
51: These requests complete successfully.
52:
53: Arguments:
54:
55: DeviceObject - Pointer to the device object.
56:
57: Irp - Pointer to the request packet.
58:
59: Return Value:
60:
61: Status is returned.
62:
63: --*/
64:
65: {
66: PIO_STACK_LOCATION IrpSp;
67: PDEVICE_EXTENSION DeviceExtension;
68: PLIST_ENTRY PacketListEntry;
69: PNDIS_PACKET pPacket;
70: PMDL pMdl;
71:
72:
73: IF_LOUD(DbgPrint("Packet: Read\n");)
74:
75: DeviceExtension = DeviceObject->DeviceExtension;
76:
77: IrpSp = IoGetCurrentIrpStackLocation(Irp);
78:
79: //
80: // See if the buffer is atleast big enough to hold the
81: // ethernet header
82: //
83: if (IrpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) {
84:
85: Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
86: return STATUS_UNSUCCESSFUL;
87: }
88:
89: //
90: // Allocate an MDL to map the portion of the buffer following the
91: // header
92: //
93: pMdl=IoAllocateMdl(
94: MmGetMdlVirtualAddress(Irp->MdlAddress),
95: MmGetMdlByteCount(Irp->MdlAddress),
96: FALSE,
97: FALSE,
98: NULL
99: );
100:
101:
102: if (pMdl == NULL) {
103: IF_LOUD(DbgPrint("Packet: Read-Failed to allocate Mdl\n");)
104: Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
105: return STATUS_UNSUCCESSFUL;
106: }
107:
108: //
109: // Build the mdl to point to the the portion of the buffer followin
110: // the header
111: //
112: IoBuildPartialMdl(
113: Irp->MdlAddress,
114: pMdl,
115: ((PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress))+ETHERNET_HEADER_LENGTH,
116: 0
117: );
118:
119: //
120: // Clear the next link in the new MDL
121: //
122: pMdl->Next=NULL;
123:
124: //
125: // Try to get a packet from our list of free ones
126: //
127: PacketListEntry=ExInterlockedRemoveHeadList(&DeviceExtension->FreePacketList,
128: &DeviceExtension->FreePacketListSpinLock);
129:
130: if (PacketListEntry == NULL) {
131: IF_LOUD(DbgPrint("Packet: Read- No free packets\n");)
132:
133: IoFreeMdl(pMdl);
134: Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
135: return STATUS_UNSUCCESSFUL;
136: }
137:
138: //
139: // Get a pointer to the packet itself
140: //
141:
142: pPacket=CONTAINING_RECORD(PacketListEntry,NDIS_PACKET,ProtocolReserved);
143: RESERVED(pPacket)->Irp=Irp;
144: RESERVED(pPacket)->pMdl=pMdl;
145:
146: IoMarkIrpPending(Irp);
147: Irp->IoStatus.Status = STATUS_PENDING;
148:
149:
150: //
151: // Attach our new MDL to the packet
152: //
153: NdisChainBufferAtFront(pPacket,pMdl);
154:
155: //
156: // Put this packet in a list of pending reads.
157: // The receive indication handler will attemp to remove packets
158: // from this list for use in transfer data calls
159: //
160: ExInterlockedInsertTailList(
161: &DeviceExtension->RcvList,
162: PacketListEntry,
163: &DeviceExtension->RcvQSpinLock);
164:
165:
166:
167:
168: return(STATUS_PENDING);
169:
170: }
171:
172:
173:
174:
175: NDIS_STATUS
176: PacketReceiveIndicate (
177: IN NDIS_HANDLE ProtocolBindingContext,
178: IN NDIS_HANDLE MacReceiveContext,
179: IN PVOID HeaderBuffer,
180: IN UINT HeaderBufferSize,
181: IN PVOID LookAheadBuffer,
182: IN UINT LookaheadBufferSize,
183: IN UINT PacketSize
184: )
185:
186: {
187: PIO_STACK_LOCATION IrpSp;
188: PDEVICE_EXTENSION DeviceExtension;
189: PIRP Irp;
190: PLIST_ENTRY PacketListEntry;
191: PNDIS_PACKET pPacket;
192: ULONG SizeToTransfer;
193: NDIS_STATUS Status;
194: UINT BytesTransfered;
195: PVOID pBuffer;
196: ULONG BufferLength;
197:
198: IF_LOUD(DbgPrint("Packet: ReceiveIndicate\n");)
199:
200: DeviceExtension= (PDEVICE_EXTENSION)ProtocolBindingContext;
201:
202: if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) {
203:
204: return NDIS_STATUS_SUCCESS;
205: }
206:
207: //
208: // See if there are any pending read that we can satisfy
209: //
210: PacketListEntry=ExInterlockedRemoveHeadList(&DeviceExtension->RcvList,
211: &DeviceExtension->RcvQSpinLock);
212:
213: if (PacketListEntry == NULL) {
214: return NDIS_STATUS_SUCCESS;
215: }
216:
217: pPacket=CONTAINING_RECORD(PacketListEntry,NDIS_PACKET,ProtocolReserved);
218:
219: Irp=RESERVED(pPacket)->Irp;
220: IrpSp = IoGetCurrentIrpStackLocation(Irp);
221:
222: //
223: // This is the length of our partial MDL
224: //
225: BufferLength=IrpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH;
226:
227: //
228: // Find out how much to transfer
229: //
230: SizeToTransfer = (PacketSize < BufferLength) ?
231: PacketSize : BufferLength;
232:
233: //
234: // copy the ethernet header into the actual readbuffer
235: //
236: NdisMoveMappedMemory(
237: MmGetSystemAddressForMdl(Irp->MdlAddress),
238: HeaderBuffer,
239: HeaderBufferSize
240: );
241:
242: //
243: // Call the Mac to transfer the packet
244: //
245:
246: NdisTransferData(
247: &Status,
248: DeviceExtension->AdapterHandle,
249: MacReceiveContext,
250: 0,
251: SizeToTransfer,
252: pPacket,
253: &BytesTransfered);
254:
255: if (Status != NDIS_STATUS_PENDING) {
256:
257: //
258: // If it didn't pend, call the completeion routine now
259: //
260: PacketTransferDataComplete(
261: DeviceExtension,
262: pPacket,
263: Status,
264: BytesTransfered
265: );
266:
267:
268: }
269:
270:
271:
272: return NDIS_STATUS_SUCCESS;
273:
274: }
275:
276:
277: VOID
278: PacketTransferDataComplete (
279: IN NDIS_HANDLE ProtocolBindingContext,
280: IN PNDIS_PACKET pPacket,
281: IN NDIS_STATUS Status,
282: IN UINT BytesTransfered
283: )
284:
285: {
286: PIO_STACK_LOCATION IrpSp;
287: PDEVICE_EXTENSION DeviceExtension;
288: PIRP Irp;
289: PMDL pMdl;
290:
291: IF_LOUD(DbgPrint("Packet: TransferDataComplete\n");)
292:
293: DeviceExtension= (PDEVICE_EXTENSION)ProtocolBindingContext;
294: Irp=RESERVED(pPacket)->Irp;
295:
296: IrpSp = IoGetCurrentIrpStackLocation(Irp);
297:
298: pMdl=RESERVED(pPacket)->pMdl;
299:
300: //
301: // Free the MDL that we allocated
302: //
303: IoFreeMdl(pMdl);
304:
305: //
306: // recylcle the packet
307: //
308: NdisReinitializePacket(pPacket);
309:
310: //
311: // Put the packet on the free queue
312: //
313: ExInterlockedInsertTailList(
314: &DeviceExtension->FreePacketList,
315: &RESERVED(pPacket)->ListElement,
316: &DeviceExtension->FreePacketListSpinLock);
317:
318:
319: Irp->IoStatus.Status = Status;
320: Irp->IoStatus.Information = BytesTransfered+ETHERNET_HEADER_LENGTH;
321: IoCompleteRequest(Irp, IO_NO_INCREMENT);
322:
323:
324: return;
325:
326:
327: }
328:
329:
330:
331:
332:
333:
334:
335:
336:
337: VOID
338: PacketReceiveComplete(
339: IN NDIS_HANDLE ProtocolBindingContext
340: )
341:
342: {
343:
344: return;
345:
346: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.