ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/b2ether/driver/b2ether_openclose.c
Revision: 1.1
Committed: 2012-04-21T16:23:07Z (12 years, 7 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 static UINT Medium;
34 static NDIS_MEDIUM MediumArray=NdisMedium802_3;
35
36 NTSTATUS PacketOpen( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
37 /*
38 This is the dispatch routine for create/open and close requests.
39 These requests complete successfully.
40 */
41 {
42 PDEVICE_EXTENSION DeviceExtension;
43
44 POPEN_INSTANCE Open;
45
46 PIO_STACK_LOCATION IrpSp;
47
48 NDIS_STATUS Status;
49 NDIS_STATUS ErrorStatus;
50
51 UINT i;
52
53 IF_LOUD(DbgPrint("Packet: OpenAdapter\n");)
54
55 DeviceExtension = DeviceObject->DeviceExtension;
56
57 IrpSp = IoGetCurrentIrpStackLocation(Irp);
58
59 Open = ExAllocatePool(NonPagedPool,sizeof(OPEN_INSTANCE));
60 if (Open==NULL) {
61 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
62 Irp->IoStatus.Information = 0;
63 IoCompleteRequest(Irp, IO_NO_INCREMENT);
64 return STATUS_INSUFFICIENT_RESOURCES;
65 }
66
67 RtlZeroMemory( Open, sizeof(OPEN_INSTANCE) );
68
69 // Save or open here
70 IrpSp->FileObject->FsContext = Open;
71 Open->DeviceExtension = DeviceExtension;
72 Open->OpenCloseIrp = Irp;
73
74 // Allocate a packet pool for our xmit and receive packets
75 NdisAllocatePacketPool(
76 &Status,
77 &Open->PacketPool,
78 TRANSMIT_PACKETS,
79 sizeof(PACKET_RESERVED));
80
81 if (Status != NDIS_STATUS_SUCCESS) {
82 IF_LOUD(DbgPrint("Packet: Failed to allocate packet pool\n");)
83 ExFreePool(Open);
84 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
85 Irp->IoStatus.Information = 0;
86 IoCompleteRequest(Irp, IO_NO_INCREMENT);
87 return STATUS_INSUFFICIENT_RESOURCES;
88 }
89
90 // list to hold irp's want to reset the adapter
91 InitializeListHead(&Open->ResetIrpList);
92
93 // Initialize list for holding pending read requests
94 KeInitializeSpinLock(&Open->RcvQSpinLock);
95 InitializeListHead(&Open->RcvList);
96
97 // Initialize the request list
98 KeInitializeSpinLock(&Open->RequestSpinLock);
99 InitializeListHead(&Open->RequestList);
100
101 // link up the request stored in our open block
102 for ( i=0; i<MAX_REQUESTS; i++ ) {
103 ExInterlockedInsertTailList(
104 &Open->RequestList,
105 &Open->Requests[i].ListElement,
106 &Open->RequestSpinLock);
107
108 }
109
110 IoMarkIrpPending(Irp);
111 Irp->IoStatus.Status = STATUS_PENDING;
112
113 // Try to open the MAC
114 NdisOpenAdapter(
115 &Status,
116 &ErrorStatus,
117 &Open->AdapterHandle,
118 &Medium,
119 &MediumArray,
120 1,
121 DeviceExtension->NdisProtocolHandle,
122 Open,
123 &DeviceExtension->AdapterName,
124 0,
125 NULL);
126
127 if (Status != NDIS_STATUS_PENDING) {
128 PacketOpenAdapterComplete( Open, Status, NDIS_STATUS_SUCCESS );
129 }
130 return(STATUS_PENDING);
131 }
132
133
134 VOID PacketOpenAdapterComplete(
135 IN NDIS_HANDLE ProtocolBindingContext,
136 IN NDIS_STATUS Status,
137 IN NDIS_STATUS OpenErrorStatus
138 )
139 {
140 PIRP Irp;
141 POPEN_INSTANCE Open;
142
143 IF_LOUD(DbgPrint("Packet: OpenAdapterComplete\n");)
144
145 Open = (POPEN_INSTANCE)ProtocolBindingContext;
146
147 Irp = Open->OpenCloseIrp;
148
149 if (Status != NDIS_STATUS_SUCCESS) {
150 IF_LOUD(DbgPrint("Packet: OpenAdapterComplete-FAILURE\n");)
151 NdisFreePacketPool(Open->PacketPool);
152 ExFreePool(Open);
153 }
154
155 Irp->IoStatus.Status = Status;
156 IoCompleteRequest(Irp, IO_NO_INCREMENT);
157
158 return;
159 }
160
161
162 NTSTATUS PacketClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
163 {
164 POPEN_INSTANCE Open;
165 NDIS_STATUS Status;
166 PIO_STACK_LOCATION IrpSp;
167
168 IF_LOUD(DbgPrint("Packet: CloseAdapter\n");)
169
170 IrpSp = IoGetCurrentIrpStackLocation(Irp);
171 Open = IrpSp->FileObject->FsContext;
172 Open->OpenCloseIrp =Irp;
173
174 IoMarkIrpPending(Irp);
175 Irp->IoStatus.Status = STATUS_PENDING;
176
177 NdisCloseAdapter( &Status, Open->AdapterHandle );
178
179 if (Status != NDIS_STATUS_PENDING) {
180 PacketCloseAdapterComplete( Open, Status );
181 }
182
183 return(STATUS_PENDING);
184 }
185
186 VOID PacketCloseAdapterComplete(
187 IN NDIS_HANDLE ProtocolBindingContext,
188 IN NDIS_STATUS Status
189 )
190 {
191 POPEN_INSTANCE Open;
192 PIRP Irp;
193
194 IF_LOUD(DbgPrint("Packet: CloseAdapterComplete\n");)
195
196 Open = (POPEN_INSTANCE)ProtocolBindingContext;
197 Irp = Open->OpenCloseIrp;
198
199 NdisFreePacketPool(Open->PacketPool);
200 ExFreePool(Open);
201
202 Irp->IoStatus.Status = STATUS_SUCCESS;
203 IoCompleteRequest(Irp, IO_NO_INCREMENT);
204 }
205
206
207 NTSTATUS PacketCleanup(
208 IN PDEVICE_OBJECT DeviceObject,
209 IN PIRP FlushIrp
210 )
211 {
212 POPEN_INSTANCE Open;
213 PIO_STACK_LOCATION IrpSp;
214 PLIST_ENTRY PacketListEntry;
215 PNDIS_PACKET pPacket;
216 NDIS_STATUS Status;
217
218 IF_LOUD(DbgPrint("Packet: Cleanup\n");)
219
220 IrpSp = IoGetCurrentIrpStackLocation(FlushIrp);
221
222 Open=IrpSp->FileObject->FsContext;
223
224 IoMarkIrpPending(FlushIrp);
225 FlushIrp->IoStatus.Status = STATUS_PENDING;
226
227 //
228 // The open instance of the device is about to close
229 // We need to complete all pending Irp's
230 // First we complete any pending read requests
231 //
232 while ((PacketListEntry=ExInterlockedRemoveHeadList(
233 &Open->RcvList,
234 &Open->RcvQSpinLock
235 )) != NULL) {
236
237 IF_LOUD(DbgPrint("Packet: CleanUp - Completeing read\n");)
238
239 pPacket=CONTAINING_RECORD(PacketListEntry,NDIS_PACKET,ProtocolReserved);
240
241 // complete normally
242 PacketTransferDataComplete(
243 Open,
244 pPacket,
245 NDIS_STATUS_SUCCESS,
246 0
247 );
248 }
249
250 // IoMarkIrpPending(FlushIrp);
251 // FlushIrp->IoStatus.Status = STATUS_PENDING;
252
253 // We now place the Irp on the Reset list
254 ExInterlockedInsertTailList(
255 &Open->ResetIrpList,
256 &FlushIrp->Tail.Overlay.ListEntry,
257 &Open->RequestSpinLock);
258
259 // Now reset the adapter, the mac driver will complete any
260 // pending requests we have made to it.
261 NdisReset( &Status, Open->AdapterHandle );
262
263 if (Status != NDIS_STATUS_PENDING) {
264 IF_LOUD(DbgPrint("Packet: Cleanup - ResetComplte being called\n");)
265 PacketResetComplete( Open, Status );
266 }
267
268 return(STATUS_PENDING);
269 }
270
271
272 VOID PacketResetComplete(
273 IN NDIS_HANDLE ProtocolBindingContext,
274 IN NDIS_STATUS Status
275 )
276 {
277 POPEN_INSTANCE Open;
278 PIRP Irp;
279 PLIST_ENTRY ResetListEntry;
280
281 IF_LOUD(DbgPrint("Packet: PacketResetComplte\n");)
282
283 Open = (POPEN_INSTANCE)ProtocolBindingContext;
284
285 // remove the reset IRP from the list
286 ResetListEntry=ExInterlockedRemoveHeadList(
287 &Open->ResetIrpList,
288 &Open->RequestSpinLock
289 );
290
291 #if DBG
292 if (ResetListEntry == NULL) {
293 DbgBreakPoint();
294 return;
295 }
296 #endif
297
298 Irp = CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry);
299 Irp->IoStatus.Status = STATUS_SUCCESS;
300 IoCompleteRequest(Irp, IO_NO_INCREMENT);
301
302 IF_LOUD(DbgPrint("Packet: PacketResetComplte exit\n");)
303 }