|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1990-1992 Microsoft Corporation
4:
5: Module Name:
6:
7: alloc.c
8:
9: Abstract:
10:
11: This file contains the code for allocating and freeing adapter
12: resources for the National Semiconductor SONIC Ethernet controller.
13: This driver conforms to the NDIS 3.0 interface.
14:
15: The overall structure and much of the code is taken from
16: the Lance NDIS driver by Tony Ercolano.
17:
18: Author:
19:
20: Anthony V. Ercolano (Tonye) 20-Jul-1990
21: Adam Barr (adamba) 14-Nov-1990
22:
23: Environment:
24:
25: Kernel Mode - Or whatever is the equivalent.
26:
27: Revision History:
28:
29:
30: --*/
31:
32: #include <ndis.h>
33:
34:
35: #include <efilter.h>
36: #include <sonichrd.h>
37: #include <sonicsft.h>
38:
39:
40:
41: STATIC
42: PNDIS_BUFFER
43: AllocateFlushBuffer(
44: IN PSONIC_ADAPTER Adapter,
45: IN PVOID VirtualAddress,
46: IN ULONG Length
47: );
48:
49:
50: //
51: // Use the alloc_text pragma to specify the driver initialization routines
52: // (they can be paged out).
53: //
54:
55: #ifdef ALLOC_PRAGMA
56: #pragma alloc_text(init,AllocateAdapterMemory)
57: #pragma alloc_text(init,AllocateFlushBuffer)
58: #endif
59:
60:
61:
62: STATIC
63: PNDIS_BUFFER
64: AllocateFlushBuffer(
65: IN PSONIC_ADAPTER Adapter,
66: IN PVOID VirtualAddress,
67: IN ULONG Length
68: )
69:
70: /*++
71:
72: Routine Description:
73:
74: Allocates an NDIS_BUFFER for the specified address and length.
75: This function is intended to create NDIS_BUFFERs for flushing.
76:
77: Arguments:
78:
79: Adapter - The adapter the buffer is for. It must have a
80: FlushBufferPoolHandle that points to a valid buffer pool.
81:
82: VirtualAddress - A pointer to the buffer to describe.
83:
84: Length - The length of the buffer.
85:
86: Return Value:
87:
88: The NDIS_BUFFER if one was allocated.
89: NULL if an NDIS_BUFFER could not be allocated.
90:
91: --*/
92:
93: {
94: PNDIS_BUFFER ReturnBuffer;
95: NDIS_STATUS Status;
96:
97: NdisAllocateBuffer(
98: &Status,
99: &ReturnBuffer,
100: Adapter->FlushBufferPoolHandle,
101: VirtualAddress,
102: Length
103: );
104:
105: if (Status != NDIS_STATUS_SUCCESS) {
106:
107: #if DBG
108: DbgPrint("SONIC: Could not allocate flush buffer, %x\n", Status);
109: #endif
110: ReturnBuffer = (PNDIS_BUFFER)NULL;
111: }
112:
113:
114: return ReturnBuffer;
115: }
116:
117: extern
118: BOOLEAN
119: AllocateAdapterMemory(
120: IN PSONIC_ADAPTER Adapter
121: )
122:
123: /*++
124:
125: Routine Description:
126:
127: This routine allocates memory for:
128:
129: - Transmit ring entries
130:
131: - Receive ring entries
132:
133: - Receive buffers
134:
135: - Adapter buffers for use if user transmit buffers don't meet hardware
136: contraints
137:
138: - Structures to map transmit ring entries back to the packets.
139:
140: Arguments:
141:
142: Adapter - The adapter to allocate memory for.
143:
144: Return Value:
145:
146: Returns FALSE if some memory needed for the adapter could not
147: be allocated. It does NOT call DeleteAdapterMemory in this
148: case.
149:
150: --*/
151:
152: {
153:
154: //
155: // Pointer to a transmit ring entry. Used while initializing
156: // the TDA.
157: //
158: PSONIC_TRANSMIT_DESCRIPTOR CurrentTransmitDescriptor;
159:
160: //
161: // Pointer to a receive buffer. Used while allocated the
162: // RBAs.
163: //
164: PVOID * CurrentReceiveBuffer;
165:
166: //
167: // Pointer to a receive descriptor. Used while initialing
168: // the RDA.
169: //
170: PSONIC_RECEIVE_DESCRIPTOR CurrentReceiveDescriptor;
171:
172: //
173: // Used for determining physical addresses.
174: //
175: SONIC_PHYSICAL_ADDRESS SonicPhysicalAdr;
176:
177: //
178: // Used for NDIS allocation routines that return an NDIS_PHYSICAL_ADDRESS
179: //
180: NDIS_PHYSICAL_ADDRESS NdisPhysicalAdr;
181:
182: //
183: // Simple iteration variable.
184: //
185: UINT i;
186:
187: //
188: // Used to flush buffers that only need to be flushed once.
189: //
190: PNDIS_BUFFER FlushBuffer;
191:
192: //
193: // The size of the buffer pool needed.
194: //
195: UINT PoolBuffersNeeded;
196:
197: //
198: // Holds the result of calls to SONIC_ALLOC_MEMORY
199: //
200: NDIS_STATUS AllocStatus;
201:
202:
203:
204: //
205: // We need some NDIS_BUFFERs to describe memory that we
206: // allocate (generally either to flush the buffer, or
207: // because we need its physical address). To do this
208: // we need a buffer pool, so we have to determine how
209: // many buffers we need.
210: //
211: PoolBuffersNeeded =
212: 1 + // for CamDescriptorArea
213: 1 + // for ReceiveResourceArea
214: 1 + // for BlankBuffer
215: SONIC_NUMBER_OF_SMALL_BUFFERS +
216: SONIC_NUMBER_OF_MEDIUM_BUFFERS +
217: SONIC_NUMBER_OF_LARGE_BUFFERS;
218:
219: NdisAllocateBufferPool(
220: &AllocStatus,
221: &Adapter->FlushBufferPoolHandle,
222: PoolBuffersNeeded
223: );
224:
225: if (AllocStatus != NDIS_STATUS_SUCCESS) {
226:
227: #if DBG
228: DbgPrint("SONIC: Could not allocate flush buffer pool\n");
229: #endif
230: return FALSE;
231:
232: }
233:
234:
235:
236: //
237: // Allocate the transmit ring descriptors.
238: //
239:
240: NdisAllocateSharedMemory(
241: Adapter->NdisAdapterHandle,
242: sizeof(SONIC_TRANSMIT_DESCRIPTOR)*
243: Adapter->NumberOfTransmitDescriptors,
244: FALSE, // non-cached
245: (PVOID *)&Adapter->TransmitDescriptorArea,
246: &Adapter->TransmitDescriptorAreaPhysical
247: );
248:
249: if (Adapter->TransmitDescriptorArea == NULL) {
250:
251: #if DBG
252: DbgPrint("SONIC: TransmitDescriptorArea memory invalid\n");
253: #endif
254: return FALSE;
255:
256: }
257:
258: if (NdisGetPhysicalAddressHigh(Adapter->TransmitDescriptorAreaPhysical) != 0) {
259:
260: #if DBG
261: DbgPrint("SONIC: TransmitDescriptorArea memory too high\n");
262: #endif
263: return FALSE;
264: }
265:
266:
267:
268: //
269: // Clean the above memory
270: //
271:
272: SONIC_ZERO_MEMORY(
273: Adapter->TransmitDescriptorArea,
274: (sizeof(SONIC_TRANSMIT_DESCRIPTOR)*Adapter->NumberOfTransmitDescriptors)
275: );
276:
277:
278: //
279: // We have the transmit ring descriptors. Initialize the Link
280: // fields.
281: //
282:
283: for (
284: i = 0, CurrentTransmitDescriptor = Adapter->TransmitDescriptorArea;
285: i < Adapter->NumberOfTransmitDescriptors;
286: i++,CurrentTransmitDescriptor++
287: ) {
288:
289: SonicPhysicalAdr = NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorAreaPhysical) +
290: (i * sizeof(SONIC_TRANSMIT_DESCRIPTOR));
291:
292: if (i == 0) {
293:
294: Adapter->TransmitDescriptorArea[Adapter->NumberOfTransmitDescriptors-1].Link = SonicPhysicalAdr;
295:
296: } else {
297:
298: (CurrentTransmitDescriptor-1)->Link = SonicPhysicalAdr;
299:
300: }
301:
302: }
303:
304:
305: //
306: // Allocate the ring to packet structure.
307: //
308:
309: SONIC_ALLOC_MEMORY(
310: &AllocStatus,
311: &Adapter->DescriptorToPacket,
312: sizeof(SONIC_DESCRIPTOR_TO_PACKET)
313: *Adapter->NumberOfTransmitDescriptors
314: );
315:
316: if (AllocStatus != NDIS_STATUS_SUCCESS) {
317: return FALSE;
318: }
319:
320:
321: //
322: // We have to do this now. The PrevLinkPointer field is used
323: // to point to where the Link field of the previous transmit
324: // descriptor is; it is normally set when the previous
325: // transmit descriptor is filled. For the very first packet
326: // transmitted there will have been no previous transmit
327: // descriptor, so we fill it in ourselves. We use the
328: // Link field of the last transmit descriptor (the actual
329: // location used doesn't really matter, as long as it is
330: // a valid address).
331: //
332:
333: Adapter->DescriptorToPacket->PrevLinkPointer =
334: &(Adapter->TransmitDescriptorArea[
335: Adapter->NumberOfTransmitDescriptors-1].Link);
336:
337:
338: //
339: // Allocate the receive resource area and the
340: // CAM descriptor area. These are allocated together
341: // since they must have the same high 16 bits in
342: // their addresses.
343: //
344:
345: NdisAllocateSharedMemory(
346: Adapter->NdisAdapterHandle,
347: (sizeof(SONIC_RECEIVE_RESOURCE)*Adapter->NumberOfReceiveBuffers) +
348: sizeof(SONIC_CAM_DESCRIPTOR_AREA),
349: TRUE, // cached
350: (PVOID *)&Adapter->ReceiveResourceArea,
351: &Adapter->ReceiveResourceAreaPhysical
352: );
353:
354:
355: if (Adapter->ReceiveResourceArea == NULL) {
356:
357: #if DBG
358: DbgPrint("SONIC: ReceiveResourceArea memory invalid\n");
359: #endif
360: return FALSE;
361:
362: }
363:
364: if (NdisGetPhysicalAddressHigh(Adapter->ReceiveResourceAreaPhysical) != 0) {
365:
366: #if DBG
367: DbgPrint("SONIC: ReceiveResourceArea memory too high\n");
368: #endif
369: return FALSE;
370:
371: }
372:
373:
374: //
375: // The CAM Descriptor Area is immediately after the RRA.
376: //
377:
378: Adapter->CamDescriptorArea = (PSONIC_CAM_DESCRIPTOR_AREA)
379: (Adapter->ReceiveResourceArea + Adapter->NumberOfReceiveBuffers);
380:
381: Adapter->CamDescriptorAreaPhysical =
382: NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical) +
383: ((PUCHAR)Adapter->CamDescriptorArea -
384: (PUCHAR)Adapter->ReceiveResourceArea);
385:
386:
387: //
388: // Allocate the NDIS_BUFFER to flush the CAM Descriptor Area.
389: //
390: Adapter->CamDescriptorAreaFlushBuffer = AllocateFlushBuffer(
391: Adapter,
392: Adapter->CamDescriptorArea,
393: sizeof(SONIC_CAM_DESCRIPTOR_AREA)
394: );
395:
396: if (!Adapter->CamDescriptorAreaFlushBuffer) {
397: return FALSE;
398: }
399:
400: SONIC_ZERO_MEMORY(
401: Adapter->CamDescriptorArea,
402: sizeof(SONIC_CAM_DESCRIPTOR_AREA)
403: );
404:
405: SONIC_FLUSH_WRITE_BUFFER(Adapter->CamDescriptorAreaFlushBuffer);
406:
407:
408: #if DBG
409: if (SonicDbg) {
410: DbgPrint("SONIC: Cam Descriptor Area: %lx physical: %lx\n",
411: Adapter->CamDescriptorArea,
412: Adapter->CamDescriptorAreaPhysical);
413: }
414: #endif
415:
416: //
417: // Allocate the array to hold pointers to the RBAs.
418: //
419:
420: SONIC_ALLOC_MEMORY(
421: &AllocStatus,
422: &Adapter->ReceiveBufferArea,
423: sizeof(PVOID) * Adapter->NumberOfReceiveBuffers
424: );
425:
426: if (AllocStatus != NDIS_STATUS_SUCCESS) {
427: return FALSE;
428: }
429:
430: #if DBG
431: if (SonicDbg) {
432: DbgPrint("SONIC: Receive Buffer Area: %lx\n",
433: (ULONG)Adapter->ReceiveBufferArea);
434: }
435: #endif
436:
437:
438: //
439: // We have the receive buffer pointers. Allocate the buffer
440: // for each entry and zero them.
441: //
442: // For each receive buffer, the Physical address and length
443: // will be in Adapter->ReceiveResourceArea[i], while the
444: // virtual address will be in Adapter->ReceiveBufferArea[i].
445: //
446:
447: for (
448: i = 0, CurrentReceiveBuffer = Adapter->ReceiveBufferArea;
449: i < Adapter->NumberOfReceiveBuffers;
450: i++,CurrentReceiveBuffer++
451: ) {
452:
453: NdisAllocateSharedMemory(
454: Adapter->NdisAdapterHandle,
455: SONIC_SIZE_OF_RECEIVE_BUFFERS,
456: FALSE, // non-cached
457: CurrentReceiveBuffer,
458: &NdisPhysicalAdr
459: );
460:
461:
462: if (*CurrentReceiveBuffer == NULL) {
463: return FALSE;
464: }
465:
466: if (NdisGetPhysicalAddressHigh(NdisPhysicalAdr) != 0) {
467: return FALSE;
468: }
469:
470:
471: SONIC_ZERO_MEMORY(
472: *CurrentReceiveBuffer,
473: SONIC_SIZE_OF_RECEIVE_BUFFERS
474: );
475:
476: SONIC_SET_RECEIVE_RESOURCE_ADDRESS(
477: &Adapter->ReceiveResourceArea[i],
478: NdisGetPhysicalAddressLow(NdisPhysicalAdr)
479: );
480:
481: SONIC_SET_RECEIVE_RESOURCE_LENGTH(
482: &Adapter->ReceiveResourceArea[i],
483: SONIC_SIZE_OF_RECEIVE_BUFFERS
484: );
485:
486:
487: }
488:
489: //
490: // The Receive Resource Area is set up, we can flush
491: // it now since it does not change.
492: //
493:
494: FlushBuffer = AllocateFlushBuffer(
495: Adapter,
496: (PVOID)Adapter->ReceiveResourceArea,
497: (sizeof(SONIC_RECEIVE_RESOURCE)*Adapter->NumberOfReceiveBuffers)
498: );
499:
500: if (!FlushBuffer) {
501: return FALSE;
502: }
503:
504: SONIC_FLUSH_WRITE_BUFFER(FlushBuffer);
505:
506: NdisFreeBuffer(FlushBuffer);
507:
508: //
509: // Allocate memory to hold the receive descriptor pointers.
510: //
511:
512: NdisAllocateSharedMemory(
513: Adapter->NdisAdapterHandle,
514: sizeof(SONIC_RECEIVE_DESCRIPTOR) *
515: Adapter->NumberOfReceiveDescriptors,
516: FALSE, // non-cached
517: (PVOID *)&Adapter->ReceiveDescriptorArea,
518: &Adapter->ReceiveDescriptorAreaPhysical
519: );
520:
521:
522: if (Adapter->ReceiveDescriptorArea == NULL) {
523:
524: #if DBG
525: DbgPrint("SONIC: ReceiveDescriptorArea memory invalid\n");
526: #endif
527: return FALSE;
528:
529: }
530:
531: if (NdisGetPhysicalAddressHigh(Adapter->ReceiveDescriptorAreaPhysical) != 0) {
532:
533: #if DBG
534: DbgPrint("SONIC: ReceiveDescriptorArea memory too high\n");
535: #endif
536: return FALSE;
537:
538: }
539:
540:
541:
542: //
543: // Clean the above memory
544: //
545:
546: SONIC_ZERO_MEMORY(
547: Adapter->ReceiveDescriptorArea,
548: (sizeof(SONIC_RECEIVE_DESCRIPTOR)*Adapter->NumberOfReceiveDescriptors)
549: );
550:
551:
552: //
553: // Now set up the Link fields in the receive descriptors.
554: //
555:
556: for (
557: i = 0, CurrentReceiveDescriptor = Adapter->ReceiveDescriptorArea;
558: i < Adapter->NumberOfReceiveDescriptors;
559: i++,CurrentReceiveDescriptor++
560: ) {
561:
562: //
563: // belongs to SONIC.
564: //
565:
566: CurrentReceiveDescriptor->InUse = SONIC_OWNED_BY_SONIC;
567:
568: SonicPhysicalAdr = NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorAreaPhysical) +
569: (i * sizeof(SONIC_RECEIVE_DESCRIPTOR));
570:
571: if (i == 0) {
572:
573: Adapter->ReceiveDescriptorArea[
574: Adapter->NumberOfReceiveDescriptors-1].Link =
575: SonicPhysicalAdr | SONIC_END_OF_LIST;
576:
577: } else {
578:
579: Adapter->ReceiveDescriptorArea[i-1].Link = SonicPhysicalAdr;
580:
581: }
582:
583: }
584:
585:
586: //
587: // Allocate the array of buffer descriptors.
588: //
589:
590: SONIC_ALLOC_MEMORY(
591: &AllocStatus,
592: &Adapter->SonicBuffers,
593: sizeof(SONIC_BUFFER_DESCRIPTOR)*
594: (SONIC_NUMBER_OF_SMALL_BUFFERS +
595: SONIC_NUMBER_OF_MEDIUM_BUFFERS +
596: SONIC_NUMBER_OF_LARGE_BUFFERS)
597: );
598:
599: if (AllocStatus != NDIS_STATUS_SUCCESS) {
600: return FALSE;
601: }
602:
603: //
604: // Zero the memory of all the descriptors so that we can
605: // know which buffers wern't allocated incase we can't allocate
606: // them all.
607: //
608: SONIC_ZERO_MEMORY(
609: Adapter->SonicBuffers,
610: sizeof(SONIC_BUFFER_DESCRIPTOR)*
611: (SONIC_NUMBER_OF_SMALL_BUFFERS +
612: SONIC_NUMBER_OF_MEDIUM_BUFFERS +
613: SONIC_NUMBER_OF_LARGE_BUFFERS)
614: );
615:
616:
617: //
618: // Allocate space for the small sonic buffers and fill in the
619: // buffer descriptors.
620: //
621:
622: Adapter->SonicBufferListHeads[0] = -1;
623: Adapter->SonicBufferListHeads[1] = 0;
624:
625: NdisAllocateSharedMemory(
626: Adapter->NdisAdapterHandle,
627: SONIC_SMALL_BUFFER_SIZE * SONIC_NUMBER_OF_SMALL_BUFFERS,
628: TRUE, // cached
629: &Adapter->SmallSonicBuffers,
630: &NdisPhysicalAdr
631: );
632:
633: if (NdisGetPhysicalAddressHigh(NdisPhysicalAdr) != 0) {
634: return FALSE;
635: }
636:
637:
638: if (Adapter->SmallSonicBuffers == NULL) {
639: return FALSE;
640: }
641:
642: for (
643: i = 0;
644: i < SONIC_NUMBER_OF_SMALL_BUFFERS;
645: i++
646: ) {
647:
648: Adapter->SonicBuffers[i].VirtualSonicBuffer = (PVOID)
649: ((PUCHAR)Adapter->SmallSonicBuffers +
650: (i * SONIC_SMALL_BUFFER_SIZE));
651:
652: NdisSetPhysicalAddressHigh(
653: Adapter->SonicBuffers[i].PhysicalSonicBuffer,
654: 0);
655:
656: NdisSetPhysicalAddressLow(
657: Adapter->SonicBuffers[i].PhysicalSonicBuffer,
658: NdisGetPhysicalAddressLow(NdisPhysicalAdr) +
659: (i * SONIC_SMALL_BUFFER_SIZE));
660:
661: Adapter->SonicBuffers[i].FlushBuffer =
662: AllocateFlushBuffer(
663: Adapter,
664: Adapter->SonicBuffers[i].VirtualSonicBuffer,
665: SONIC_SMALL_BUFFER_SIZE
666: );
667:
668: if (!Adapter->SonicBuffers[i].FlushBuffer) {
669: return FALSE;
670: }
671:
672: Adapter->SonicBuffers[i].Next = i+1;
673:
674: }
675:
676: //
677: // Make sure that the last buffer correctly terminates the free list.
678: //
679:
680: Adapter->SonicBuffers[i-1].Next = -1;
681:
682: //
683: // Do the medium buffers now.
684: //
685:
686: Adapter->SonicBufferListHeads[2] = i;
687:
688: NdisAllocateSharedMemory(
689: Adapter->NdisAdapterHandle,
690: SONIC_MEDIUM_BUFFER_SIZE * SONIC_NUMBER_OF_MEDIUM_BUFFERS,
691: TRUE, // cached
692: &Adapter->MediumSonicBuffers,
693: &NdisPhysicalAdr
694: );
695:
696:
697: if (Adapter->MediumSonicBuffers == NULL) {
698: return FALSE;
699: }
700:
701: if (NdisGetPhysicalAddressHigh(NdisPhysicalAdr) != 0) {
702: return FALSE;
703: }
704:
705:
706:
707: for (
708: ;
709: i < SONIC_NUMBER_OF_SMALL_BUFFERS + SONIC_NUMBER_OF_MEDIUM_BUFFERS;
710: i++
711: ) {
712:
713: Adapter->SonicBuffers[i].VirtualSonicBuffer = (PVOID)
714: ((PUCHAR)Adapter->MediumSonicBuffers +
715: ((i - SONIC_NUMBER_OF_SMALL_BUFFERS) * SONIC_MEDIUM_BUFFER_SIZE));
716:
717: NdisSetPhysicalAddressHigh(
718: Adapter->SonicBuffers[i].PhysicalSonicBuffer,
719: 0);
720:
721: NdisSetPhysicalAddressLow(
722: Adapter->SonicBuffers[i].PhysicalSonicBuffer,
723: NdisGetPhysicalAddressLow(NdisPhysicalAdr) +
724: ((i - SONIC_NUMBER_OF_SMALL_BUFFERS) * SONIC_MEDIUM_BUFFER_SIZE));
725:
726:
727: Adapter->SonicBuffers[i].FlushBuffer =
728: AllocateFlushBuffer(
729: Adapter,
730: Adapter->SonicBuffers[i].VirtualSonicBuffer,
731: SONIC_MEDIUM_BUFFER_SIZE
732: );
733:
734: if (!Adapter->SonicBuffers[i].FlushBuffer) {
735: return FALSE;
736: }
737:
738:
739: Adapter->SonicBuffers[i].Next = i+1;
740:
741: }
742:
743: //
744: // Make sure that the last buffer correctly terminates the free list.
745: //
746:
747: Adapter->SonicBuffers[i-1].Next = -1;
748:
749: //
750: // Now do the large buffers; note that they have one
751: // Physical address per buffer.
752: //
753:
754: Adapter->SonicBufferListHeads[3] = i;
755:
756: for (
757: ;
758: i < SONIC_NUMBER_OF_SMALL_BUFFERS +
759: SONIC_NUMBER_OF_MEDIUM_BUFFERS +
760: SONIC_NUMBER_OF_LARGE_BUFFERS;
761: i++
762: ) {
763:
764:
765: NdisAllocateSharedMemory(
766: Adapter->NdisAdapterHandle,
767: SONIC_LARGE_BUFFER_SIZE,
768: TRUE, // cached
769: (PVOID *)&Adapter->SonicBuffers[i].VirtualSonicBuffer,
770: &Adapter->SonicBuffers[i].PhysicalSonicBuffer
771: );
772:
773:
774: if (Adapter->SonicBuffers[i].VirtualSonicBuffer == NULL) {
775: return FALSE;
776: }
777:
778: if (NdisGetPhysicalAddressHigh(Adapter->SonicBuffers[i].PhysicalSonicBuffer) != 0) {
779: return FALSE;
780: }
781:
782:
783: Adapter->SonicBuffers[i].FlushBuffer =
784: AllocateFlushBuffer(
785: Adapter,
786: Adapter->SonicBuffers[i].VirtualSonicBuffer,
787: SONIC_LARGE_BUFFER_SIZE
788: );
789:
790: if (!Adapter->SonicBuffers[i].FlushBuffer) {
791: return FALSE;
792: }
793:
794:
795: Adapter->SonicBuffers[i].Next = i+1;
796:
797: }
798:
799: //
800: // Make sure that the last buffer correctly terminates the free list.
801: //
802:
803: Adapter->SonicBuffers[i-1].Next = -1;
804:
805:
806: //
807: // Allocate the BlankBuffer
808: //
809:
810: NdisAllocateSharedMemory(
811: Adapter->NdisAdapterHandle,
812: SONIC_SMALL_BUFFER_SIZE,
813: TRUE, // cached
814: (PVOID *)&Adapter->BlankBuffer,
815: &Adapter->BlankBufferAddress
816: );
817:
818:
819: if (Adapter->BlankBuffer == NULL) {
820: return FALSE;
821: }
822:
823: if (NdisGetPhysicalAddressHigh(Adapter->BlankBufferAddress) != 0) {
824: return FALSE;
825: }
826:
827: for (i=0; i < SONIC_SMALL_BUFFER_SIZE; i++) {
828:
829: Adapter->BlankBuffer[i] = ' ';
830:
831: }
832:
833:
834: //
835: // Flush the blank buffer now, it never changes.
836: //
837:
838: FlushBuffer = AllocateFlushBuffer(
839: Adapter,
840: Adapter->BlankBuffer,
841: SONIC_SMALL_BUFFER_SIZE
842: );
843:
844: if (!FlushBuffer) {
845: return FALSE;
846: }
847:
848: SONIC_FLUSH_WRITE_BUFFER(FlushBuffer);
849:
850: //
851: // We are done with the FlushBuffer.
852: //
853:
854: NdisFreeBuffer(FlushBuffer);
855:
856:
857: return TRUE;
858:
859: }
860:
861: extern
862: VOID
863: DeleteAdapterMemory(
864: IN PSONIC_ADAPTER Adapter
865: )
866:
867: /*++
868:
869: Routine Description:
870:
871: This routine deallocates memory for:
872:
873: - Transmit ring entries
874:
875: - Receive ring entries
876:
877: - Receive buffers
878:
879: - Adapter buffers for use if user transmit buffers don't meet hardware
880: contraints
881:
882: - Structures to map transmit ring entries back to the packets.
883:
884: Arguments:
885:
886: Adapter - The adapter to deallocate memory for.
887:
888: Return Value:
889:
890: None.
891:
892: --*/
893:
894: {
895:
896: if (Adapter->FlushBufferPoolHandle) {
897:
898: NdisFreeBufferPool(Adapter->FlushBufferPoolHandle);
899:
900: }
901:
902: if (Adapter->TransmitDescriptorArea) {
903:
904: NdisFreeSharedMemory(
905: Adapter->NdisAdapterHandle,
906: sizeof(SONIC_TRANSMIT_DESCRIPTOR)*
907: Adapter->NumberOfTransmitDescriptors,
908: FALSE,
909: Adapter->TransmitDescriptorArea,
910: Adapter->TransmitDescriptorAreaPhysical
911: );
912:
913: }
914:
915: if (Adapter->CamDescriptorAreaFlushBuffer) {
916:
917: NdisFreeBuffer(Adapter->CamDescriptorAreaFlushBuffer);
918:
919: }
920:
921: if (Adapter->ReceiveBufferArea) {
922:
923: UINT i;
924: NDIS_PHYSICAL_ADDRESS PhysicalAddr;
925:
926: for (
927: i = 0;
928: i < Adapter->NumberOfReceiveBuffers;
929: i++
930: ) {
931:
932: if (Adapter->ReceiveBufferArea[i]) {
933:
934: NdisSetPhysicalAddressHigh(PhysicalAddr, 0);
935: NdisSetPhysicalAddressLow(
936: PhysicalAddr,
937: SONIC_GET_RECEIVE_RESOURCE_ADDRESS(&Adapter->ReceiveResourceArea[i]));
938:
939: NdisFreeSharedMemory(
940: Adapter->NdisAdapterHandle,
941: SONIC_SIZE_OF_RECEIVE_BUFFERS,
942: FALSE,
943: Adapter->ReceiveBufferArea[i],
944: PhysicalAddr
945: );
946:
947: } else {
948:
949: break;
950:
951: }
952:
953: }
954:
955: SONIC_FREE_MEMORY(Adapter->ReceiveBufferArea,
956: sizeof(PVOID) * Adapter->NumberOfReceiveBuffers);
957:
958: }
959:
960: if (Adapter->ReceiveResourceArea) {
961:
962: NdisFreeSharedMemory(
963: Adapter->NdisAdapterHandle,
964: (sizeof(SONIC_RECEIVE_RESOURCE)*Adapter->NumberOfReceiveBuffers) +
965: sizeof(SONIC_CAM_DESCRIPTOR_AREA),
966: TRUE,
967: Adapter->ReceiveResourceArea,
968: Adapter->ReceiveResourceAreaPhysical
969: );
970:
971: }
972:
973: if (Adapter->ReceiveDescriptorArea) {
974:
975: NdisFreeSharedMemory(
976: Adapter->NdisAdapterHandle,
977: sizeof(SONIC_RECEIVE_DESCRIPTOR) *
978: Adapter->NumberOfReceiveDescriptors,
979: FALSE,
980: Adapter->ReceiveDescriptorArea,
981: Adapter->ReceiveDescriptorAreaPhysical
982: );
983:
984: }
985:
986: if (Adapter->DescriptorToPacket) {
987:
988: SONIC_FREE_MEMORY(Adapter->DescriptorToPacket,
989: sizeof(SONIC_DESCRIPTOR_TO_PACKET)
990: *Adapter->NumberOfTransmitDescriptors);
991:
992: }
993:
994:
995: if (Adapter->SmallSonicBuffers) {
996:
997: NdisFreeSharedMemory(
998: Adapter->NdisAdapterHandle,
999: SONIC_SMALL_BUFFER_SIZE * SONIC_NUMBER_OF_SMALL_BUFFERS,
1000: TRUE,
1001: Adapter->SmallSonicBuffers,
1002: Adapter->SonicBuffers[0].PhysicalSonicBuffer
1003: );
1004:
1005: }
1006:
1007: if (Adapter->MediumSonicBuffers) {
1008:
1009: NdisFreeSharedMemory(
1010: Adapter->NdisAdapterHandle,
1011: SONIC_MEDIUM_BUFFER_SIZE * SONIC_NUMBER_OF_MEDIUM_BUFFERS,
1012: TRUE,
1013: Adapter->MediumSonicBuffers,
1014: Adapter->SonicBuffers[SONIC_NUMBER_OF_SMALL_BUFFERS].PhysicalSonicBuffer
1015: );
1016:
1017: }
1018:
1019: if (Adapter->SonicBuffers) {
1020:
1021: UINT i;
1022:
1023: //
1024: // First free the large buffers.
1025: //
1026:
1027: for (
1028: i = SONIC_NUMBER_OF_SMALL_BUFFERS +
1029: SONIC_NUMBER_OF_MEDIUM_BUFFERS;
1030: i < SONIC_NUMBER_OF_SMALL_BUFFERS +
1031: SONIC_NUMBER_OF_MEDIUM_BUFFERS +
1032: SONIC_NUMBER_OF_LARGE_BUFFERS;
1033: i++) {
1034:
1035: if (Adapter->SonicBuffers[i].VirtualSonicBuffer) {
1036:
1037: NdisFreeSharedMemory(
1038: Adapter->NdisAdapterHandle,
1039: SONIC_LARGE_BUFFER_SIZE,
1040: TRUE,
1041: Adapter->SonicBuffers[i].VirtualSonicBuffer,
1042: Adapter->SonicBuffers[i].PhysicalSonicBuffer
1043: );
1044:
1045: } else {
1046:
1047: break;
1048:
1049: }
1050:
1051: }
1052:
1053: //
1054: // Now free the flush buffers.
1055: //
1056:
1057: for (
1058: i = 0;
1059: i < SONIC_NUMBER_OF_SMALL_BUFFERS +
1060: SONIC_NUMBER_OF_MEDIUM_BUFFERS +
1061: SONIC_NUMBER_OF_LARGE_BUFFERS;
1062: i++) {
1063:
1064: if (Adapter->SonicBuffers[i].FlushBuffer) {
1065: NdisFreeBuffer(Adapter->SonicBuffers[i].FlushBuffer);
1066: }
1067:
1068: }
1069:
1070: SONIC_FREE_MEMORY(Adapter->SonicBuffers,
1071: sizeof(SONIC_BUFFER_DESCRIPTOR)*
1072: (SONIC_NUMBER_OF_SMALL_BUFFERS +
1073: SONIC_NUMBER_OF_MEDIUM_BUFFERS +
1074: SONIC_NUMBER_OF_LARGE_BUFFERS)
1075: );
1076:
1077: }
1078:
1079:
1080: if (Adapter->BlankBuffer) {
1081:
1082: NdisFreeSharedMemory(
1083: Adapter->NdisAdapterHandle,
1084: SONIC_SMALL_BUFFER_SIZE,
1085: TRUE,
1086: Adapter->BlankBuffer,
1087: Adapter->BlankBufferAddress
1088: );
1089:
1090: }
1091:
1092:
1093: if (Adapter->FlushBufferPoolHandle) {
1094:
1095: NdisFreeBufferPool(Adapter->FlushBufferPoolHandle);
1096:
1097: }
1098:
1099: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.