)
{
PXENVIF_FRONTEND Frontend;
- CHAR Name[MAXNAMELEN];
NTSTATUS status;
Frontend = Receiver->Frontend;
KeInitializeDpc(&(*Ring)->Dpc, ReceiverRingDpc, *Ring);
- status = RtlStringCbPrintfA(Name,
- sizeof (Name),
- "%s_receiver_packet",
- (*Ring)->Path);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- for (Index = 0; Name[Index] != '\0'; Index++)
- if (Name[Index] == '/')
- Name[Index] = '_';
-
- status = XENBUS_CACHE(Create,
- &Receiver->CacheInterface,
- Name,
- sizeof (XENVIF_RECEIVER_PACKET),
- 0,
- ReceiverPacketCtor,
- ReceiverPacketDtor,
- ReceiverRingAcquireLock,
- ReceiverRingReleaseLock,
- *Ring,
- &(*Ring)->PacketCache);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- status = RtlStringCbPrintfA(Name,
- sizeof (Name),
- "%s_receiver_fragment",
- (*Ring)->Path);
- if (!NT_SUCCESS(status))
- goto fail5;
-
- for (Index = 0; Name[Index] != '\0'; Index++)
- if (Name[Index] == '/')
- Name[Index] = '_';
-
- status = XENBUS_CACHE(Create,
- &Receiver->CacheInterface,
- Name,
- sizeof (XENVIF_RECEIVER_FRAGMENT),
- 0,
- ReceiverFragmentCtor,
- ReceiverFragmentDtor,
- ReceiverRingAcquireLock,
- ReceiverRingReleaseLock,
- *Ring,
- &(*Ring)->FragmentCache);
- if (!NT_SUCCESS(status))
- goto fail6;
-
status = ThreadCreate(ReceiverRingWatchdog,
*Ring,
&(*Ring)->WatchdogThread);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail3;
return STATUS_SUCCESS;
-fail7:
- Error("fail7\n");
-
- XENBUS_CACHE(Destroy,
- &Receiver->CacheInterface,
- (*Ring)->FragmentCache);
- (*Ring)->FragmentCache = NULL;
-
-fail6:
- Error("fail6\n");
-
-fail5:
- Error("fail5\n");
-
- XENBUS_CACHE(Destroy,
- &Receiver->CacheInterface,
- (*Ring)->PacketCache);
- (*Ring)->PacketCache = NULL;
-
-fail4:
- Error("fail4\n");
-
fail3:
Error("fail3\n");
status = RtlStringCbPrintfA(Name,
sizeof (Name),
- "%s_receiver",
+ "%s_receiver_packet",
Ring->Path);
if (!NT_SUCCESS(status))
goto fail1;
if (Name[Index] == '/')
Name[Index] = '_';
+ status = XENBUS_CACHE(Create,
+ &Receiver->CacheInterface,
+ Name,
+ sizeof (XENVIF_RECEIVER_PACKET),
+ 0,
+ ReceiverPacketCtor,
+ ReceiverPacketDtor,
+ ReceiverRingAcquireLock,
+ ReceiverRingReleaseLock,
+ Ring,
+ &Ring->PacketCache);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = RtlStringCbPrintfA(Name,
+ sizeof (Name),
+ "%s_receiver_fragment",
+ Ring->Path);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ for (Index = 0; Name[Index] != '\0'; Index++)
+ if (Name[Index] == '/')
+ Name[Index] = '_';
+
+ status = XENBUS_CACHE(Create,
+ &Receiver->CacheInterface,
+ Name,
+ sizeof (XENVIF_RECEIVER_FRAGMENT),
+ 0,
+ ReceiverFragmentCtor,
+ ReceiverFragmentDtor,
+ ReceiverRingAcquireLock,
+ ReceiverRingReleaseLock,
+ Ring,
+ &Ring->FragmentCache);
+ if (!NT_SUCCESS(status))
+ goto fail4;
+
+ status = RtlStringCbPrintfA(Name,
+ sizeof (Name),
+ "%s_receiver",
+ Ring->Path);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
+ for (Index = 0; Name[Index] != '\0'; Index++)
+ if (Name[Index] == '/')
+ Name[Index] = '_';
+
status = XENBUS_GNTTAB(CreateCache,
&Receiver->GnttabInterface,
Name,
Ring,
&Ring->GnttabCache);
if (!NT_SUCCESS(status))
- goto fail2;
+ goto fail6;
Ring->Mdl = __AllocatePage();
status = STATUS_NO_MEMORY;
if (Ring->Mdl == NULL)
- goto fail3;
+ goto fail7;
Ring->Shared = MmGetSystemAddressForMdlSafe(Ring->Mdl, NormalPagePriority);
ASSERT(Ring->Shared != NULL);
FALSE,
&Ring->Entry);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail8;
status = RtlStringCbPrintfA(Name,
sizeof (Name),
__MODULE__ "|RECEIVER[%u]",
Ring->Index);
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail9;
ASSERT(!Ring->Connected);
status = STATUS_UNSUCCESSFUL;
if (Ring->Channel == NULL)
- goto fail6;
+ goto fail10;
status = KeGetProcessorNumberFromIndex(Ring->Index, &ProcNumber);
ASSERT(NT_SUCCESS(status));
Ring,
&Ring->DebugCallback);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail11;
return STATUS_SUCCESS;
-fail7:
- Error("fail7\n");
+fail11:
+ Error("fail11\n");
Ring->Connected = FALSE;
Ring->Events = 0;
-fail6:
- Error("fail6\n");
+fail10:
+ Error("fail10\n");
-fail5:
- Error("fail5\n");
+fail9:
+ Error("fail9\n");
(VOID) XENBUS_GNTTAB(RevokeForeignAccess,
&Receiver->GnttabInterface,
Ring->Entry);
Ring->Entry = NULL;
-fail4:
- Error("fail4\n");
+fail8:
+ Error("fail8\n");
RtlZeroMemory(&Ring->Front, sizeof (netif_rx_front_ring_t));
RtlZeroMemory(Ring->Shared, PAGE_SIZE);
__FreePage(Ring->Mdl);
Ring->Mdl = NULL;
-fail3:
- Error("fail3\n");
+fail7:
+ Error("fail7\n");
XENBUS_GNTTAB(DestroyCache,
&Receiver->GnttabInterface,
Ring->GnttabCache);
Ring->GnttabCache = NULL;
+fail6:
+ Error("fail6\n");
+
+fail5:
+ Error("fail5\n");
+
+ XENBUS_CACHE(Destroy,
+ &Receiver->CacheInterface,
+ Ring->FragmentCache);
+ Ring->FragmentCache = NULL;
+
+fail4:
+ Error("fail4\n");
+
+fail3:
+ Error("fail3\n");
+
+ XENBUS_CACHE(Destroy,
+ &Receiver->CacheInterface,
+ Ring->PacketCache);
+ Ring->PacketCache = NULL;
+
fail2:
Error("fail2\n");
&Receiver->GnttabInterface,
Ring->GnttabCache);
Ring->GnttabCache = NULL;
+
+ XENBUS_CACHE(Destroy,
+ &Receiver->CacheInterface,
+ Ring->FragmentCache);
+ Ring->FragmentCache = NULL;
+
+ XENBUS_CACHE(Destroy,
+ &Receiver->CacheInterface,
+ Ring->PacketCache);
+ Ring->PacketCache = NULL;
}
static FORCEINLINE VOID
ThreadJoin(Ring->WatchdogThread);
Ring->WatchdogThread = NULL;
- XENBUS_CACHE(Destroy,
- &Receiver->CacheInterface,
- Ring->FragmentCache);
- Ring->FragmentCache = NULL;
-
- XENBUS_CACHE(Destroy,
- &Receiver->CacheInterface,
- Ring->PacketCache);
- Ring->PacketCache = NULL;
-
ASSERT(IsListEmpty(&Ring->PacketList));
RtlZeroMemory(&Ring->PacketList, sizeof (LIST_ENTRY));
(*Receiver)->Frontend = Frontend;
- status = XENBUS_CACHE(Acquire, &(*Receiver)->CacheInterface);
- if (!NT_SUCCESS(status))
- goto fail2;
-
(*Receiver)->MaxQueues = FrontendGetMaxQueues(Frontend);
(*Receiver)->Ring = __ReceiverAllocate(sizeof (PXENVIF_RECEIVER_RING) *
(*Receiver)->MaxQueues);
status = STATUS_NO_MEMORY;
if ((*Receiver)->Ring == NULL)
- goto fail3;
+ goto fail2;
Index = 0;
while (Index < (*Receiver)->MaxQueues) {
status = __ReceiverRingInitialize(*Receiver, Index, &Ring);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail3;
(*Receiver)->Ring[Index] = Ring;
Index++;
return STATUS_SUCCESS;
-fail4:
- Error("fail4\n");
+fail3:
+ Error("fail3\n");
while (--Index >= 0) {
PXENVIF_RECEIVER_RING Ring = (*Receiver)->Ring[Index];
}
__ReceiverFree((*Receiver)->Ring);
- (*Receiver)->Ring = NULL;
-
-fail3:
- Error("fail3\n");
-
- (*Receiver)->MaxQueues = 0;
- XENBUS_CACHE(Release, &(*Receiver)->CacheInterface);
+ (*Receiver)->Ring = NULL;
fail2:
Error("fail2\n");
+ (*Receiver)->MaxQueues = 0;
(*Receiver)->Frontend = NULL;
RtlZeroMemory(&(*Receiver)->EvtchnInterface,
if (!NT_SUCCESS(status))
goto fail3;
- status = XENBUS_GNTTAB(Acquire, &Receiver->GnttabInterface);
+ status = XENBUS_CACHE(Acquire, &Receiver->CacheInterface);
if (!NT_SUCCESS(status))
goto fail4;
+ status = XENBUS_GNTTAB(Acquire, &Receiver->GnttabInterface);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
status = XENBUS_STORE(Read,
&Receiver->StoreInterface,
NULL,
status = __ReceiverRingConnect(Ring);
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail6;
Index++;
}
Receiver,
&Receiver->DebugCallback);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail7;
Trace("<====\n");
return STATUS_SUCCESS;
-fail6:
- Error("fail6\n");
+fail7:
+ Error("fail7\n");
Index = Receiver->NumQueues;
-fail5:
- Error("fail5\n");
+fail6:
+ Error("fail6\n");
while (--Index >= 0) {
PXENVIF_RECEIVER_RING Ring = Receiver->Ring[Index];
XENBUS_GNTTAB(Release, &Receiver->GnttabInterface);
+fail5:
+ Error("fail5\n");
+
+ XENBUS_CACHE(Release, &Receiver->CacheInterface);
+
fail4:
Error("fail4\n");
XENBUS_GNTTAB(Release, &Receiver->GnttabInterface);
+ XENBUS_CACHE(Release, &Receiver->CacheInterface);
+
XENBUS_EVTCHN(Release, &Receiver->EvtchnInterface);
XENBUS_STORE(Release, &Receiver->StoreInterface);
Receiver->Ring = NULL;
Receiver->MaxQueues = 0;
- XENBUS_CACHE(Release, &Receiver->CacheInterface);
-
Receiver->Frontend = NULL;
RtlZeroMemory(&Receiver->EvtchnInterface,
)
{
PXENVIF_FRONTEND Frontend;
- CHAR Name[MAXNAMELEN];
NTSTATUS status;
Frontend = Transmitter->Frontend;
KeInitializeDpc(&(*Ring)->Dpc, TransmitterRingDpc, *Ring);
+ status = ThreadCreate(TransmitterRingWatchdog,
+ *Ring,
+ &(*Ring)->WatchdogThread);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ return STATUS_SUCCESS;
+
+fail3:
+ Error("fail3\n");
+
+ RtlZeroMemory(&(*Ring)->Dpc, sizeof (KDPC));
+
+ RtlZeroMemory(&(*Ring)->PacketComplete, sizeof (LIST_ENTRY));
+ RtlZeroMemory(&(*Ring)->RequestQueue, sizeof (LIST_ENTRY));
+ RtlZeroMemory(&(*Ring)->PacketQueue, sizeof (LIST_ENTRY));
+
+ FrontendFreePath(Frontend, (*Ring)->Path);
+ (*Ring)->Path = NULL;
+
+fail2:
+ Error("fail2\n");
+
+ (*Ring)->Index = 0;
+ (*Ring)->Transmitter = NULL;
+
+ ASSERT(IsZeroMemory(*Ring, sizeof (XENVIF_TRANSMITTER_RING)));
+ __TransmitterFree(*Ring);
+ *Ring = NULL;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__TransmitterRingConnect(
+ IN PXENVIF_TRANSMITTER_RING Ring
+ )
+{
+ PXENVIF_TRANSMITTER Transmitter;
+ PXENVIF_FRONTEND Frontend;
+ PFN_NUMBER Pfn;
+ CHAR Name[MAXNAMELEN];
+ ULONG Index;
+ PROCESSOR_NUMBER ProcNumber;
+ NTSTATUS status;
+
+ ASSERT(!Ring->Connected);
+
+ Transmitter = Ring->Transmitter;
+ Frontend = Transmitter->Frontend;
+
status = RtlStringCbPrintfA(Name,
sizeof (Name),
"%s_transmitter_buffer",
- (*Ring)->Path);
+ Ring->Path);
if (!NT_SUCCESS(status))
- goto fail3;
+ goto fail1;
for (Index = 0; Name[Index] != '\0'; Index++)
if (Name[Index] == '/')
TransmitterBufferDtor,
TransmitterRingAcquireLock,
TransmitterRingReleaseLock,
- *Ring,
- &(*Ring)->BufferCache);
+ Ring,
+ &Ring->BufferCache);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail2;
status = RtlStringCbPrintfA(Name,
sizeof (Name),
"%s_transmitter_multicast_control",
- (*Ring)->Path);
+ Ring->Path);
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail3;
for (Index = 0; Name[Index] != '\0'; Index++)
if (Name[Index] == '/')
TransmitterMulticastControlDtor,
TransmitterRingAcquireLock,
TransmitterRingReleaseLock,
- *Ring,
- &(*Ring)->MulticastControlCache);
+ Ring,
+ &Ring->MulticastControlCache);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail4;
status = RtlStringCbPrintfA(Name,
sizeof (Name),
"%s_transmitter_req_id",
- (*Ring)->Path);
+ Ring->Path);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail5;
for (Index = 0; Name[Index] != '\0'; Index++)
if (Name[Index] == '/')
status = XENBUS_RANGE_SET(Create,
&Transmitter->RangeSetInterface,
Name,
- &(*Ring)->RangeSet);
+ &Ring->RangeSet);
if (!NT_SUCCESS(status))
- goto fail8;
+ goto fail6;
status = XENBUS_RANGE_SET(Put,
&Transmitter->RangeSetInterface,
- (*Ring)->RangeSet,
+ Ring->RangeSet,
1,
XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
if (!NT_SUCCESS(status))
- goto fail9;
+ goto fail7;
status = RtlStringCbPrintfA(Name,
sizeof (Name),
"%s_transmitter_fragment",
- (*Ring)->Path);
+ Ring->Path);
if (!NT_SUCCESS(status))
- goto fail10;
+ goto fail8;
for (Index = 0; Name[Index] != '\0'; Index++)
if (Name[Index] == '/')
TransmitterFragmentDtor,
TransmitterRingAcquireLock,
TransmitterRingReleaseLock,
- *Ring,
- &(*Ring)->FragmentCache);
+ Ring,
+ &Ring->FragmentCache);
if (!NT_SUCCESS(status))
- goto fail11;
+ goto fail9;
status = RtlStringCbPrintfA(Name,
sizeof (Name),
"%s_transmitter_request",
- (*Ring)->Path);
+ Ring->Path);
if (!NT_SUCCESS(status))
- goto fail12;
+ goto fail10;
for (Index = 0; Name[Index] != '\0'; Index++)
if (Name[Index] == '/')
TransmitterRequestDtor,
TransmitterRingAcquireLock,
TransmitterRingReleaseLock,
- *Ring,
- &(*Ring)->RequestCache);
- if (!NT_SUCCESS(status))
- goto fail13;
-
- status = ThreadCreate(TransmitterRingWatchdog,
- *Ring,
- &(*Ring)->WatchdogThread);
+ Ring,
+ &Ring->RequestCache);
if (!NT_SUCCESS(status))
- goto fail14;
-
- return STATUS_SUCCESS;
-
-fail14:
- Error("fail14\n");
-
- XENBUS_CACHE(Destroy,
- &Transmitter->CacheInterface,
- (*Ring)->RequestCache);
- (*Ring)->RequestCache = NULL;
-
-fail13:
- Error("fail13\n");
-
-fail12:
- Error("fail12\n");
-
- XENBUS_CACHE(Destroy,
- &Transmitter->CacheInterface,
- (*Ring)->FragmentCache);
- (*Ring)->FragmentCache = NULL;
-
-fail11:
- Error("fail11\n");
-
-fail10:
- Error("fail10\n");
-
- (VOID) XENBUS_RANGE_SET(Get,
- &Transmitter->RangeSetInterface,
- (*Ring)->RangeSet,
- 1,
- XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
-
-fail9:
- Error("fail9\n");
-
- XENBUS_RANGE_SET(Destroy,
- &Transmitter->RangeSetInterface,
- (*Ring)->RangeSet);
- (*Ring)->RangeSet = NULL;
-
-fail8:
- Error("fail8\n");
-
-fail7:
- Error("fail7\n");
-
- XENBUS_CACHE(Destroy,
- &Transmitter->CacheInterface,
- (*Ring)->MulticastControlCache);
- (*Ring)->MulticastControlCache = NULL;
-
-fail6:
- Error("fail6\n");
-
-fail5:
- Error("fail5\n");
-
- XENBUS_CACHE(Destroy,
- &Transmitter->CacheInterface,
- (*Ring)->BufferCache);
- (*Ring)->BufferCache = NULL;
-
-fail4:
- Error("fail4\n");
-
-fail3:
- Error("fail3\n");
-
- RtlZeroMemory(&(*Ring)->Dpc, sizeof (KDPC));
-
- RtlZeroMemory(&(*Ring)->PacketComplete, sizeof (LIST_ENTRY));
- RtlZeroMemory(&(*Ring)->RequestQueue, sizeof (LIST_ENTRY));
- RtlZeroMemory(&(*Ring)->PacketQueue, sizeof (LIST_ENTRY));
-
- FrontendFreePath(Frontend, (*Ring)->Path);
- (*Ring)->Path = NULL;
-
-fail2:
- Error("fail2\n");
-
- (*Ring)->Index = 0;
- (*Ring)->Transmitter = NULL;
-
- ASSERT(IsZeroMemory(*Ring, sizeof (XENVIF_TRANSMITTER_RING)));
- __TransmitterFree(*Ring);
- *Ring = NULL;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
-static FORCEINLINE NTSTATUS
-__TransmitterRingConnect(
- IN PXENVIF_TRANSMITTER_RING Ring
- )
-{
- PXENVIF_TRANSMITTER Transmitter;
- PXENVIF_FRONTEND Frontend;
- PFN_NUMBER Pfn;
- CHAR Name[MAXNAMELEN];
- ULONG Index;
- PROCESSOR_NUMBER ProcNumber;
- NTSTATUS status;
-
- ASSERT(!Ring->Connected);
-
- Transmitter = Ring->Transmitter;
- Frontend = Transmitter->Frontend;
+ goto fail11;
status = RtlStringCbPrintfA(Name,
sizeof (Name),
"%s_transmitter",
Ring->Path);
if (!NT_SUCCESS(status))
- goto fail1;
+ goto fail12;
for (Index = 0; Name[Index] != '\0'; Index++)
if (Name[Index] == '/')
Ring,
&Ring->GnttabCache);
if (!NT_SUCCESS(status))
- goto fail2;
+ goto fail13;
Ring->Mdl = __AllocatePage();
status = STATUS_NO_MEMORY;
if (Ring->Mdl == NULL)
- goto fail3;
+ goto fail14;
Ring->Shared = MmGetSystemAddressForMdlSafe(Ring->Mdl, NormalPagePriority);
ASSERT(Ring->Shared != NULL);
FALSE,
&Ring->Entry);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail15;
status = RtlStringCbPrintfA(Name,
sizeof (Name),
__MODULE__ "|TRANSMITTER[%u]",
Ring->Index);
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail16;
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
status = STATUS_UNSUCCESSFUL;
if (Ring->Channel == NULL)
- goto fail6;
+ goto fail17;
status = KeGetProcessorNumberFromIndex(Ring->Index, &ProcNumber);
ASSERT(NT_SUCCESS(status));
Ring,
&Ring->DebugCallback);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail18;
Ring->Connected = TRUE;
return STATUS_SUCCESS;
-fail7:
- Error("fail7\n");
+fail18:
+ Error("fail18\n");
XENBUS_EVTCHN(Close,
&Transmitter->EvtchnInterface,
Ring->Events = 0;
-fail6:
- Error("fail6\n");
+fail17:
+ Error("fail17\n");
-fail5:
- Error("fail5\n");
+fail16:
+ Error("fail16\n");
(VOID) XENBUS_GNTTAB(RevokeForeignAccess,
&Transmitter->GnttabInterface,
Ring->Entry);
Ring->Entry = NULL;
-fail4:
- Error("fail4\n");
+fail15:
+ Error("fail15\n");
RtlZeroMemory(&Ring->Front, sizeof (netif_tx_front_ring_t));
RtlZeroMemory(Ring->Shared, PAGE_SIZE);
__FreePage(Ring->Mdl);
Ring->Mdl = NULL;
-fail3:
- Error("fail3\n");
+fail14:
+ Error("fail14\n");
XENBUS_GNTTAB(DestroyCache,
&Transmitter->GnttabInterface,
Ring->GnttabCache);
Ring->GnttabCache = NULL;
+fail13:
+ Error("fail13\n");
+
+fail12:
+ Error("fail12\n");
+
+ XENBUS_CACHE(Destroy,
+ &Transmitter->CacheInterface,
+ Ring->RequestCache);
+ Ring->RequestCache = NULL;
+
+fail11:
+ Error("fail11\n");
+
+fail10:
+ Error("fail10\n");
+
+ XENBUS_CACHE(Destroy,
+ &Transmitter->CacheInterface,
+ Ring->FragmentCache);
+ Ring->FragmentCache = NULL;
+
+fail9:
+ Error("fail9\n");
+
+fail8:
+ Error("fail8\n");
+
+ (VOID) XENBUS_RANGE_SET(Get,
+ &Transmitter->RangeSetInterface,
+ Ring->RangeSet,
+ 1,
+ XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
+
+fail7:
+ Error("fail7\n");
+
+ XENBUS_RANGE_SET(Destroy,
+ &Transmitter->RangeSetInterface,
+ Ring->RangeSet);
+ Ring->RangeSet = NULL;
+
+fail6:
+ Error("fail6\n");
+
+fail5:
+ Error("fail5\n");
+
+ XENBUS_CACHE(Destroy,
+ &Transmitter->CacheInterface,
+ Ring->MulticastControlCache);
+ Ring->MulticastControlCache = NULL;
+
+fail4:
+ Error("fail4\n");
+
+fail3:
+ Error("fail3\n");
+
+ XENBUS_CACHE(Destroy,
+ &Transmitter->CacheInterface,
+ Ring->BufferCache);
+ Ring->BufferCache = NULL;
+
fail2:
Error("fail2\n");
&Transmitter->GnttabInterface,
Ring->GnttabCache);
Ring->GnttabCache = NULL;
+
+ XENBUS_CACHE(Destroy,
+ &Transmitter->CacheInterface,
+ Ring->RequestCache);
+ Ring->RequestCache = NULL;
+
+ XENBUS_CACHE(Destroy,
+ &Transmitter->CacheInterface,
+ Ring->FragmentCache);
+ Ring->FragmentCache = NULL;
+
+ (VOID) XENBUS_RANGE_SET(Get,
+ &Transmitter->RangeSetInterface,
+ Ring->RangeSet,
+ 1,
+ XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
+
+ XENBUS_RANGE_SET(Destroy,
+ &Transmitter->RangeSetInterface,
+ Ring->RangeSet);
+ Ring->RangeSet = NULL;
+
+ XENBUS_CACHE(Destroy,
+ &Transmitter->CacheInterface,
+ Ring->MulticastControlCache);
+ Ring->MulticastControlCache = NULL;
+
+ XENBUS_CACHE(Destroy,
+ &Transmitter->CacheInterface,
+ Ring->BufferCache);
+ Ring->BufferCache = NULL;
}
static FORCEINLINE VOID
ThreadJoin(Ring->WatchdogThread);
Ring->WatchdogThread = NULL;
- XENBUS_CACHE(Destroy,
- &Transmitter->CacheInterface,
- Ring->RequestCache);
- Ring->RequestCache = NULL;
-
- XENBUS_CACHE(Destroy,
- &Transmitter->CacheInterface,
- Ring->FragmentCache);
- Ring->FragmentCache = NULL;
-
- (VOID) XENBUS_RANGE_SET(Get,
- &Transmitter->RangeSetInterface,
- Ring->RangeSet,
- 1,
- XENVIF_TRANSMITTER_MAXIMUM_FRAGMENT_ID);
-
- XENBUS_RANGE_SET(Destroy,
- &Transmitter->RangeSetInterface,
- Ring->RangeSet);
- Ring->RangeSet = NULL;
-
- XENBUS_CACHE(Destroy,
- &Transmitter->CacheInterface,
- Ring->MulticastControlCache);
- Ring->MulticastControlCache = NULL;
-
- XENBUS_CACHE(Destroy,
- &Transmitter->CacheInterface,
- Ring->BufferCache);
- Ring->BufferCache = NULL;
-
ASSERT(IsListEmpty(&Ring->PacketComplete));
RtlZeroMemory(&Ring->PacketComplete, sizeof (LIST_ENTRY));
(*Transmitter)->Frontend = Frontend;
KeInitializeSpinLock(&(*Transmitter)->Lock);
- status = XENBUS_RANGE_SET(Acquire, &(*Transmitter)->RangeSetInterface);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- status = XENBUS_CACHE(Acquire, &(*Transmitter)->CacheInterface);
- if (!NT_SUCCESS(status))
- goto fail3;
-
(*Transmitter)->MaxQueues = FrontendGetMaxQueues(Frontend);
(*Transmitter)->Ring = __TransmitterAllocate(sizeof (PXENVIF_TRANSMITTER_RING) *
(*Transmitter)->MaxQueues);
status = STATUS_NO_MEMORY;
if ((*Transmitter)->Ring == NULL)
- goto fail4;
+ goto fail2;
Index = 0;
while (Index < (*Transmitter)->MaxQueues) {
status = __TransmitterRingInitialize(*Transmitter, Index, &Ring);
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail3;
(*Transmitter)->Ring[Index] = Ring;
Index++;
return STATUS_SUCCESS;
-fail5:
- Error("fail5\n");
+fail3:
+ Error("fail3\n");
while (--Index > 0) {
PXENVIF_TRANSMITTER_RING Ring = (*Transmitter)->Ring[Index];
__TransmitterFree((*Transmitter)->Ring);
(*Transmitter)->Ring = NULL;
-fail4:
- Error("fail4\n");
-
- (*Transmitter)->MaxQueues = 0;
-
- XENBUS_CACHE(Release, &(*Transmitter)->CacheInterface);
-
-fail3:
- Error("fail3\n");
-
- XENBUS_RANGE_SET(Release, &(*Transmitter)->RangeSetInterface);
-
fail2:
Error("fail2\n");
+ (*Transmitter)->MaxQueues = 0;
+
(*Transmitter)->Frontend = NULL;
RtlZeroMemory(&(*Transmitter)->Lock,
if (!NT_SUCCESS(status))
goto fail3;
- status = XENBUS_GNTTAB(Acquire, &Transmitter->GnttabInterface);
+ status = XENBUS_RANGE_SET(Acquire, &Transmitter->RangeSetInterface);
if (!NT_SUCCESS(status))
goto fail4;
+ status = XENBUS_CACHE(Acquire, &Transmitter->CacheInterface);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
+ status = XENBUS_GNTTAB(Acquire, &Transmitter->GnttabInterface);
+ if (!NT_SUCCESS(status))
+ goto fail6;
+
status = RtlStringCbPrintfA(Name,
sizeof (Name),
"%s_transmitter_packet",
FrontendGetPath(Frontend));
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail7;
for (Index = 0; Name[Index] != '\0'; Index++)
if (Name[Index] == '/')
Transmitter,
&Transmitter->PacketCache);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail8;
status = XENBUS_STORE(Read,
&Transmitter->StoreInterface,
status = __TransmitterRingConnect(Ring);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail9;
Index++;
}
Transmitter,
&Transmitter->DebugCallback);
if (!NT_SUCCESS(status))
- goto fail8;
+ goto fail10;
Trace("<====\n");
return STATUS_SUCCESS;
-fail8:
- Error("fail8\n");
+fail10:
+ Error("fail10\n");
Index = Transmitter->NumQueues;
-fail7:
- Error("fail7\n");
+fail9:
+ Error("fail9\n");
while (--Index >= 0) {
PXENVIF_TRANSMITTER_RING Ring;
Transmitter->PacketCache);
Transmitter->PacketCache = NULL;
+fail8:
+ Error("fail8\n");
+
+fail7:
+ Error("fail7\n");
+
+ XENBUS_GNTTAB(Release, &Transmitter->GnttabInterface);
+
fail6:
Error("fail6\n");
+ XENBUS_CACHE(Release, &Transmitter->CacheInterface);
+
fail5:
Error("fail5\n");
- XENBUS_GNTTAB(Release, &Transmitter->GnttabInterface);
+ XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
fail4:
Error("fail4\n");
XENBUS_GNTTAB(Release, &Transmitter->GnttabInterface);
+ XENBUS_CACHE(Release, &Transmitter->CacheInterface);
+
+ XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
+
XENBUS_EVTCHN(Release, &Transmitter->EvtchnInterface);
XENBUS_STORE(Release, &Transmitter->StoreInterface);
Transmitter->Ring = NULL;
Transmitter->MaxQueues = 0;
- XENBUS_CACHE(Release, &Transmitter->CacheInterface);
-
- XENBUS_RANGE_SET(Release, &Transmitter->RangeSetInterface);
-
Transmitter->Frontend = NULL;
RtlZeroMemory(&Transmitter->Lock,
return STATUS_SUCCESS;
}
+static DECLSPEC_NOINLINE VOID
+VifSuspendCallbackLate(
+ IN PVOID Argument
+ )
+{
+ PXENVIF_VIF_CONTEXT Context = Argument;
+ NTSTATUS status;
+
+ if (!Context->Enabled)
+ return;
+
+ status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
+ ASSERT(NT_SUCCESS(status));
+
+ // We do this three times to make sure switches take note
+ FrontendAdvertiseIpAddresses(Context->Frontend);
+ FrontendAdvertiseIpAddresses(Context->Frontend);
+ FrontendAdvertiseIpAddresses(Context->Frontend);
+}
+
static NTSTATUS
VifEnable(
IN PINTERFACE Interface,
{
PXENVIF_VIF_CONTEXT Context = Interface->Context;
KIRQL Irql;
+ BOOLEAN Exclusive;
NTSTATUS status;
Trace("====>\n");
AcquireMrswLockExclusive(&Context->Lock, &Irql);
+ Exclusive = TRUE;
if (Context->Enabled)
goto done;
KeMemoryBarrier();
- status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
+ status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
if (!NT_SUCCESS(status))
goto fail1;
+ status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = XENBUS_SUSPEND(Register,
+ &Context->SuspendInterface,
+ SUSPEND_CALLBACK_LATE,
+ VifSuspendCallbackLate,
+ Context,
+ &Context->SuspendCallbackLate);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
done:
+ ASSERT(Exclusive);
ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
Trace("<====\n");
return STATUS_SUCCESS;
+fail3:
+ Error("fail3\n");
+
+ (VOID) FrontendSetState(Context->Frontend, FRONTEND_CONNECTED);
+
+ ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE);
+ Exclusive = FALSE;
+
+ ReceiverWaitForPackets(FrontendGetReceiver(Context->Frontend));
+ TransmitterAbortPackets(FrontendGetTransmitter(Context->Frontend));
+
+ Trace("waiting for mac thread..\n");
+
+ KeClearEvent(&Context->MacEvent);
+ ThreadWake(Context->MacThread);
+
+ (VOID) KeWaitForSingleObject(&Context->MacEvent,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ Trace("done\n");
+
+fail2:
+ Error("fail2\n");
+
+ XENBUS_SUSPEND(Release, &Context->SuspendInterface);
+
fail1:
Error("fail1 (%08x)\n", status);
+ Context->Enabled = FALSE;
+
+ KeMemoryBarrier();
+
Context->Argument = NULL;
Context->Callback = NULL;
- ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
+ if (Exclusive)
+ ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
+ else
+ ReleaseMrswLockShared(&Context->Lock);
return status;
}
KeMemoryBarrier();
+ XENBUS_SUSPEND(Deregister,
+ &Context->SuspendInterface,
+ Context->SuspendCallbackLate);
+ Context->SuspendCallbackLate = NULL;
+
(VOID) FrontendSetState(Context->Frontend, FRONTEND_CONNECTED);
ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE);
Trace("done\n");
+ XENBUS_SUSPEND(Release, &Context->SuspendInterface);
+
Context->Argument = NULL;
Context->Callback = NULL;
ReleaseMrswLockShared(&Context->Lock);
}
-static DECLSPEC_NOINLINE VOID
-VifSuspendCallbackLate(
- IN PVOID Argument
- )
-{
- PXENVIF_VIF_CONTEXT Context = Argument;
- NTSTATUS status;
-
- if (!Context->Enabled)
- return;
-
- status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
- ASSERT(NT_SUCCESS(status));
-
- // We do this three times to make sure switches take note
- FrontendAdvertiseIpAddresses(Context->Frontend);
- FrontendAdvertiseIpAddresses(Context->Frontend);
- FrontendAdvertiseIpAddresses(Context->Frontend);
-}
-
static NTSTATUS
VifAcquire(
PINTERFACE Interface
{
PXENVIF_VIF_CONTEXT Context = Interface->Context;
KIRQL Irql;
- NTSTATUS status;
AcquireMrswLockExclusive(&Context->Lock, &Irql);
Trace("====>\n");
- status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = XENBUS_SUSPEND(Register,
- &Context->SuspendInterface,
- SUSPEND_CALLBACK_LATE,
- VifSuspendCallbackLate,
- Context,
- &Context->SuspendCallbackLate);
- if (!NT_SUCCESS(status))
- goto fail2;
-
Context->Frontend = PdoGetFrontend(Context->Pdo);
Trace("<====\n");
ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
return STATUS_SUCCESS;
-
-fail2:
- Error("fail2\n");
-
- XENBUS_SUSPEND(Release, &Context->SuspendInterface);
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- --Context->References;
- ASSERT3U(Context->References, ==, 0);
- ReleaseMrswLockExclusive(&Context->Lock, Irql, FALSE);
-
- return status;
}
VOID
Context->Frontend = NULL;
- XENBUS_SUSPEND(Deregister,
- &Context->SuspendInterface,
- Context->SuspendCallbackLate);
- Context->SuspendCallbackLate = NULL;
-
- XENBUS_SUSPEND(Release, &Context->SuspendInterface);
-
Trace("<====\n");
done: