ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/b2ether/driver/b2ether_read.c
Revision: 1.1
Committed: 2012-04-21T16:23:07Z (12 years, 6 months ago) by asvitkine
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
Import b2ether driver sources from a 2001 source archive of BasiliskII.

File Contents

# Content
1 /*
2 * b2ether driver -- derived from DDK packet driver sample
3 *
4 * Basilisk II (C) 1997-1999 Christian Bauer
5 *
6 * Windows platform specific code copyright (C) Lauri Pesonen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include "stdarg.h"
24 #include "ntddk.h"
25 #include "ntiologc.h"
26 #include "ndis.h"
27 #include "b2ether.h"
28
29 #undef DBG
30 #define DBG 0
31 #include "debug.h"
32
33
34 NTSTATUS PacketRead(
35 IN PDEVICE_OBJECT DeviceObject,
36 IN PIRP Irp
37 )
38 {
39 POPEN_INSTANCE Open;
40 PIO_STACK_LOCATION IrpSp;
41 PNDIS_PACKET pPacket;
42 PMDL pMdl;
43 NDIS_STATUS Status;
44
45 IF_LOUD(DbgPrint("Packet: Read\n");)
46
47 IrpSp = IoGetCurrentIrpStackLocation(Irp);
48
49 Open = IrpSp->FileObject->FsContext;
50
51 if (IrpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) {
52 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
53 Irp->IoStatus.Information = 0;
54 IoCompleteRequest(Irp, IO_NO_INCREMENT);
55 return STATUS_UNSUCCESSFUL;
56 }
57
58 pMdl=IoAllocateMdl(
59 MmGetMdlVirtualAddress(Irp->MdlAddress),
60 MmGetMdlByteCount(Irp->MdlAddress),
61 FALSE,
62 FALSE,
63 NULL
64 );
65
66 if (!pMdl) {
67 IF_LOUD(DbgPrint("Packet: Read-Failed to allocate Mdl\n");)
68 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
69 Irp->IoStatus.Information = 0;
70 IoCompleteRequest(Irp, IO_NO_INCREMENT);
71 return STATUS_UNSUCCESSFUL;
72 }
73
74 IoBuildPartialMdl(
75 Irp->MdlAddress,
76 pMdl,
77 ((PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress))+ETHERNET_HEADER_LENGTH,
78 0
79 );
80 pMdl->Next = NULL;
81
82 //
83 // Try to get a packet from our list of free ones
84 //
85 NdisAllocatePacket( &Status, &pPacket, Open->PacketPool );
86
87 if (Status != NDIS_STATUS_SUCCESS) {
88 IF_LOUD(DbgPrint("Packet: Read- No free packets\n");)
89 IoFreeMdl(pMdl);
90 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
91 Irp->IoStatus.Information = 0;
92 IoCompleteRequest(Irp, IO_NO_INCREMENT);
93 return STATUS_UNSUCCESSFUL;
94 }
95
96 //
97 // Get a pointer to the packet itself
98 //
99 RESERVED(pPacket)->Irp = Irp;
100 RESERVED(pPacket)->pMdl = pMdl;
101
102 IoMarkIrpPending(Irp);
103 Irp->IoStatus.Status = STATUS_PENDING;
104
105 //
106 // Attach our new MDL to the packet
107 //
108 NdisChainBufferAtFront(pPacket,pMdl);
109
110
111 //
112 // Put this packet in a list of pending reads.
113 // The receive indication handler will attemp to remove packets
114 // from this list for use in transfer data calls
115 //
116 ExInterlockedInsertTailList(
117 &Open->RcvList,
118 &RESERVED(pPacket)->ListElement,
119 &Open->RcvQSpinLock);
120
121 return(STATUS_PENDING);
122 }
123
124
125 NDIS_STATUS
126 PacketReceiveIndicate (
127 IN NDIS_HANDLE ProtocolBindingContext,
128 IN NDIS_HANDLE MacReceiveContext,
129 IN PVOID HeaderBuffer,
130 IN UINT HeaderBufferSize,
131 IN PVOID LookAheadBuffer,
132 IN UINT LookaheadBufferSize,
133 IN UINT PacketSize
134 )
135
136 {
137 POPEN_INSTANCE Open;
138 PIO_STACK_LOCATION IrpSp;
139 PIRP Irp;
140 PLIST_ENTRY PacketListEntry;
141 PNDIS_PACKET pPacket;
142 ULONG SizeToTransfer;
143 NDIS_STATUS Status;
144 UINT BytesTransfered;
145 ULONG BufferLength;
146 PPACKET_RESERVED Reserved;
147
148 IF_LOUD(DbgPrint("Packet: ReceiveIndicate\n");)
149
150 Open = (POPEN_INSTANCE)ProtocolBindingContext;
151
152 if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) {
153 return NDIS_STATUS_NOT_ACCEPTED; // NDIS_STATUS_SUCCESS;
154 }
155
156 // See if there are any pending read that we can satisfy
157 PacketListEntry=ExInterlockedRemoveHeadList(
158 &Open->RcvList,
159 &Open->RcvQSpinLock
160 );
161
162 if (PacketListEntry == NULL) {
163 IF_LOUD(DbgPrint("Packet: ReceiveIndicate dropped a packet\n");)
164 return NDIS_STATUS_NOT_ACCEPTED;
165 }
166
167 Reserved=CONTAINING_RECORD(PacketListEntry,PACKET_RESERVED,ListElement);
168 pPacket=CONTAINING_RECORD(Reserved,NDIS_PACKET,ProtocolReserved);
169
170 Irp=RESERVED(pPacket)->Irp;
171 IrpSp = IoGetCurrentIrpStackLocation(Irp);
172
173 // This is the length of our partial MDL
174 BufferLength = IrpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH;
175
176 SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength;
177
178 // copy the ethernet header into the actual readbuffer
179 NdisMoveMappedMemory(
180 MmGetSystemAddressForMdl(Irp->MdlAddress),
181 HeaderBuffer,
182 HeaderBufferSize
183 );
184
185 // Call the Mac to transfer the packet
186 NdisTransferData(
187 &Status,
188 Open->AdapterHandle,
189 MacReceiveContext,
190 0,
191 SizeToTransfer,
192 pPacket,
193 &BytesTransfered);
194
195 if (Status != NDIS_STATUS_PENDING) {
196 PacketTransferDataComplete( Open, pPacket, Status, BytesTransfered );
197 }
198
199 return NDIS_STATUS_SUCCESS;
200 }
201
202 VOID PacketTransferDataComplete (
203 IN NDIS_HANDLE ProtocolBindingContext,
204 IN PNDIS_PACKET pPacket,
205 IN NDIS_STATUS Status,
206 IN UINT BytesTransfered
207 )
208 {
209 PIO_STACK_LOCATION IrpSp;
210 POPEN_INSTANCE Open;
211 PIRP Irp;
212 PMDL pMdl;
213
214 IF_LOUD(DbgPrint("Packet: TransferDataComplete\n");)
215
216 Open = (POPEN_INSTANCE)ProtocolBindingContext;
217 Irp = RESERVED(pPacket)->Irp;
218 IrpSp = IoGetCurrentIrpStackLocation(Irp);
219 pMdl = RESERVED(pPacket)->pMdl;
220
221 // Free the MDL that we allocated
222 IoFreeMdl(pMdl);
223
224 // recycle the packet
225 NdisReinitializePacket(pPacket);
226
227 // Put the packet on the free queue
228 NdisFreePacket(pPacket);
229
230 Irp->IoStatus.Status = Status;
231 Irp->IoStatus.Information = BytesTransfered+ETHERNET_HEADER_LENGTH;
232 IoCompleteRequest(Irp, IO_NO_INCREMENT);
233 }
234
235
236 VOID PacketReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext )
237 {
238 }