win-pvdrivers

changeset 138:7ff0dd6ba883

Lots of changes to try and resolve the crash-on-unload problem with xennet. No fix though.
author James Harper <james.harper@bendigoit.com.au>
date Sun Jan 20 22:57:30 2008 +1100 (2008-01-20)
parents 76b6a278e97d
children 00e9b5835d28
files common/include/xen_windows.h xennet/sources xennet/xennet.c xenpci/evtchn.c xenpci/gnttbl.c xenpci/sources xenpci/xenbus.c xenpci/xenpci.c xenpci/xenpci.h
line diff
     1.1 --- a/common/include/xen_windows.h	Sat Jan 19 17:42:05 2008 +1100
     1.2 +++ b/common/include/xen_windows.h	Sun Jan 20 22:57:30 2008 +1100
     1.3 @@ -104,12 +104,12 @@ AllocatePages(int Pages)
     1.4    PMDL Mdl;
     1.5    PVOID Buf;
     1.6  
     1.7 -  //KdPrint((__DRIVER_NAME " --- AllocatePages IRQL = %d\n", KeGetCurrentIrql()));
     1.8    Buf = ExAllocatePoolWithTag(NonPagedPool, Pages * PAGE_SIZE, ALLOCATE_PAGES_POOL_TAG);
     1.9    if (Buf == NULL)
    1.10    {
    1.11      KdPrint((__DRIVER_NAME "     AllocatePages Failed at ExAllocatePoolWithTag\n"));
    1.12    }
    1.13 +  KdPrint((__DRIVER_NAME " --- AllocatePages IRQL = %d, Buf = %p\n", KeGetCurrentIrql(), Buf));
    1.14    Mdl = IoAllocateMdl(Buf, Pages * PAGE_SIZE, FALSE, FALSE, NULL);
    1.15    if (Mdl == NULL)
    1.16    {
    1.17 @@ -130,7 +130,7 @@ static VOID
    1.18  FreePages(PMDL Mdl)
    1.19  {
    1.20    PVOID Buf = MmGetMdlVirtualAddress(Mdl);
    1.21 -  //KdPrint((__DRIVER_NAME " --- FreePages IRQL = %d\n", KeGetCurrentIrql()));
    1.22 +  KdPrint((__DRIVER_NAME " --- FreePages IRQL = %d, Buf = %p\n", KeGetCurrentIrql(), Buf));
    1.23    IoFreeMdl(Mdl);
    1.24    ExFreePoolWithTag(Buf, ALLOCATE_PAGES_POOL_TAG);
    1.25  }
     2.1 --- a/xennet/sources	Sat Jan 19 17:42:05 2008 +1100
     2.2 +++ b/xennet/sources	Sun Jan 20 22:57:30 2008 +1100
     2.3 @@ -1,7 +1,7 @@
     2.4  TARGETNAME=XENNET
     2.5  TARGETTYPE=DRIVER
     2.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     2.7 -VERSION=0.5.0.102
     2.8 +VERSION=0.5.0.142
     2.9  KMDF_VERSION=1
    2.10  MSC_WARNING_LEVEL=/W4
    2.11  INF_NAME=xennet
     3.1 --- a/xennet/xennet.c	Sat Jan 19 17:42:05 2008 +1100
     3.2 +++ b/xennet/xennet.c	Sun Jan 20 22:57:30 2008 +1100
     3.3 @@ -32,8 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fi
     3.4  
     3.5  #define GRANT_INVALID_REF 0
     3.6  
     3.7 -#define XEN_DOESNT_UNGRANT_RINGS 1
     3.8 -
     3.9  /* couldn't get regular xen ring macros to work...*/
    3.10  #define __NET_RING_SIZE(type, _sz) \
    3.11      (__RD32( \
    3.12 @@ -89,14 +87,9 @@ struct xennet_info
    3.13    struct netif_tx_sring *tx_pgs;
    3.14    struct netif_rx_sring *rx_pgs;
    3.15  
    3.16 -#if !defined(XEN_DOESNT_UNGRANT_RINGS)
    3.17    /* MDLs for the above */
    3.18    PMDL tx_mdl;
    3.19    PMDL rx_mdl;
    3.20 -#else
    3.21 -  PHYSICAL_ADDRESS tx_phys;
    3.22 -  PHYSICAL_ADDRESS rx_phys;
    3.23 -#endif
    3.24  
    3.25    /* Packets given to netback. The first entry in tx_pkts
    3.26     * is an index into a chain of free entries. */
    3.27 @@ -107,7 +100,7 @@ struct xennet_info
    3.28    grant_ref_t gref_tx_head;
    3.29    grant_ref_t grant_tx_ref[NET_TX_RING_SIZE+1];
    3.30    grant_ref_t gref_rx_head;
    3.31 -  grant_ref_t grant_rx_ref[NET_TX_RING_SIZE];
    3.32 +  grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
    3.33  
    3.34    /* Receive-ring batched refills. */
    3.35  #define RX_MIN_TARGET 8
    3.36 @@ -165,7 +158,7 @@ simple_strtoul(const char *cp,char **end
    3.37    if (endp)
    3.38    *endp = (char *)cp;
    3.39    return result;
    3.40 - }
    3.41 +}
    3.42  
    3.43  static void
    3.44  add_id_to_freelist(struct xennet_info *xi, unsigned short id)
    3.45 @@ -199,6 +192,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
    3.46    PNDIS_PACKET pkt;
    3.47    PMDL pmdl;
    3.48    KIRQL OldIrql;
    3.49 +  PVOID ptr;
    3.50  
    3.51    ASSERT(xi->connected);
    3.52  
    3.53 @@ -226,10 +220,11 @@ XenNet_TxBufferGC(struct xennet_info *xi
    3.54  
    3.55        /* free linearized data page */
    3.56        pmdl = *(PMDL *)pkt->MiniportReservedEx;
    3.57 -      NdisFreeMemory(MmGetMdlVirtualAddress(pmdl), 0, 0); // <= DISPATCH_LEVEL
    3.58 -NdisAlloc--;
    3.59 +      ptr = MmGetMdlVirtualAddress(pmdl);
    3.60        IoFreeMdl(pmdl);
    3.61  MdlAlloc--;
    3.62 +      NdisFreeMemory(ptr, 0, 0); // <= DISPATCH_LEVEL
    3.63 +NdisAlloc--;
    3.64  
    3.65        InterlockedDecrement(&xi->tx_outstanding);
    3.66        xi->stat_tx_ok++;
    3.67 @@ -268,6 +263,7 @@ XenNet_TxBufferFree(struct xennet_info *
    3.68    PMDL pmdl;
    3.69    PLIST_ENTRY entry;
    3.70    unsigned short id;
    3.71 +  PVOID ptr;
    3.72  
    3.73    ASSERT(!xi->connected);
    3.74  
    3.75 @@ -275,14 +271,16 @@ XenNet_TxBufferFree(struct xennet_info *
    3.76    entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
    3.77    while (entry != &xi->tx_waiting_pkt_list)
    3.78    {
    3.79 -    packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[4]);
    3.80 +    packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
    3.81  
    3.82      /* free linearized data page */
    3.83      pmdl = *(PMDL *)packet->MiniportReservedEx;
    3.84 -    NdisFreeMemory(MmGetMdlVirtualAddress(pmdl), 0, 0); // <= DISPATCH_LEVEL
    3.85 -NdisAlloc--;
    3.86 +    ptr = MmGetMdlVirtualAddress(pmdl);
    3.87 +KdPrint((__DRIVER_NAME " --- TxBufferFree %p\n", ptr));
    3.88      IoFreeMdl(pmdl);
    3.89  MdlAlloc--;
    3.90 +    NdisFreeMemory(ptr, 0, 0); // <= DISPATCH_LEVEL
    3.91 +NdisAlloc--;
    3.92  
    3.93      NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_FAILURE);
    3.94  
    3.95 @@ -302,10 +300,12 @@ MdlAlloc--;
    3.96  
    3.97      /* free linearized data page */
    3.98      pmdl = *(PMDL *)packet->MiniportReservedEx;
    3.99 -    NdisFreeMemory(MmGetMdlVirtualAddress(pmdl), 0, 0); // <= DISPATCH_LEVEL
   3.100 -NdisAlloc--;
   3.101 +    ptr = MmGetMdlVirtualAddress(pmdl);
   3.102 +KdPrint((__DRIVER_NAME " --- TxBufferFree %p\n", ptr));
   3.103      IoFreeMdl(pmdl);
   3.104  MdlAlloc--;
   3.105 +    NdisFreeMemory(ptr, 0, 0); // <= DISPATCH_LEVEL
   3.106 +NdisAlloc--;
   3.107  
   3.108      NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_FAILURE);
   3.109    }
   3.110 @@ -406,6 +406,7 @@ XenNet_RxBufferFree(struct xennet_info *
   3.111      buff_va = NdisBufferVirtualAddressSafe(buffer, NormalPagePriority);
   3.112      NdisFreeBuffer(buffer);
   3.113  BufferAlloc--;
   3.114 +KdPrint((__DRIVER_NAME " --- RxBufferFree %p\n", buff_va));
   3.115      NdisFreeMemory(buff_va, 0, 0);
   3.116  NdisAlloc--;
   3.117    }
   3.118 @@ -547,6 +548,7 @@ PacketAlloc++;
   3.119  }
   3.120  
   3.121  // Called at DISPATCH_LEVEL
   3.122 +
   3.123  static BOOLEAN
   3.124  XenNet_Interrupt(
   3.125    PKINTERRUPT Interrupt,
   3.126 @@ -558,13 +560,11 @@ XenNet_Interrupt(
   3.127    UNREFERENCED_PARAMETER(Interrupt);
   3.128  
   3.129  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.130 -
   3.131    if (xi->connected)
   3.132    {
   3.133      XenNet_TxBufferGC(xi);
   3.134      XenNet_RxBufferCheck(xi);
   3.135    }
   3.136 -
   3.137  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.138  
   3.139    return TRUE;
   3.140 @@ -577,33 +577,19 @@ XenNet_BackEndStateHandler(char *Path, P
   3.141  {
   3.142    struct xennet_info *xi = Data;
   3.143    char *Value;
   3.144 -  char TmpPath[MAX_XENBUS_STR_LEN];
   3.145 -  xenbus_transaction_t xbt = 0;
   3.146 -  int retry = 0;
   3.147    char *err;
   3.148 -  int i;
   3.149    ULONG new_backend_state;
   3.150  
   3.151 -  struct set_params {
   3.152 -    char *name;
   3.153 -    int value;
   3.154 -  } params[] = {
   3.155 -    {"tx-ring-ref", 0},
   3.156 -    {"rx-ring-ref", 0},
   3.157 -    {"event-channel", 0},
   3.158 -    {"request-rx-copy", 1},
   3.159 -    {"feature-rx-notify", 1},
   3.160 -    {"feature-no-csum-offload", 1},
   3.161 -    {"feature-sg", 1},
   3.162 -    {"feature-gso-tcpv4", 0},
   3.163 -    {NULL, 0},
   3.164 -  };
   3.165 -
   3.166    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.167    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   3.168  
   3.169 -  xi->XenInterface.XenBus_Read(xi->XenInterface.InterfaceHeader.Context,
   3.170 +  err = xi->XenInterface.XenBus_Read(xi->XenInterface.InterfaceHeader.Context,
   3.171      XBT_NIL, Path, &Value);
   3.172 +  if (err)
   3.173 +  {
   3.174 +    KdPrint(("Failed to read %s\n", Path, err));
   3.175 +    return;
   3.176 +  }
   3.177    new_backend_state = atoi(Value);
   3.178    xi->XenInterface.FreeMem(Value);
   3.179  
   3.180 @@ -628,96 +614,6 @@ XenNet_BackEndStateHandler(char *Path, P
   3.181  
   3.182    case XenbusStateInitWait:
   3.183      KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait\n"));  
   3.184 -
   3.185 -    xi->event_channel = xi->XenInterface.EvtChn_AllocUnbound(
   3.186 -      xi->XenInterface.InterfaceHeader.Context, 0);
   3.187 -    xi->XenInterface.EvtChn_BindDpc(xi->XenInterface.InterfaceHeader.Context,
   3.188 -      xi->event_channel, XenNet_Interrupt, xi);
   3.189 -
   3.190 -#if !defined(XEN_DOESNT_UNGRANT_RINGS)
   3.191 -    xi->tx_mdl = AllocatePage();
   3.192 -PageAlloc++;
   3.193 -    xi->tx_pgs = MmGetMdlVirtualAddress(xi->tx_mdl);
   3.194 -    SHARED_RING_INIT(xi->tx_pgs);
   3.195 -    FRONT_RING_INIT(&xi->tx, xi->tx_pgs, PAGE_SIZE);
   3.196 -    xi->tx_ring_ref = xi->XenInterface.GntTbl_GrantAccess(
   3.197 -      xi->XenInterface.InterfaceHeader.Context, 0,
   3.198 -      *MmGetMdlPfnArray(xi->tx_mdl), FALSE);
   3.199 -
   3.200 -    xi->rx_mdl = AllocatePage();
   3.201 -PageAlloc++;
   3.202 -    xi->rx_pgs = MmGetMdlVirtualAddress(xi->rx_mdl);
   3.203 -    SHARED_RING_INIT(xi->rx_pgs);
   3.204 -    FRONT_RING_INIT(&xi->rx, xi->rx_pgs, PAGE_SIZE);
   3.205 -    xi->rx_ring_ref = xi->XenInterface.GntTbl_GrantAccess(
   3.206 -      xi->XenInterface.InterfaceHeader.Context, 0,
   3.207 -      *MmGetMdlPfnArray(xi->rx_mdl), FALSE);
   3.208 -#else
   3.209 -    xi->tx_phys = xi->XenInterface.AllocMMIO(
   3.210 -      xi->XenInterface.InterfaceHeader.Context, PAGE_SIZE);
   3.211 -KdPrint(("tx_phys = %08x\n", xi->tx_phys.LowPart));
   3.212 -    xi->tx_pgs = MmMapIoSpace(xi->tx_phys,
   3.213 -      PAGE_SIZE, MmNonCached);
   3.214 -KdPrint(("tx_pgs = %08p\n", xi->tx_pgs));
   3.215 -    SHARED_RING_INIT(xi->tx_pgs);
   3.216 -    FRONT_RING_INIT(&xi->tx, xi->tx_pgs, PAGE_SIZE);
   3.217 -KdPrint(("tx_pfn = %08x\n", xi->tx_phys.QuadPart >> PAGE_SHIFT));
   3.218 -    xi->tx_ring_ref = xi->XenInterface.GntTbl_GrantAccess(
   3.219 -      xi->XenInterface.InterfaceHeader.Context, 0,
   3.220 -      (ULONG)(xi->tx_phys.QuadPart >> PAGE_SHIFT), FALSE);
   3.221 -KdPrint(("tx_ring_ref = %08x\n", xi->tx_ring_ref));
   3.222 -
   3.223 -    xi->rx_phys = xi->XenInterface.AllocMMIO(
   3.224 -      xi->XenInterface.InterfaceHeader.Context, PAGE_SIZE);
   3.225 -KdPrint(("rx_phys = %08x\n", xi->rx_phys.LowPart));
   3.226 -    xi->rx_pgs = MmMapIoSpace(xi->rx_phys,
   3.227 -      PAGE_SIZE, MmNonCached);
   3.228 -KdPrint(("rx_pgs = %08x\n", xi->rx_pgs));
   3.229 -    SHARED_RING_INIT(xi->rx_pgs);
   3.230 -    FRONT_RING_INIT(&xi->rx, xi->rx_pgs, PAGE_SIZE);
   3.231 -    xi->rx_ring_ref = xi->XenInterface.GntTbl_GrantAccess(
   3.232 -      xi->XenInterface.InterfaceHeader.Context, 0,
   3.233 -      (ULONG)(xi->rx_phys.QuadPart >> PAGE_SHIFT), FALSE);
   3.234 -KdPrint(("rx_ring_ref = %08x\n", xi->rx_ring_ref));
   3.235 -#endif
   3.236 -
   3.237 -    /* fixup array for dynamic values */
   3.238 -    params[0].value = xi->tx_ring_ref;
   3.239 -    params[1].value = xi->rx_ring_ref;
   3.240 -    params[2].value = xi->event_channel;
   3.241 -
   3.242 -    xi->XenInterface.XenBus_StartTransaction(
   3.243 -      xi->XenInterface.InterfaceHeader.Context, &xbt);
   3.244 -
   3.245 -    for (i = 0; params[i].name; i++)
   3.246 -    {
   3.247 -      RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/%s",
   3.248 -        xi->pdo_data->Path, params[i].name);
   3.249 -      err = xi->XenInterface.XenBus_Printf(xi->XenInterface.InterfaceHeader.Context,
   3.250 -        XBT_NIL, TmpPath, "%d", params[i].value);
   3.251 -      if (err)
   3.252 -      {
   3.253 -        KdPrint(("setting %s failed, err = %s\n", params[i].name, err));
   3.254 -        goto trouble;
   3.255 -      }
   3.256 -    }
   3.257 -
   3.258 -    /* commit transaction */
   3.259 -    xi->XenInterface.XenBus_EndTransaction(xi->XenInterface.InterfaceHeader.Context,
   3.260 -      xbt, 0, &retry);
   3.261 -
   3.262 -    XenNet_RxBufferAlloc(xi);
   3.263 -
   3.264 -    xi->state = XenbusStateConnected;
   3.265 -    KdPrint((__DRIVER_NAME "     Set Frontend state to Connected\n"));
   3.266 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/state", xi->pdo_data->Path);
   3.267 -    xi->XenInterface.XenBus_Printf(xi->XenInterface.InterfaceHeader.Context,
   3.268 -      XBT_NIL, TmpPath, "%d", xi->state);
   3.269 -
   3.270 -    /* send fake arp? */
   3.271 -
   3.272 -    xi->connected = TRUE;
   3.273 -
   3.274      break;
   3.275  
   3.276    case XenbusStateInitialised:
   3.277 @@ -746,12 +642,6 @@ KdPrint(("rx_ring_ref = %08x\n", xi->rx_
   3.278    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.279  
   3.280    return;
   3.281 -
   3.282 -trouble:
   3.283 -  KdPrint((__DRIVER_NAME __FUNCTION__ ": Should never happen!\n"));
   3.284 -  xi->XenInterface.XenBus_EndTransaction(xi->XenInterface.InterfaceHeader.Context,
   3.285 -    xbt, 1, &retry);
   3.286 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.287  }
   3.288  
   3.289  static NDIS_STATUS
   3.290 @@ -773,6 +663,23 @@ XenNet_Init(
   3.291    char *res;
   3.292    char *Value;
   3.293    char TmpPath[MAX_XENBUS_STR_LEN];
   3.294 +  struct set_params {
   3.295 +    char *name;
   3.296 +    int value;
   3.297 +  } params[] = {
   3.298 +    {"tx-ring-ref", 0},
   3.299 +    {"rx-ring-ref", 0},
   3.300 +    {"event-channel", 0},
   3.301 +    {"request-rx-copy", 1},
   3.302 +    {"feature-rx-notify", 1},
   3.303 +    {"feature-no-csum-offload", 1},
   3.304 +    {"feature-sg", 1},
   3.305 +    {"feature-gso-tcpv4", 0},
   3.306 +    {NULL, 0},
   3.307 +  };
   3.308 +  int retry = 0;
   3.309 +  char *err;
   3.310 +  xenbus_transaction_t xbt = 0;
   3.311  
   3.312    UNREFERENCED_PARAMETER(OpenErrorStatus);
   3.313    UNREFERENCED_PARAMETER(WrapperConfigurationContext);
   3.314 @@ -818,10 +725,10 @@ NdisAlloc++;
   3.315  
   3.316    KeInitializeSpinLock(&xi->tx_lock);
   3.317    KeInitializeSpinLock(&xi->rx_lock);
   3.318 +
   3.319    InitializeListHead(&xi->rx_free_pkt_list);
   3.320    InitializeListHead(&xi->tx_waiting_pkt_list);
   3.321    
   3.322 -
   3.323    NdisAllocatePacketPool(&status, &xi->packet_pool, NET_RX_RING_SIZE,
   3.324      PROTOCOL_RESERVED_SIZE_IN_PACKET);
   3.325  PacketPoolAlloc++;
   3.326 @@ -851,7 +758,6 @@ BufferPoolAlloc++;
   3.327      xi->tx_pkts[i] = IntToPtr(i + 1);
   3.328      xi->grant_tx_ref[i] = GRANT_INVALID_REF;
   3.329    }
   3.330 -
   3.331    for (i = 0; i < NET_RX_RING_SIZE; i++) {
   3.332      xi->rx_buffers[i] = NULL;
   3.333      xi->grant_rx_ref[i] = GRANT_INVALID_REF;
   3.334 @@ -907,21 +813,9 @@ BufferPoolAlloc++;
   3.335      goto err;
   3.336    }
   3.337    RtlStringCbCopyA(xi->backend_path, ARRAY_SIZE(xi->backend_path), Value);
   3.338 +  xi->XenInterface.FreeMem(Value);
   3.339    KdPrint((__DRIVER_NAME "backend path = %s\n", xi->backend_path));
   3.340  
   3.341 -  RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/type", xi->backend_path);
   3.342 -  res = xi->XenInterface.XenBus_Read(xi->XenInterface.InterfaceHeader.Context,
   3.343 -      XBT_NIL, TmpPath, &Value);
   3.344 -
   3.345 -#if 0
   3.346 -  if (res || strcmp(Value, "netfront") != 0)
   3.347 -  {
   3.348 -    KdPrint((__DRIVER_NAME "    Backend type is not 'netfront'\n"));
   3.349 -    status = NDIS_STATUS_FAILURE;
   3.350 -    goto err;
   3.351 -  }
   3.352 -#endif
   3.353 -
   3.354    KeInitializeEvent(&xi->backend_state_change_event, SynchronizationEvent, FALSE);  
   3.355    KeInitializeEvent(&xi->shutdown_event, SynchronizationEvent, FALSE);  
   3.356  
   3.357 @@ -935,6 +829,72 @@ BufferPoolAlloc++;
   3.358    xi->XenInterface.XenBus_Printf(xi->XenInterface.InterfaceHeader.Context,
   3.359      XBT_NIL, TmpPath, "%d", XenbusStateInitialising);
   3.360  
   3.361 +  // wait here for signal that we are all set up
   3.362 +  while (xi->backend_state != XenbusStateInitWait)
   3.363 +    KeWaitForSingleObject(&xi->backend_state_change_event, Executive, KernelMode, FALSE, NULL);
   3.364 +
   3.365 +  xi->event_channel = xi->XenInterface.EvtChn_AllocUnbound(
   3.366 +    xi->XenInterface.InterfaceHeader.Context, 0);
   3.367 +  xi->XenInterface.EvtChn_BindDpc(xi->XenInterface.InterfaceHeader.Context,
   3.368 +    xi->event_channel, XenNet_Interrupt, xi);
   3.369 +
   3.370 +  xi->tx_mdl = AllocatePage();
   3.371 +PageAlloc++;
   3.372 +  xi->tx_pgs = MmGetMdlVirtualAddress(xi->tx_mdl);
   3.373 +  SHARED_RING_INIT(xi->tx_pgs);
   3.374 +  FRONT_RING_INIT(&xi->tx, xi->tx_pgs, PAGE_SIZE);
   3.375 +  xi->tx_ring_ref = xi->XenInterface.GntTbl_GrantAccess(
   3.376 +    xi->XenInterface.InterfaceHeader.Context, 0,
   3.377 +    *MmGetMdlPfnArray(xi->tx_mdl), FALSE);
   3.378 +
   3.379 +  xi->rx_mdl = AllocatePage();
   3.380 +PageAlloc++;
   3.381 +  xi->rx_pgs = MmGetMdlVirtualAddress(xi->rx_mdl);
   3.382 +  SHARED_RING_INIT(xi->rx_pgs);
   3.383 +  FRONT_RING_INIT(&xi->rx, xi->rx_pgs, PAGE_SIZE);
   3.384 +  xi->rx_ring_ref = xi->XenInterface.GntTbl_GrantAccess(
   3.385 +    xi->XenInterface.InterfaceHeader.Context, 0,
   3.386 +    *MmGetMdlPfnArray(xi->rx_mdl), FALSE);
   3.387 +
   3.388 +  /* fixup array for dynamic values */
   3.389 +  params[0].value = xi->tx_ring_ref;
   3.390 +  params[1].value = xi->rx_ring_ref;
   3.391 +  params[2].value = xi->event_channel;
   3.392 +  xi->XenInterface.XenBus_StartTransaction(
   3.393 +    xi->XenInterface.InterfaceHeader.Context, &xbt);
   3.394 +
   3.395 +  for (err = NULL, i = 0; params[i].name; i++)
   3.396 +  {
   3.397 +    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/%s",
   3.398 +      xi->pdo_data->Path, params[i].name);
   3.399 +    err = xi->XenInterface.XenBus_Printf(xi->XenInterface.InterfaceHeader.Context,
   3.400 +      XBT_NIL, TmpPath, "%d", params[i].value);
   3.401 +    if (err)
   3.402 +    {
   3.403 +      KdPrint(("setting %s failed, err = %s\n", params[i].name, err));
   3.404 +      break;
   3.405 +    }
   3.406 +  }
   3.407 +
   3.408 +  xi->XenInterface.XenBus_EndTransaction(xi->XenInterface.InterfaceHeader.Context,
   3.409 +    xbt, 1, &retry);
   3.410 +  if (err)
   3.411 +  {
   3.412 +    status = NDIS_STATUS_FAILURE;
   3.413 +    goto err;
   3.414 +  } 
   3.415 +  XenNet_RxBufferAlloc(xi);
   3.416 +
   3.417 +  xi->connected = TRUE;
   3.418 +
   3.419 +  KeMemoryBarrier(); // packets could be received anytime after we set Frontent to Connected
   3.420 +
   3.421 +  xi->state = XenbusStateConnected;
   3.422 +  KdPrint((__DRIVER_NAME "     Set Frontend state to Connected\n"));
   3.423 +  RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/state", xi->pdo_data->Path);
   3.424 +  xi->XenInterface.XenBus_Printf(xi->XenInterface.InterfaceHeader.Context,
   3.425 +    XBT_NIL, TmpPath, "%d", xi->state);
   3.426 +
   3.427    KdPrint((__DRIVER_NAME "     Waiting for backend to connect\n"));
   3.428  
   3.429    // wait here for signal that we are all set up
   3.430 @@ -971,6 +931,8 @@ BufferPoolAlloc++;
   3.431      xi->XenInterface.FreeMem(Value);
   3.432    }
   3.433  
   3.434 +  /* send fake arp? */
   3.435 +
   3.436    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.437  
   3.438    return NDIS_STATUS_SUCCESS;
   3.439 @@ -1502,8 +1464,7 @@ NdisAlloc++;
   3.440      KdPrint(("Could not allocate memory for linearization\n"));
   3.441      return NULL;
   3.442    }
   3.443 -  pmdl = IoAllocateMdl(start, tot_buff_len, FALSE, FALSE, FALSE);
   3.444 -MdlAlloc++;
   3.445 +  pmdl = IoAllocateMdl(start, tot_buff_len, FALSE, FALSE, NULL);
   3.446    if (!pmdl)
   3.447    {
   3.448      KdPrint(("Could not allocate MDL for linearization\n"));
   3.449 @@ -1511,6 +1472,7 @@ MdlAlloc++;
   3.450  NdisAlloc--;
   3.451      return NULL;
   3.452    }
   3.453 +MdlAlloc++;
   3.454    MmBuildMdlForNonPagedPool(pmdl);
   3.455  
   3.456    while (buffer)
   3.457 @@ -1543,7 +1505,7 @@ XenNet_SendQueuedPackets(struct xennet_i
   3.458    /* if empty, the above returns head*, not NULL */
   3.459    while (entry != &xi->tx_waiting_pkt_list)
   3.460    {
   3.461 -    packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[4]);
   3.462 +    packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   3.463  
   3.464      NdisQueryPacket(packet, NULL, NULL, NULL, &pkt_size);
   3.465      pmdl = *(PMDL *)packet->MiniportReservedEx;
   3.466 @@ -1552,7 +1514,7 @@ XenNet_SendQueuedPackets(struct xennet_i
   3.467      if (!id)
   3.468      {
   3.469        /* whups, out of space on the ring. requeue and get out */
   3.470 -      InsertHeadList(&xi->tx_waiting_pkt_list, entry);
   3.471 +      InsertTailList(&xi->tx_waiting_pkt_list, entry);
   3.472        break;
   3.473      }
   3.474      xi->tx_pkts[id] = packet;
   3.475 @@ -1597,9 +1559,18 @@ XenNet_SendPackets(
   3.476    UINT i;
   3.477    PMDL pmdl;
   3.478    PLIST_ENTRY entry;
   3.479 +  KIRQL OldIrql;
   3.480 +
   3.481 +#if 0
   3.482 +  for (i = 0; i < NumberOfPackets; i++)
   3.483 +  {
   3.484 +    curr_packet = PacketArray[i];
   3.485 +    NdisMSendComplete(xi->adapter_handle, curr_packet, NDIS_STATUS_FAILURE);
   3.486 +  }
   3.487 +  return;
   3.488 +#endif
   3.489  
   3.490  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.491 -
   3.492    for (i = 0; i < NumberOfPackets; i++)
   3.493    {
   3.494      curr_packet = PacketArray[i];
   3.495 @@ -1611,24 +1582,24 @@ XenNet_SendPackets(
   3.496      if (!pmdl)
   3.497      {
   3.498        KdPrint((__DRIVER_NAME "Couldn't linearize packet!\n"));
   3.499 -      NdisMSendComplete(xi, curr_packet, NDIS_STATUS_FAILURE);
   3.500 +      NdisMSendComplete(xi->adapter_handle, curr_packet, NDIS_STATUS_FAILURE);
   3.501        break;
   3.502      }
   3.503  
   3.504      /* NOTE: 
   3.505 -     * We use the UCHAR[12] array in each packet's MiniportReservedEx thusly:
   3.506 -     * 0-3: PMDL to linearized data
   3.507 -     * 4-11: LIST_ENTRY for placing packet on the waiting pkt list
   3.508 +     * We use the UCHAR[3*sizeof(PVOID)] array in each packet's MiniportReservedEx thusly:
   3.509 +     * 0: PMDL to linearized data
   3.510 +     * sizeof(PVOID)+: LIST_ENTRY for placing packet on the waiting pkt list
   3.511       */
   3.512      *(PMDL *)&curr_packet->MiniportReservedEx = pmdl;
   3.513  
   3.514 -    entry = (PLIST_ENTRY)&curr_packet->MiniportReservedEx[4];
   3.515 -    ExInterlockedInsertTailList(&xi->tx_waiting_pkt_list, entry, &xi->tx_lock);
   3.516 +    entry = (PLIST_ENTRY)&curr_packet->MiniportReservedEx[sizeof(PVOID)];
   3.517 +    KeAcquireSpinLock(&xi->tx_lock, &OldIrql);
   3.518 +    InsertTailList(&xi->tx_waiting_pkt_list, entry);
   3.519 +    KeReleaseSpinLock(&xi->tx_lock, OldIrql);
   3.520      InterlockedIncrement(&xi->tx_outstanding);
   3.521    }
   3.522 -
   3.523    XenNet_SendQueuedPackets(xi);
   3.524 -
   3.525  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.526  }
   3.527  
   3.528 @@ -1658,7 +1629,7 @@ XenNet_Shutdown(
   3.529  
   3.530    /* turn off interrupt */
   3.531    xi->XenInterface.EvtChn_Unbind(xi->XenInterface.InterfaceHeader.Context,
   3.532 -    xi->event_channel);  
   3.533 +    xi->event_channel);
   3.534  
   3.535    KdPrint((__FUNCTION__ " called\n"));
   3.536  }
   3.537 @@ -1675,8 +1646,8 @@ XenNet_Halt(
   3.538  
   3.539    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.540    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
   3.541 -  KdPrint((__DRIVER_NAME "     tx_outstanding = %d\n", xi->tx_outstanding));
   3.542 -  KdPrint((__DRIVER_NAME "     rx_outstanding = %d\n", xi->rx_outstanding));
   3.543 +//  KdPrint((__DRIVER_NAME "     tx_outstanding = %d\n", xi->tx_outstanding));
   3.544 +//  KdPrint((__DRIVER_NAME "     rx_outstanding = %d\n", xi->rx_outstanding));
   3.545  
   3.546    // this disables the interrupt
   3.547    XenNet_Shutdown(xi);
   3.548 @@ -1703,16 +1674,16 @@ XenNet_Halt(
   3.549        KernelMode, FALSE, NULL);
   3.550  
   3.551    xi->connected = FALSE;
   3.552 -
   3.553    /* wait for all receive buffers to be returned */
   3.554    KeMemoryBarrier(); /* make sure everyone sees that we are now shut down */
   3.555 +
   3.556    while (xi->rx_outstanding > 0)
   3.557      KeWaitForSingleObject(&xi->shutdown_event, Executive, KernelMode, FALSE, NULL);
   3.558  
   3.559    // TODO: remove event channel xenbus entry (how?)
   3.560  
   3.561 -  KdPrint((__DRIVER_NAME "     tx_outstanding = %d\n", xi->tx_outstanding));
   3.562 -  KdPrint((__DRIVER_NAME "     rx_outstanding = %d\n", xi->rx_outstanding));
   3.563 +//  KdPrint((__DRIVER_NAME "     tx_outstanding = %d\n", xi->tx_outstanding));
   3.564 +//  KdPrint((__DRIVER_NAME "     rx_outstanding = %d\n", xi->rx_outstanding));
   3.565  
   3.566  KdPrint((__DRIVER_NAME "     NdisAlloc = %d\n", NdisAlloc));
   3.567  KdPrint((__DRIVER_NAME "     MdlAlloc = %d\n", MdlAlloc));
   3.568 @@ -1721,8 +1692,6 @@ KdPrint((__DRIVER_NAME "     PacketAlloc
   3.569  KdPrint((__DRIVER_NAME "     PageAlloc = %d\n", PageAlloc));
   3.570  KdPrint((__DRIVER_NAME "     PacketPoolAlloc = %d\n", PacketPoolAlloc));
   3.571  KdPrint((__DRIVER_NAME "     BufferPoolAlloc = %d\n", BufferPoolAlloc));
   3.572 -
   3.573 -#if !defined(XEN_DOESNT_UNGRANT_RINGS)
   3.574    /* free TX resources */
   3.575    if (xi->XenInterface.GntTbl_EndAccess(if_cxt, xi->tx_ring_ref))
   3.576    {
   3.577 @@ -1742,7 +1711,6 @@ PageAlloc--;
   3.578  PageAlloc--;
   3.579    }
   3.580    xi->rx_pgs = NULL;
   3.581 -#endif
   3.582  
   3.583    XenNet_TxBufferFree(xi);
   3.584    XenNet_RxBufferFree(MiniportAdapterContext);
   3.585 @@ -1754,8 +1722,6 @@ PageAlloc--;
   3.586  
   3.587    xi->XenInterface.InterfaceHeader.InterfaceDereference(NULL);
   3.588  
   3.589 -  //WdfDriverMiniportUnload(WdfGetDriver()); // this should only happen on _driver_ unload
   3.590 -
   3.591    NdisFreeBufferPool(xi->buffer_pool);
   3.592  BufferPoolAlloc--;
   3.593    NdisFreePacketPool(xi->packet_pool);
     4.1 --- a/xenpci/evtchn.c	Sat Jan 19 17:42:05 2008 +1100
     4.2 +++ b/xenpci/evtchn.c	Sun Jan 20 22:57:30 2008 +1100
     4.3 @@ -134,8 +134,6 @@ EvtChn_BindDpc(PVOID Context, evtchn_por
     4.4    DpcObjectAttributes.ParentObject = Device;
     4.5    WdfDpcCreate(&DpcConfig, &DpcObjectAttributes, &xpdd->ev_actions[Port].Dpc);
     4.6    GetEvtChnDeviceData(xpdd->ev_actions[Port].Dpc)->Action = &xpdd->ev_actions[Port];
     4.7 -//  GetEvtChnDeviceData(xpdd->ev_actions[Port].Dpc)->shared_info_area = xpdd->shared_info_area;
     4.8 -//  GetEvtChnDeviceData(xpdd->ev_actions[Port].Dpc)->port = Port;
     4.9  
    4.10    KeMemoryBarrier(); // make sure that the new service routine is only called once the context is set up
    4.11    xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
     5.1 --- a/xenpci/gnttbl.c	Sat Jan 19 17:42:05 2008 +1100
     5.2 +++ b/xenpci/gnttbl.c	Sun Jan 20 22:57:30 2008 +1100
     5.3 @@ -109,7 +109,7 @@ GntTbl_GrantAccess(
     5.4  
     5.5    //KdPrint((__DRIVER_NAME " --> GntTbl_GrantAccess\n"));
     5.6  
     5.7 -  KdPrint((__DRIVER_NAME "     Granting access to frame %08x\n", frame));
     5.8 +  //KdPrint((__DRIVER_NAME "     Granting access to frame %08x\n", frame));
     5.9  
    5.10    /* TODO: locking? */
    5.11    ref = get_free_entry(Device);
     6.1 --- a/xenpci/sources	Sat Jan 19 17:42:05 2008 +1100
     6.2 +++ b/xenpci/sources	Sun Jan 20 22:57:30 2008 +1100
     6.3 @@ -1,7 +1,7 @@
     6.4  TARGETNAME=XENPCI
     6.5  TARGETTYPE=DRIVER
     6.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     6.7 -VERSION=0.5.0.37
     6.8 +VERSION=0.5.0.40
     6.9  KMDF_VERSION=1
    6.10  MSC_WARNING_LEVEL=/W4
    6.11  INF_NAME=xenpci
     7.1 --- a/xenpci/xenbus.c	Sat Jan 19 17:42:05 2008 +1100
     7.2 +++ b/xenpci/xenbus.c	Sun Jan 20 22:57:30 2008 +1100
     7.3 @@ -555,11 +555,20 @@ XenBus_WatchThreadProc(PVOID StartContex
     7.4        if (!entry->Active || !entry->ServiceRoutine)
     7.5        {
     7.6          KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
     7.7 +        KdPrint((__DRIVER_NAME "     No watch for index %d\n", index));
     7.8          continue;
     7.9        }
    7.10 +KdPrint((__DRIVER_NAME " --- About to call watch\n"));
    7.11 +      if (entry->RemovePending)
    7.12 +      {
    7.13 +        KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
    7.14 +        KdPrint((__DRIVER_NAME "     Not calling watch - remove is pending\n"));
    7.15 +        continue;
    7.16 +      }        
    7.17        entry->Running = 1;
    7.18        KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
    7.19        entry->Count++;
    7.20 +KdPrint((__DRIVER_NAME " --- for %s\n", xpdd->XenBus_WatchRing[xpdd->XenBus_WatchRingReadIndex].Path));
    7.21        entry->ServiceRoutine(xpdd->XenBus_WatchRing[xpdd->XenBus_WatchRingReadIndex].Path, entry->ServiceContext);
    7.22        entry->Running = 0;
    7.23        KeSetEvent(&entry->CompleteEvent, 1, FALSE);
    7.24 @@ -653,7 +662,7 @@ XenBus_RemWatch(
    7.25    struct write_req req[2];
    7.26    KIRQL OldIrql;
    7.27  
    7.28 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    7.29 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    7.30  
    7.31    KeAcquireSpinLock(&xpdd->WatchLock, &OldIrql);
    7.32  
    7.33 @@ -674,14 +683,21 @@ XenBus_RemWatch(
    7.34      return NULL;
    7.35    }
    7.36  
    7.37 -  while (xpdd->XenBus_WatchEntries[i].Running)
    7.38 +  if (xpdd->XenBus_WatchEntries[i].RemovePending)
    7.39    {
    7.40      KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
    7.41 +    KdPrint((__DRIVER_NAME "     Remove already pending - can't remove\n"));
    7.42 +    return NULL;
    7.43 +  }
    7.44 +  KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
    7.45 +
    7.46 +  while (xpdd->XenBus_WatchEntries[i].Running)
    7.47      KeWaitForSingleObject(&xpdd->XenBus_WatchEntries[i].CompleteEvent, Executive, KernelMode, FALSE, NULL);
    7.48 -    KeAcquireSpinLock(&xpdd->WatchLock, &OldIrql);
    7.49 -  }
    7.50 +
    7.51 +  KeAcquireSpinLock(&xpdd->WatchLock, &OldIrql);
    7.52  
    7.53    xpdd->XenBus_WatchEntries[i].Active = 0;
    7.54 +  xpdd->XenBus_WatchEntries[i].RemovePending = 0;
    7.55    xpdd->XenBus_WatchEntries[i].Path[0] = 0;
    7.56  
    7.57    KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
    7.58 @@ -701,9 +717,11 @@ XenBus_RemWatch(
    7.59      return msg;
    7.60    }
    7.61  
    7.62 +  ASSERT(rep != NULL);
    7.63 +
    7.64    ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    7.65  
    7.66 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    7.67 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    7.68  
    7.69    return NULL;
    7.70  }
     8.1 --- a/xenpci/xenpci.c	Sat Jan 19 17:42:05 2008 +1100
     8.2 +++ b/xenpci/xenpci.c	Sun Jan 20 22:57:30 2008 +1100
     8.3 @@ -293,9 +293,6 @@ init_xen_info(WDFDEVICE Device)
     8.4    int ret;
     8.5    PHYSICAL_ADDRESS shared_info_area_unmapped;
     8.6  
     8.7 -  //setup_xen_features();
     8.8 -  //KdPrint((__DRIVER_NAME " init_xen_info Hypercall area at %08x\n", hypercall_stubs));
     8.9 -
    8.10    shared_info_area_unmapped = XenPCI_AllocMMIO(Device, PAGE_SIZE);
    8.11    xatp.domid = DOMID_SELF;
    8.12    xatp.idx = 0;
     9.1 --- a/xenpci/xenpci.h	Sat Jan 19 17:42:05 2008 +1100
     9.2 +++ b/xenpci/xenpci.h	Sun Jan 20 22:57:30 2008 +1100
     9.3 @@ -90,6 +90,7 @@ typedef struct _XENBUS_WATCH_ENTRY {
     9.4    PVOID ServiceContext;
     9.5    int Count;
     9.6    int Active;
     9.7 +  int RemovePending;
     9.8    int Running;
     9.9    KEVENT CompleteEvent;
    9.10  } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;