win-pvdrivers

changeset 115:0d9e5303a8d2

- Fix 'unbind' so that the dpc (if any) is cancelled or completed before returning.
- Add code to make sure that no further calls will be made to ReturnPacket after _Halt is complete
Upgrading xennet.sys on a running system now appears to work properly again.
author James Harper <james.harper@bendigoit.com.au>
date Sat Jan 12 22:14:04 2008 +1100 (2008-01-12)
parents 64e4596aec1c
children ff8c14904e96
files xennet/sources xennet/xennet.c xenpci/evtchn.c xenpci/sources
line diff
     1.1 --- a/xennet/sources	Sat Jan 12 17:12:07 2008 +1100
     1.2 +++ b/xennet/sources	Sat Jan 12 22:14:04 2008 +1100
     1.3 @@ -1,7 +1,7 @@
     1.4  TARGETNAME=XENNET
     1.5  TARGETTYPE=DRIVER
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7 -VERSION=0.5.0.80
     1.8 +VERSION=0.5.0.85
     1.9  KMDF_VERSION=1
    1.10  MSC_WARNING_LEVEL=/W4
    1.11  INF_NAME=xennet
     2.1 --- a/xennet/xennet.c	Sat Jan 12 17:12:07 2008 +1100
     2.2 +++ b/xennet/xennet.c	Sat Jan 12 22:14:04 2008 +1100
     2.3 @@ -67,6 +67,7 @@ struct xennet_info
     2.4    evtchn_port_t event_channel;
     2.5    ULONG state;
     2.6    KEVENT backend_state_change_event;
     2.7 +  KEVENT shutdown_event;
     2.8    char backend_path[MAX_XENBUS_STR_LEN];
     2.9    ULONG backend_state;
    2.10  
    2.11 @@ -109,6 +110,8 @@ struct xennet_info
    2.12    ULONG rx_max_target;
    2.13    ULONG rx_min_target;
    2.14  
    2.15 +  ULONG rx_outstanding;
    2.16 +
    2.17    /* stats */
    2.18    ULONG64 stat_tx_ok;
    2.19    ULONG64 stat_rx_ok;
    2.20 @@ -366,6 +369,7 @@ XenNet_ReturnPacket(
    2.21    IN PNDIS_PACKET Packet
    2.22    )
    2.23  {
    2.24 +  struct xennet_info *xi = MiniportAdapterContext;
    2.25    PNDIS_BUFFER buffer;
    2.26    PNDIS_BUFFER next_buffer;
    2.27    PVOID buff_va;
    2.28 @@ -374,8 +378,6 @@ XenNet_ReturnPacket(
    2.29  
    2.30  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.31  
    2.32 -  UNREFERENCED_PARAMETER(MiniportAdapterContext);
    2.33 -
    2.34    NdisGetFirstBufferFromPacketSafe(Packet, &buffer, &buff_va, &buff_len,
    2.35      &tot_buff_len, NormalPagePriority);
    2.36    ASSERT(tot_buff_len <= XN_MAX_PKT_SIZE);
    2.37 @@ -391,6 +393,11 @@ XenNet_ReturnPacket(
    2.38  
    2.39    NdisFreePacket(Packet);
    2.40  
    2.41 +  InterlockedDecrement(&xi->rx_outstanding);
    2.42 +  // if we are no longer connected then _halt probably needs to know when rx_outstanding reaches zero
    2.43 +  if (!xi->connected && !xi->rx_outstanding)
    2.44 +    KeSetEvent(&xi->shutdown_event, 1, FALSE);  
    2.45 +
    2.46  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.47  }
    2.48  
    2.49 @@ -466,6 +473,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    2.50        if (!more_frags)
    2.51        {
    2.52          xi->stat_rx_ok++;
    2.53 +        InterlockedIncrement(&xi->rx_outstanding);
    2.54          NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
    2.55          NdisMIndicateReceivePacket(xi->adapter_handle, &packet, 1);
    2.56        }
    2.57 @@ -838,6 +846,7 @@ XenNet_Init(
    2.58  #endif
    2.59  
    2.60    KeInitializeEvent(&xi->backend_state_change_event, SynchronizationEvent, FALSE);  
    2.61 +  KeInitializeEvent(&xi->shutdown_event, SynchronizationEvent, FALSE);  
    2.62  
    2.63    /* Add watch on backend state */
    2.64    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/state", xi->backend_path);
    2.65 @@ -1583,6 +1592,7 @@ XenNet_Halt(
    2.66    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.67    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
    2.68  
    2.69 +  // this disables the interrupt
    2.70    XenNet_Shutdown(xi);
    2.71  
    2.72    // set frontend state to 'closing'
    2.73 @@ -1608,6 +1618,11 @@ XenNet_Halt(
    2.74  
    2.75    xi->connected = FALSE;
    2.76  
    2.77 +  /* wait for all receive buffers to be returned */
    2.78 +  KeMemoryBarrier(); /* make sure everyone sees that we are now shut down */
    2.79 +  while (xi->rx_outstanding > 0)
    2.80 +    KeWaitForSingleObject(&xi->shutdown_event, Executive, KernelMode, FALSE, NULL);
    2.81 +
    2.82    // TODO: remove event channel xenbus entry (how?)
    2.83  
    2.84    /* free TX resources */
     3.1 --- a/xenpci/evtchn.c	Sat Jan 12 17:12:07 2008 +1100
     3.2 +++ b/xenpci/evtchn.c	Sat Jan 12 22:14:04 2008 +1100
     3.3 @@ -154,9 +154,13 @@ EvtChn_Unbind(PVOID Context, evtchn_port
     3.4    PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
     3.5  
     3.6    EvtChn_Mask(Context, Port);
     3.7 +  xpdd->ev_actions[Port].ServiceRoutine = NULL;
     3.8 +  KeMemoryBarrier();
     3.9    xpdd->ev_actions[Port].ServiceContext = NULL;
    3.10 -  xpdd->ev_actions[Port].ServiceRoutine = NULL;
    3.11  
    3.12 +  if (xpdd->ev_actions[Port].DpcFlag)
    3.13 +    WdfDpcCancel(xpdd->ev_actions[Port].Dpc, TRUE);
    3.14 +  
    3.15    //KdPrint((__DRIVER_NAME " <-- EvtChn_UnBind\n"));
    3.16  
    3.17    return STATUS_SUCCESS;
     4.1 --- a/xenpci/sources	Sat Jan 12 17:12:07 2008 +1100
     4.2 +++ b/xenpci/sources	Sat Jan 12 22:14:04 2008 +1100
     4.3 @@ -1,7 +1,7 @@
     4.4  TARGETNAME=XENPCI
     4.5  TARGETTYPE=DRIVER
     4.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     4.7 -VERSION=0.5.0.22
     4.8 +VERSION=0.5.0.23
     4.9  KMDF_VERSION=1
    4.10  MSC_WARNING_LEVEL=/W4
    4.11  INF_NAME=xenpci