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

# User Rev Content
1 asvitkine 1.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     }