win-pvdrivers

changeset 504:cb0b2da68686

big changes to xenbus interface. simplified it a bit. started work on userspace interface.
author James Harper <james.harper@bendigoit.com.au>
date Mon Dec 22 22:34:52 2008 +1100 (2008-12-22)
parents 81a13e8a064f
children f1be6c082c71
files common/include/xen_public.h xenpci/sources xenpci/xenbus.c xenpci/xenbus_device_interface.c xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c
line diff
     1.1 --- a/common/include/xen_public.h	Mon Dec 22 22:34:13 2008 +1100
     1.2 +++ b/common/include/xen_public.h	Mon Dec 22 22:34:52 2008 +1100
     1.3 @@ -23,9 +23,13 @@ Foundation, Inc., 51 Franklin Street, Fi
     1.4  #include <grant_table.h>
     1.5  #include <event_channel.h>
     1.6  #include <xen_guids.h>
     1.7 -//{5C568AC5-9DDF-4FA5-A94A-39D67077819C}
     1.8 +
     1.9 +// {5C568AC5-9DDF-4FA5-A94A-39D67077819C}
    1.10  DEFINE_GUID(GUID_XEN_IFACE, 0x5C568AC5, 0x9DDF, 0x4FA5, 0xA9, 0x4A, 0x39, 0xD6, 0x70, 0x77, 0x81, 0x9C);
    1.11  
    1.12 +// {14CE175A-3EE2-4fae-9252-00DBD84F018E}
    1.13 +DEFINE_GUID(GUID_XENBUS_IFACE, 0x14ce175a, 0x3ee2, 0x4fae, 0x92, 0x52, 0x0, 0xdb, 0xd8, 0x4f, 0x1, 0x8e);
    1.14 +
    1.15  #define INVALID_GRANT_REF 0xFFFFFFFF
    1.16  
    1.17  typedef PHYSICAL_ADDRESS
    1.18 @@ -72,13 +76,13 @@ typedef VOID
    1.19  (*PXENBUS_WATCH_CALLBACK)(char *Path, PVOID ServiceContext);
    1.20  
    1.21  typedef char *
    1.22 -(*PXEN_XENBUS_READ)(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
    1.23 +(*PXEN_XENBUS_READ)(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
    1.24  
    1.25  typedef char *
    1.26 -(*PXEN_XENBUS_WRITE)(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *value);
    1.27 +(*PXEN_XENBUS_WRITE)(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
    1.28  
    1.29  typedef char *
    1.30 -(*PXEN_XENBUS_PRINTF)(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *fmt, ...);
    1.31 +(*PXEN_XENBUS_PRINTF)(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
    1.32  
    1.33  typedef char *
    1.34  (*PXEN_XENBUS_STARTTRANSACTION)(PVOID Context, xenbus_transaction_t *xbt);
    1.35 @@ -87,13 +91,13 @@ typedef char *
    1.36  (*PXEN_XENBUS_ENDTRANSACTION)(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
    1.37  
    1.38  typedef char *
    1.39 -(*PXEN_XENBUS_LIST)(PVOID Context, xenbus_transaction_t xbt, const char *prefix, char ***contents);
    1.40 +(*PXEN_XENBUS_LIST)(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
    1.41  
    1.42  typedef char *
    1.43 -(*PXEN_XENBUS_ADDWATCH)(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
    1.44 +(*PXEN_XENBUS_ADDWATCH)(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
    1.45  
    1.46  typedef char *
    1.47 -(*PXEN_XENBUS_REMWATCH)(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
    1.48 +(*PXEN_XENBUS_REMWATCH)(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
    1.49  
    1.50  typedef NTSTATUS
    1.51  (*PXEN_XENPCI_XEN_CONFIG_DEVICE)(PVOID Context);
     2.1 --- a/xenpci/sources	Mon Dec 22 22:34:13 2008 +1100
     2.2 +++ b/xenpci/sources	Mon Dec 22 22:34:52 2008 +1100
     2.3 @@ -5,4 +5,4 @@ INF_NAME=$(TARGETNAME)
     2.4  MISCFILES=..\Target\$(DDK_TARGET_OS)\$(INF_NAME).inf
     2.5  TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\wdmsec.lib
     2.6  AMD64_SOURCES=hypercall.asm swint.asm
     2.7 -SOURCES=xenpci.c xenpci_fdo.c xenpci_pdo.c evtchn.c gnttbl.c xenbus.c memory.c
     2.8 \ No newline at end of file
     2.9 +SOURCES=xenpci.c xenpci_fdo.c xenpci_pdo.c evtchn.c gnttbl.c xenbus.c memory.c xenbus_device_interface.c
    2.10 \ No newline at end of file
     3.1 --- a/xenpci/xenbus.c	Mon Dec 22 22:34:13 2008 +1100
     3.2 +++ b/xenpci/xenbus.c	Mon Dec 22 22:34:52 2008 +1100
     3.3 @@ -18,14 +18,13 @@ Foundation, Inc., 51 Franklin Street, Fi
     3.4  */
     3.5  
     3.6  #include "xenpci.h"
     3.7 -#include "io/xs_wire.h"
     3.8  #include <stdlib.h>
     3.9  
    3.10  #pragma warning( disable : 4204 ) 
    3.11  #pragma warning( disable : 4221 ) 
    3.12  
    3.13  struct write_req {
    3.14 -    const void *data;
    3.15 +    void *data;
    3.16      unsigned len;
    3.17  };
    3.18  
    3.19 @@ -36,59 +35,6 @@ XenBus_WatchThreadProc(PVOID StartContex
    3.20  static DDKAPI BOOLEAN
    3.21  XenBus_Dpc(PKINTERRUPT Interrupt, PVOID ServiceContext);
    3.22  
    3.23 -/* called with xenbus_mutex held */
    3.24 -static int allocate_xenbus_id(PXENPCI_DEVICE_DATA xpdd)
    3.25 -{
    3.26 -  static int probe;
    3.27 -  int o_probe;
    3.28 -  KIRQL old_irql;
    3.29 -
    3.30 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    3.31 -
    3.32 -  for (;;)
    3.33 -  {
    3.34 -    KeAcquireSpinLock(&xpdd->xenbus_id_lock, &old_irql);
    3.35 -    if (xpdd->nr_live_reqs < NR_XB_REQS)
    3.36 -      break;
    3.37 -    KeReleaseSpinLock(&xpdd->xenbus_id_lock, old_irql);
    3.38 -    KeWaitForSingleObject(&xpdd->xenbus_id_event, Executive, KernelMode, FALSE, NULL);
    3.39 -  }
    3.40 -
    3.41 -  o_probe = probe;
    3.42 -
    3.43 -  for (;;)
    3.44 -  {
    3.45 -    if (!xpdd->req_info[o_probe].In_Use)
    3.46 -      break;
    3.47 -    o_probe = (o_probe + 1) % NR_XB_REQS;
    3.48 -    ASSERT(o_probe != probe);
    3.49 -  }
    3.50 -  xpdd->nr_live_reqs++;
    3.51 -  xpdd->req_info[o_probe].In_Use = 1;
    3.52 -  probe = (o_probe + 1) % NR_XB_REQS;
    3.53 -  KeReleaseSpinLock(&xpdd->xenbus_id_lock, old_irql);
    3.54 -  KeInitializeEvent(&xpdd->req_info[o_probe].WaitEvent, SynchronizationEvent, FALSE);
    3.55 -
    3.56 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    3.57 -
    3.58 -  return o_probe;
    3.59 -}
    3.60 -
    3.61 -/* called with xenbus_mutex held */
    3.62 -static void release_xenbus_id(PXENPCI_DEVICE_DATA xpdd, int id)
    3.63 -{
    3.64 -  KIRQL old_irql;
    3.65 -
    3.66 -  ASSERT(xpdd->req_info[id].In_Use);
    3.67 -  KeAcquireSpinLock(&xpdd->xenbus_id_lock, &old_irql);
    3.68 -  xpdd->req_info[id].In_Use = 0;
    3.69 -  xpdd->nr_live_reqs--;
    3.70 -  xpdd->req_info[id].In_Use = 0;
    3.71 -  if (xpdd->nr_live_reqs == NR_XB_REQS - 1)
    3.72 -    KeSetEvent(&xpdd->xenbus_id_event, IO_NO_INCREMENT, FALSE);
    3.73 -  KeReleaseSpinLock(&xpdd->xenbus_id_lock, old_irql);
    3.74 -}
    3.75 -
    3.76  // This routine free's the rep structure if there was an error!!!
    3.77  static char *errmsg(struct xsd_sockmsg *rep)
    3.78  {
    3.79 @@ -108,13 +54,13 @@ static char *errmsg(struct xsd_sockmsg *
    3.80    return res;
    3.81  }
    3.82  
    3.83 -static void memcpy_from_ring(const void *Ring,
    3.84 +static void memcpy_from_ring(void *Ring,
    3.85          void *Dest,
    3.86          int off,
    3.87          int len)
    3.88  {
    3.89    int c1, c2;
    3.90 -  const char *ring = Ring;
    3.91 +  char *ring = Ring;
    3.92    char *dest = Dest;
    3.93    c1 = min(len, XENSTORE_RING_SIZE - off);
    3.94    c2 = len - c1;
    3.95 @@ -125,30 +71,17 @@ static void memcpy_from_ring(const void 
    3.96  /* called with xenbus_mutex held */
    3.97  static void xb_write(
    3.98    PXENPCI_DEVICE_DATA xpdd,
    3.99 -  int type,
   3.100 -  int req_id,
   3.101 -  xenbus_transaction_t trans_id,
   3.102 -  const struct write_req *req,
   3.103 -  int nr_reqs)
   3.104 +  PVOID data,
   3.105 +  ULONG len
   3.106 +)
   3.107  {
   3.108    XENSTORE_RING_IDX prod;
   3.109 -  int r;
   3.110 -  size_t len = 0;
   3.111 -  const struct write_req *cur_req;
   3.112 -  size_t req_off;
   3.113 -  size_t total_off;
   3.114 -  size_t this_chunk;
   3.115 -  struct xsd_sockmsg m = {type, req_id, trans_id };
   3.116 -  struct write_req header_req = { &m, sizeof(m) };
   3.117 -
   3.118 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.119 -
   3.120 -  for (r = 0; r < nr_reqs; r++)
   3.121 -    len += (size_t)req[r].len;
   3.122 -  m.len = (ULONG)len;
   3.123 -  len += sizeof(m);
   3.124 -
   3.125 -  cur_req = &header_req;
   3.126 +  ULONG copy_len;
   3.127 +  PUCHAR ptr;
   3.128 +  ULONG remaining;
   3.129 +  
   3.130 +  FUNCTION_ENTER();
   3.131 +  KdPrint((__DRIVER_NAME "     len = %d\n", len));
   3.132  
   3.133    ASSERT(len <= XENSTORE_RING_SIZE);
   3.134    /* Wait for the ring to drain to the point where we can send the
   3.135 @@ -158,6 +91,7 @@ static void xb_write(
   3.136    while (prod + len - xpdd->xen_store_interface->req_cons > XENSTORE_RING_SIZE)
   3.137    {
   3.138      /* Wait for there to be space on the ring */
   3.139 +    /* not sure if I can wait here like this... */
   3.140      KeWaitForSingleObject(&xpdd->XenBus_ReadThreadEvent, Executive, KernelMode, FALSE, NULL);
   3.141      prod = xpdd->xen_store_interface->req_prod;
   3.142    }
   3.143 @@ -165,72 +99,90 @@ static void xb_write(
   3.144    /* We're now guaranteed to be able to send the message without
   3.145       overflowing the ring.  Do so. */
   3.146  
   3.147 -  total_off = 0;
   3.148 -  req_off = 0;
   3.149 -
   3.150 -  while (total_off < len)
   3.151 +  ptr = data;
   3.152 +  remaining = len;
   3.153 +  while (remaining)
   3.154    {
   3.155 -    this_chunk = min(cur_req->len - req_off,XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
   3.156 -    memcpy((char *)xpdd->xen_store_interface->req + MASK_XENSTORE_IDX(prod), (char *)cur_req->data + req_off, this_chunk);
   3.157 -    prod += (XENSTORE_RING_IDX)this_chunk;
   3.158 -    req_off += this_chunk;
   3.159 -    total_off += this_chunk;
   3.160 -    if (req_off == cur_req->len)
   3.161 -    {
   3.162 -      req_off = 0;
   3.163 -      if (cur_req == &header_req)
   3.164 -        cur_req = req;
   3.165 -      else
   3.166 -        cur_req++;
   3.167 -    }
   3.168 +    copy_len = min(remaining, XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
   3.169 +    KdPrint((__DRIVER_NAME "     copy_len = %d\n", copy_len));
   3.170 +    memcpy((PUCHAR)xpdd->xen_store_interface->req + MASK_XENSTORE_IDX(prod), ptr, copy_len);
   3.171 +    prod += (XENSTORE_RING_IDX)copy_len;
   3.172 +    ptr += copy_len;
   3.173 +    remaining -= copy_len;
   3.174    }
   3.175 -
   3.176    /* Remote must see entire message before updating indexes */
   3.177    KeMemoryBarrier();
   3.178 -
   3.179 -  xpdd->xen_store_interface->req_prod += (XENSTORE_RING_IDX)len;
   3.180 -
   3.181 -  /* Send evtchn to notify remote */
   3.182 +  xpdd->xen_store_interface->req_prod = prod;
   3.183    EvtChn_Notify(xpdd, xpdd->xen_store_evtchn);
   3.184  
   3.185 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.186 +  FUNCTION_EXIT();
   3.187  }
   3.188  
   3.189 -/* called with xenbus_mutex held */
   3.190 +/* takes and releases xb_request_mutex */
   3.191  static struct xsd_sockmsg *
   3.192 -xenbus_msg_reply(
   3.193 +xenbus_format_msg_reply(
   3.194    PXENPCI_DEVICE_DATA xpdd,
   3.195    int type,
   3.196 -  xenbus_transaction_t trans,
   3.197 -  struct write_req *io,
   3.198 +  xenbus_transaction_t trans_id,
   3.199 +  struct write_req *req,
   3.200    int nr_reqs)
   3.201  {
   3.202 -  int id;
   3.203 -
   3.204 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.205 -
   3.206 -  id = allocate_xenbus_id(xpdd);
   3.207 +  struct xsd_sockmsg msg;
   3.208 +  struct xsd_sockmsg *reply;
   3.209 +  int i;
   3.210  
   3.211 -  xb_write(xpdd, type, id, trans, io, nr_reqs);
   3.212 -
   3.213 -  KeWaitForSingleObject(&xpdd->req_info[id].WaitEvent, Executive, KernelMode, FALSE, NULL);
   3.214 +  FUNCTION_ENTER();
   3.215 +  
   3.216 +  msg.type = type;
   3.217 +  msg.req_id = 0;
   3.218 +  msg.tx_id = trans_id;
   3.219 +  msg.len = 0;
   3.220 +  for (i = 0; i < nr_reqs; i++)
   3.221 +    msg.len += (size_t)req[i].len;
   3.222  
   3.223 -  release_xenbus_id(xpdd, id);
   3.224 +  ExAcquireFastMutex(&xpdd->xb_request_mutex);
   3.225 +  xb_write(xpdd, &msg, sizeof(msg));
   3.226 +  for (i = 0; i < nr_reqs; i++)
   3.227 +    xb_write(xpdd, req[i].data, req[i].len);
   3.228  
   3.229 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.230 +  KdPrint((__DRIVER_NAME "     waiting...\n"));
   3.231 +  KeWaitForSingleObject(&xpdd->xb_request_complete_event, Executive, KernelMode, FALSE, NULL);
   3.232 +  KdPrint((__DRIVER_NAME "     ...done waiting\n"));
   3.233 +  reply = xpdd->xb_reply;
   3.234 +  xpdd->xb_reply = NULL;
   3.235 +  ExReleaseFastMutex(&xpdd->xb_request_mutex);  
   3.236  
   3.237 -  return xpdd->req_info[id].Reply;
   3.238 +  FUNCTION_EXIT();
   3.239 +  
   3.240 +  return reply;
   3.241 +}
   3.242 +
   3.243 +/* takes and releases xb_request_mutex */
   3.244 +struct xsd_sockmsg *
   3.245 +XenBus_Raw(
   3.246 +  PXENPCI_DEVICE_DATA xpdd,
   3.247 +  struct xsd_sockmsg *msg)
   3.248 +{
   3.249 +  struct xsd_sockmsg *reply;
   3.250 +
   3.251 +  ExAcquireFastMutex(&xpdd->xb_request_mutex);
   3.252 +  xb_write(xpdd, msg, sizeof(struct xsd_sockmsg) + msg->len);
   3.253 +  KeWaitForSingleObject(&xpdd->xb_request_complete_event, Executive, KernelMode, FALSE, NULL);
   3.254 +  reply = xpdd->xb_reply;
   3.255 +  xpdd->xb_reply = NULL;
   3.256 +  ExReleaseFastMutex(&xpdd->xb_request_mutex);  
   3.257 +
   3.258 +  return reply;
   3.259  }
   3.260  
   3.261  /*
   3.262  Called at PASSIVE_LEVEL
   3.263 -Acquires the mutex
   3.264  */
   3.265  char *
   3.266  XenBus_Read(
   3.267    PVOID Context,
   3.268    xenbus_transaction_t xbt,
   3.269 -  const char *path,
   3.270 +  char *path,
   3.271    char **value)
   3.272  {
   3.273    PXENPCI_DEVICE_DATA xpdd = Context;
   3.274 @@ -243,11 +195,7 @@ XenBus_Read(
   3.275  
   3.276    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   3.277  
   3.278 -  // get mutex or wait for mutex to be acquired
   3.279 -  
   3.280 -  ExAcquireFastMutex(&xpdd->xenbus_mutex);
   3.281 -  rep = xenbus_msg_reply(xpdd, XS_READ, xbt, req, ARRAY_SIZE(req));
   3.282 -  ExReleaseFastMutex(&xpdd->xenbus_mutex);
   3.283 +  rep = xenbus_format_msg_reply(xpdd, XS_READ, xbt, req, ARRAY_SIZE(req));
   3.284    msg = errmsg(rep);
   3.285    if (msg) {
   3.286      *value = NULL;
   3.287 @@ -266,14 +214,13 @@ XenBus_Read(
   3.288  
   3.289  /*
   3.290  Called at PASSIVE_LEVEL
   3.291 -Acquires the mutex
   3.292  */
   3.293  char *
   3.294  XenBus_Write(
   3.295    PVOID Context,
   3.296    xenbus_transaction_t xbt,
   3.297 -  const char *path,
   3.298 -  const char *value)
   3.299 +  char *path,
   3.300 +  char *value)
   3.301  {
   3.302    PXENPCI_DEVICE_DATA xpdd = Context;
   3.303    struct write_req req[] = {
   3.304 @@ -287,9 +234,7 @@ XenBus_Write(
   3.305  
   3.306    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   3.307  
   3.308 -  ExAcquireFastMutex(&xpdd->xenbus_mutex);
   3.309 -  rep = xenbus_msg_reply(xpdd, XS_WRITE, xbt, req, ARRAY_SIZE(req));
   3.310 -  ExReleaseFastMutex(&xpdd->xenbus_mutex);
   3.311 +  rep = xenbus_format_msg_reply(xpdd, XS_WRITE, xbt, req, ARRAY_SIZE(req));
   3.312    msg = errmsg(rep);
   3.313    if (msg)
   3.314      return msg;
   3.315 @@ -330,8 +275,8 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   3.316  
   3.317    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   3.318  
   3.319 -  ExInitializeFastMutex(&xpdd->watch_mutex);
   3.320 -  ExInitializeFastMutex(&xpdd->xenbus_mutex);
   3.321 +  ExInitializeFastMutex(&xpdd->xb_request_mutex);
   3.322 +  ExInitializeFastMutex(&xpdd->xb_watch_mutex);
   3.323  
   3.324    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   3.325    {
   3.326 @@ -340,8 +285,8 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   3.327  
   3.328    KeInitializeEvent(&xpdd->XenBus_ReadThreadEvent, SynchronizationEvent, FALSE);
   3.329    KeInitializeEvent(&xpdd->XenBus_WatchThreadEvent, SynchronizationEvent, FALSE);
   3.330 -  KeInitializeEvent(&xpdd->xenbus_id_event, SynchronizationEvent, FALSE);
   3.331 -  KeInitializeSpinLock(&xpdd->xenbus_id_lock);
   3.332 +  KeInitializeEvent(&xpdd->xb_request_complete_event, SynchronizationEvent, FALSE);
   3.333 +
   3.334    xpdd->XenBus_ShuttingDown = FALSE;
   3.335  
   3.336    status = XenBus_Connect(xpdd);
   3.337 @@ -385,36 +330,12 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
   3.338    return STATUS_SUCCESS;
   3.339  }
   3.340  
   3.341 -#if 0
   3.342 -NTSTATUS
   3.343 -XenBus_Stop(PXENPCI_DEVICE_DATA xpdd)
   3.344 -{
   3.345 -  int i;
   3.346 -
   3.347 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.348 -
   3.349 -  for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   3.350 -  {
   3.351 -    if (xpdd->XenBus_WatchEntries[i].Active)
   3.352 -      XenBus_RemWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path,
   3.353 -        xpdd->XenBus_WatchEntries[i].ServiceRoutine,
   3.354 -        xpdd->XenBus_WatchEntries[i].ServiceContext);
   3.355 -  }
   3.356 -
   3.357 -  EvtChn_Unbind(xpdd, xpdd->xen_store_evtchn);
   3.358 -
   3.359 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.360 -
   3.361 -  return STATUS_SUCCESS;
   3.362 -}
   3.363 -#endif
   3.364 -
   3.365  char *
   3.366  XenBus_SendRemWatch(
   3.367    PVOID context,
   3.368    xenbus_transaction_t xbt,
   3.369 -  const char *path,
   3.370 -  const int index)
   3.371 +  char *path,
   3.372 +  int index)
   3.373  {
   3.374    struct xsd_sockmsg *rep;
   3.375    char *msg;
   3.376 @@ -428,7 +349,7 @@ XenBus_SendRemWatch(
   3.377    req[1].data = Token;
   3.378    req[1].len = (ULONG)strlen(Token) + 1;
   3.379  
   3.380 -  rep = xenbus_msg_reply(context, XS_UNWATCH, xbt, req, ARRAY_SIZE(req));
   3.381 +  rep = xenbus_format_msg_reply(context, XS_UNWATCH, xbt, req, ARRAY_SIZE(req));
   3.382  
   3.383    msg = errmsg(rep);
   3.384    if (msg)
   3.385 @@ -452,38 +373,29 @@ XenBus_StopThreads(PXENPCI_DEVICE_DATA x
   3.386    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   3.387  
   3.388    /* we need to remove the watches as a watch firing could lead to a XenBus_Read/Write/Printf */
   3.389 -  ExAcquireFastMutex(&xpdd->watch_mutex);
   3.390    for (i = 0; i < MAX_WATCH_ENTRIES; i++) {
   3.391      if (xpdd->XenBus_WatchEntries[i].Active)
   3.392        XenBus_SendRemWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
   3.393    }
   3.394 -  ExReleaseFastMutex(&xpdd->watch_mutex);
   3.395  
   3.396    xpdd->XenBus_ShuttingDown = TRUE;
   3.397    KeMemoryBarrier();
   3.398  
   3.399 -KdPrint((__DRIVER_NAME "     Setting ReadThreadEvent\n"));
   3.400    KeSetEvent(&xpdd->XenBus_ReadThreadEvent, IO_NO_INCREMENT, FALSE);
   3.401 -KdPrint((__DRIVER_NAME "     Setting WatchThreadEvent\n"));
   3.402    KeSetEvent(&xpdd->XenBus_WatchThreadEvent, IO_NO_INCREMENT, FALSE);
   3.403    
   3.404 -KdPrint((__DRIVER_NAME "     Waiting for ReadThread\n"));
   3.405    timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   3.406    while ((status = KeWaitForSingleObject(xpdd->XenBus_ReadThread, Executive, KernelMode, FALSE, &timeout)) != STATUS_SUCCESS)
   3.407    {
   3.408 -KdPrint((__DRIVER_NAME "     Still waiting for ReadThread (status = %08x)\n", status));
   3.409      timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   3.410    }
   3.411    ObDereferenceObject(xpdd->XenBus_ReadThread);
   3.412 -KdPrint((__DRIVER_NAME "     Waiting for WatchThread\n"));
   3.413    timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   3.414    while ((status = KeWaitForSingleObject(xpdd->XenBus_WatchThread, Executive, KernelMode, FALSE, &timeout)) != STATUS_SUCCESS)
   3.415    {
   3.416 -KdPrint((__DRIVER_NAME "     Still waiting for WatchThread (status = %08x)\n", status));
   3.417      timeout.QuadPart = (LONGLONG)-1 * 1000 * 1000 * 10;
   3.418    }
   3.419    ObDereferenceObject(xpdd->XenBus_WatchThread);
   3.420 -KdPrint((__DRIVER_NAME "     Done\n"));
   3.421    
   3.422    xpdd->XenBus_ShuttingDown = FALSE;
   3.423  
   3.424 @@ -496,7 +408,7 @@ char *
   3.425  XenBus_List(
   3.426    PVOID Context,
   3.427    xenbus_transaction_t xbt,
   3.428 -  const char *pre,
   3.429 +  char *pre,
   3.430    char ***contents)
   3.431  {
   3.432    PXENPCI_DEVICE_DATA xpdd = Context;
   3.433 @@ -510,7 +422,7 @@ XenBus_List(
   3.434  
   3.435    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   3.436  
   3.437 -  repmsg = xenbus_msg_reply(xpdd, XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
   3.438 +  repmsg = xenbus_format_msg_reply(xpdd, XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
   3.439    msg = errmsg(repmsg);
   3.440    if (msg)
   3.441    {
   3.442 @@ -551,6 +463,7 @@ XenBus_ReadThreadProc(PVOID StartContext
   3.443    for(;;)
   3.444    {
   3.445      KeWaitForSingleObject(&xpdd->XenBus_ReadThreadEvent, Executive, KernelMode, FALSE, NULL);
   3.446 +    KdPrint((__DRIVER_NAME " +++ thread woken\n"));
   3.447      if (xpdd->XenBus_ShuttingDown)
   3.448      {
   3.449        KdPrint((__DRIVER_NAME "     Shutdown detected in ReadThreadProc\n"));
   3.450 @@ -562,7 +475,7 @@ XenBus_ReadThreadProc(PVOID StartContext
   3.451        //KdPrint((__DRIVER_NAME "     a - Rsp_cons %d, rsp_prod %d.\n", xen_store_interface->rsp_cons, xen_store_interface->rsp_prod));
   3.452        if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(msg))
   3.453        {
   3.454 -        //KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n"));
   3.455 +        KdPrint((__DRIVER_NAME " +++ Message incomplete (not even a full header)\n"));
   3.456          break;
   3.457        }
   3.458        KeMemoryBarrier();
   3.459 @@ -570,19 +483,20 @@ XenBus_ReadThreadProc(PVOID StartContext
   3.460          MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons), sizeof(msg));
   3.461        if (xpdd->xen_store_interface->rsp_prod - xpdd->xen_store_interface->rsp_cons < sizeof(msg) + msg.len)
   3.462        {
   3.463 -        //KdPrint((__DRIVER_NAME " +++ Message incomplete (header but not full body)\n"));
   3.464 +        KdPrint((__DRIVER_NAME " +++ Message incomplete (header but not full body)\n"));
   3.465          break;
   3.466        }
   3.467    
   3.468        if (msg.type != XS_WATCH_EVENT)
   3.469        {
   3.470 -        xpdd->req_info[msg.req_id].Reply = ExAllocatePoolWithTag(NonPagedPool, sizeof(msg) + msg.len, XENPCI_POOL_TAG);
   3.471 +        xpdd->xb_reply = ExAllocatePoolWithTag(NonPagedPool, sizeof(msg) + msg.len, XENPCI_POOL_TAG);
   3.472          memcpy_from_ring(xpdd->xen_store_interface->rsp,
   3.473 -          xpdd->req_info[msg.req_id].Reply,
   3.474 +          xpdd->xb_reply,
   3.475            MASK_XENSTORE_IDX(xpdd->xen_store_interface->rsp_cons),
   3.476            msg.len + sizeof(msg));
   3.477          xpdd->xen_store_interface->rsp_cons += msg.len + sizeof(msg);
   3.478 -        KeSetEvent(&xpdd->req_info[msg.req_id].WaitEvent, IO_NO_INCREMENT, FALSE);
   3.479 +        KdPrint((__DRIVER_NAME " +++ Setting event\n"));
   3.480 +        KeSetEvent(&xpdd->xb_request_complete_event, IO_NO_INCREMENT, FALSE);
   3.481        }
   3.482        else // a watch: add to watch ring and signal watch thread
   3.483        {
   3.484 @@ -624,11 +538,11 @@ XenBus_WatchThreadProc(PVOID StartContex
   3.485    for(;;)
   3.486    {
   3.487      KeWaitForSingleObject(&xpdd->XenBus_WatchThreadEvent, Executive, KernelMode, FALSE, NULL);
   3.488 -    ExAcquireFastMutex(&xpdd->watch_mutex);
   3.489 +    ExAcquireFastMutex(&xpdd->xb_watch_mutex);
   3.490      if (xpdd->XenBus_ShuttingDown)
   3.491      {
   3.492        KdPrint((__DRIVER_NAME "     Shutdown detected in WatchThreadProc\n"));
   3.493 -      ExReleaseFastMutex(&xpdd->watch_mutex);
   3.494 +      ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   3.495        PsTerminateSystemThread(0);
   3.496        KdPrint((__DRIVER_NAME "     WatchThreadProc still running... wtf?\n"));
   3.497      }
   3.498 @@ -647,19 +561,18 @@ XenBus_WatchThreadProc(PVOID StartContex
   3.499        entry->Count++;
   3.500        entry->ServiceRoutine(xpdd->XenBus_WatchRing[xpdd->XenBus_WatchRingReadIndex].Path, entry->ServiceContext);
   3.501      }
   3.502 -    ExReleaseFastMutex(&xpdd->watch_mutex);
   3.503 +    ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   3.504    }
   3.505  }    
   3.506  
   3.507  /*
   3.508  Called at PASSIVE_LEVEL
   3.509 -Acquires the mutex
   3.510  */
   3.511  static char *
   3.512  XenBus_SendAddWatch(
   3.513    PVOID Context,
   3.514    xenbus_transaction_t xbt,
   3.515 -  const char *Path,
   3.516 +  char *Path,
   3.517    int slot)
   3.518  {
   3.519    PXENPCI_DEVICE_DATA xpdd = Context;
   3.520 @@ -675,9 +588,7 @@ XenBus_SendAddWatch(
   3.521    req[1].data = Token;
   3.522    req[1].len = (ULONG)strlen(Token) + 1;
   3.523  
   3.524 -  ExAcquireFastMutex(&xpdd->xenbus_mutex);
   3.525 -  rep = xenbus_msg_reply(xpdd, XS_WATCH, xbt, req, ARRAY_SIZE(req));
   3.526 -  ExReleaseFastMutex(&xpdd->xenbus_mutex);
   3.527 +  rep = xenbus_format_msg_reply(xpdd, XS_WATCH, xbt, req, ARRAY_SIZE(req));
   3.528  
   3.529    msg = errmsg(rep);
   3.530    if (!msg)
   3.531 @@ -693,12 +604,10 @@ XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd)
   3.532    int i;
   3.533    
   3.534    /* we need to remove the watches as a watch firing could lead to a XenBus_Read/Write/Printf */
   3.535 -  ExAcquireFastMutex(&xpdd->watch_mutex);
   3.536    for (i = 0; i < MAX_WATCH_ENTRIES; i++) {
   3.537      if (xpdd->XenBus_WatchEntries[i].Active)
   3.538        XenBus_SendRemWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
   3.539    }
   3.540 -  ExReleaseFastMutex(&xpdd->watch_mutex);
   3.541  
   3.542    // need to synchronise with readthread here too to ensure that it won't do anything silly
   3.543    
   3.544 @@ -737,7 +646,7 @@ char *
   3.545  XenBus_AddWatch(
   3.546    PVOID Context,
   3.547    xenbus_transaction_t xbt,
   3.548 -  const char *Path,
   3.549 +  char *Path,
   3.550    PXENBUS_WATCH_CALLBACK ServiceRoutine,
   3.551    PVOID ServiceContext)
   3.552  {
   3.553 @@ -752,7 +661,7 @@ XenBus_AddWatch(
   3.554  
   3.555    ASSERT(strlen(Path) < ARRAY_SIZE(w_entry->Path));
   3.556  
   3.557 -  ExAcquireFastMutex(&xpdd->watch_mutex);
   3.558 +  ExAcquireFastMutex(&xpdd->xb_watch_mutex);
   3.559  
   3.560    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   3.561      if (xpdd->XenBus_WatchEntries[i].Active == 0)
   3.562 @@ -761,7 +670,7 @@ XenBus_AddWatch(
   3.563    if (i == MAX_WATCH_ENTRIES)
   3.564    {
   3.565      KdPrint((__DRIVER_NAME " +++ No more watch slots left\n"));
   3.566 -    ExReleaseFastMutex(&xpdd->watch_mutex);
   3.567 +    ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   3.568      return NULL;
   3.569    }
   3.570  
   3.571 @@ -774,7 +683,7 @@ XenBus_AddWatch(
   3.572    w_entry->Count = 0;
   3.573    w_entry->Active = 1;
   3.574  
   3.575 -  ExReleaseFastMutex(&xpdd->watch_mutex);
   3.576 +  ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   3.577  
   3.578    msg = XenBus_SendAddWatch(xpdd, xbt, Path, i);
   3.579  
   3.580 @@ -794,7 +703,7 @@ char *
   3.581  XenBus_RemWatch(
   3.582    PVOID Context,
   3.583    xenbus_transaction_t xbt,
   3.584 -  const char *Path,
   3.585 +  char *Path,
   3.586    PXENBUS_WATCH_CALLBACK ServiceRoutine,
   3.587    PVOID ServiceContext)
   3.588  {
   3.589 @@ -805,7 +714,7 @@ XenBus_RemWatch(
   3.590  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.591    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   3.592  
   3.593 -  ExAcquireFastMutex(&xpdd->watch_mutex);
   3.594 +  ExAcquireFastMutex(&xpdd->xb_watch_mutex);
   3.595  
   3.596    // check that Path < 128 chars
   3.597  
   3.598 @@ -834,7 +743,7 @@ XenBus_RemWatch(
   3.599  
   3.600    if (i == MAX_WATCH_ENTRIES)
   3.601    {
   3.602 -    ExReleaseFastMutex(&xpdd->watch_mutex);
   3.603 +    ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   3.604      KdPrint((__DRIVER_NAME "     Watch not set - can't remove\n"));
   3.605      return NULL;
   3.606    }
   3.607 @@ -842,7 +751,7 @@ XenBus_RemWatch(
   3.608    xpdd->XenBus_WatchEntries[i].Active = 0;
   3.609    xpdd->XenBus_WatchEntries[i].Path[0] = 0;
   3.610  
   3.611 -  ExReleaseFastMutex(&xpdd->watch_mutex);
   3.612 +  ExReleaseFastMutex(&xpdd->xb_watch_mutex);
   3.613  
   3.614    msg = XenBus_SendRemWatch(Context, xbt, Path, i);
   3.615    
   3.616 @@ -865,7 +774,7 @@ XenBus_StartTransaction(PVOID Context, x
   3.617  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.618    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   3.619  
   3.620 -  rep = xenbus_msg_reply(xpdd, XS_TRANSACTION_START, 0, &req, 1);
   3.621 +  rep = xenbus_format_msg_reply(xpdd, XS_TRANSACTION_START, 0, &req, 1);
   3.622    err = errmsg(rep);
   3.623    if (err)
   3.624      return err;
   3.625 @@ -896,7 +805,7 @@ XenBus_EndTransaction(
   3.626  
   3.627    req.data = abort ? "F" : "T";
   3.628    req.len = 2;
   3.629 -  rep = xenbus_msg_reply(xpdd, XS_TRANSACTION_END, t, &req, 1);
   3.630 +  rep = xenbus_format_msg_reply(xpdd, XS_TRANSACTION_END, t, &req, 1);
   3.631    err = errmsg(rep);
   3.632    if (err) {
   3.633      if (!strcmp(err, "EAGAIN")) {
   3.634 @@ -934,8 +843,8 @@ char *
   3.635  XenBus_Printf(
   3.636    PVOID Context,
   3.637    xenbus_transaction_t xbt,
   3.638 -  const char *path,
   3.639 -  const char *fmt,
   3.640 +  char *path,
   3.641 +  char *fmt,
   3.642    ...)
   3.643  {
   3.644    PXENPCI_DEVICE_DATA xpdd = Context;
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xenpci/xenbus_device_interface.c	Mon Dec 22 22:34:52 2008 +1100
     4.3 @@ -0,0 +1,251 @@
     4.4 +/*
     4.5 +PV Drivers for Windows Xen HVM Domains
     4.6 +Copyright (C) 2007 James Harper
     4.7 +
     4.8 +This program is free software; you can redistribute it and/or
     4.9 +modify it under the terms of the GNU General Public License
    4.10 +as published by the Free Software Foundation; either version 2
    4.11 +of the License, or (at your option) any later version.
    4.12 +
    4.13 +This program is distributed in the hope that it will be useful,
    4.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.16 +GNU General Public License for more details.
    4.17 +
    4.18 +You should have received a copy of the GNU General Public License
    4.19 +along with this program; if not, write to the Free Software
    4.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    4.21 +*/
    4.22 +
    4.23 +#include "xenpci.h"
    4.24 +
    4.25 +NTSTATUS
    4.26 +XenPci_Irp_Create_XenBus(PDEVICE_OBJECT device_object, PIRP irp)
    4.27 +{
    4.28 +  NTSTATUS status;
    4.29 +  PIO_STACK_LOCATION stack;
    4.30 +  PFILE_OBJECT file;
    4.31 +  device_interface_xenbus_context_t *dixc;
    4.32 +  
    4.33 +  UNREFERENCED_PARAMETER(device_object);
    4.34 +  stack = IoGetCurrentIrpStackLocation(irp);
    4.35 +  file = stack->FileObject;
    4.36 +  dixc = (device_interface_xenbus_context_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(device_interface_xenbus_context_t), XENPCI_POOL_TAG);
    4.37 +  dixc->type = DEVICE_INTERFACE_TYPE_XENBUS;
    4.38 +  KeInitializeSpinLock(&dixc->lock);
    4.39 +  InitializeListHead(&dixc->read_list_head);
    4.40 +  dixc->len = 0;
    4.41 +  file->FsContext = dixc;
    4.42 +  status = STATUS_SUCCESS;    
    4.43 +  irp->IoStatus.Status = status;
    4.44 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
    4.45 +  return status;
    4.46 +}
    4.47 +
    4.48 +NTSTATUS
    4.49 +XenPci_Irp_Close_XenBus(PDEVICE_OBJECT device_object, PIRP irp)
    4.50 +{
    4.51 +  PXENPCI_DEVICE_DATA xpdd;
    4.52 +  NTSTATUS status;
    4.53 +
    4.54 +  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    4.55 +  status = STATUS_SUCCESS;    
    4.56 +  irp->IoStatus.Status = status;
    4.57 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
    4.58 +  // cleanup dixc here
    4.59 +  
    4.60 +  return status;
    4.61 +}
    4.62 +
    4.63 +typedef struct {
    4.64 +  LIST_ENTRY entry;
    4.65 +  PVOID data;
    4.66 +  ULONG length;
    4.67 +  ULONG offset;
    4.68 +} xenbus_read_queue_item_t;
    4.69 +
    4.70 +static NTSTATUS
    4.71 +XenPci_Irp_Read_XenBus_Complete(device_interface_xenbus_context_t *dixc, PIRP irp)
    4.72 +{
    4.73 +  KIRQL old_irql;
    4.74 +  ULONG dst_length;
    4.75 +  ULONG dst_offset;
    4.76 +  ULONG copy_length;
    4.77 +  xenbus_read_queue_item_t *list_entry;
    4.78 +  PIO_STACK_LOCATION stack;
    4.79 +  NTSTATUS status;
    4.80 +  
    4.81 +  dixc->pending_read_irp = NULL;
    4.82 +  stack = IoGetCurrentIrpStackLocation(irp);
    4.83 +  dst_length = stack->Parameters.Read.Length;
    4.84 +  dst_offset = 0;
    4.85 +  KeAcquireSpinLock(&dixc->lock, &old_irql);
    4.86 +  while(dst_offset < dst_length && (list_entry = (xenbus_read_queue_item_t *)RemoveHeadList(&dixc->read_list_head)) != (xenbus_read_queue_item_t *)&dixc->read_list_head)
    4.87 +  {
    4.88 +    copy_length = min(list_entry->length - list_entry->offset, dst_length - dst_offset);
    4.89 +    memcpy((PUCHAR)irp->AssociatedIrp.SystemBuffer + dst_offset, (PUCHAR)list_entry->data + list_entry->offset, copy_length);
    4.90 +    list_entry->offset += copy_length;
    4.91 +    dst_offset += copy_length;
    4.92 +    if (list_entry->offset == list_entry->length)
    4.93 +    {
    4.94 +      // free the list entry
    4.95 +      // free the data
    4.96 +    }
    4.97 +    else
    4.98 +    {
    4.99 +      InsertHeadList(&dixc->read_list_head, (PLIST_ENTRY)list_entry);
   4.100 +    }      
   4.101 +  }
   4.102 +  KeReleaseSpinLock(&dixc->lock, old_irql);
   4.103 +    
   4.104 +  if (dst_offset > 0)
   4.105 +  {
   4.106 +    status = STATUS_SUCCESS;
   4.107 +    irp->IoStatus.Status = status;
   4.108 +    irp->IoStatus.Information = dst_offset;
   4.109 +    //IoSetCancelRoutine(irp, NULL);
   4.110 +    IoCompleteRequest(irp, IO_NO_INCREMENT);
   4.111 +  }
   4.112 +  else
   4.113 +  {
   4.114 +    status = STATUS_PENDING;
   4.115 +  }
   4.116 +  return status;
   4.117 +}
   4.118 +
   4.119 +NTSTATUS
   4.120 +XenPci_Irp_Read_XenBus(PDEVICE_OBJECT device_object, PIRP irp)
   4.121 +{
   4.122 +  NTSTATUS status;
   4.123 +  PIO_STACK_LOCATION stack;
   4.124 +  PFILE_OBJECT file;
   4.125 +  device_interface_xenbus_context_t *dixc;
   4.126 +  KIRQL old_irql;
   4.127 +
   4.128 +  UNREFERENCED_PARAMETER(device_object);
   4.129 +
   4.130 +  stack = IoGetCurrentIrpStackLocation(irp);
   4.131 +  file = stack->FileObject;
   4.132 +  dixc = file->FsContext;
   4.133 +
   4.134 +  ASSERT(dixc->pending_read_irp);
   4.135 +  
   4.136 +  if (stack->Parameters.Read.Length == 0)
   4.137 +  {
   4.138 +    status = STATUS_SUCCESS;    
   4.139 +    irp->IoStatus.Status = status;
   4.140 +    irp->IoStatus.Information = 0;
   4.141 +    IoCompleteRequest(irp, IO_NO_INCREMENT);
   4.142 +  }
   4.143 +  else 
   4.144 +  {
   4.145 +    status = XenPci_Irp_Read_XenBus_Complete(dixc, irp);
   4.146 +    if (status == STATUS_PENDING)
   4.147 +    {
   4.148 +      IoMarkIrpPending(irp);
   4.149 +      KeAcquireSpinLock(&dixc->lock, &old_irql);
   4.150 +      dixc->pending_read_irp = irp;
   4.151 +      //IoSetCancelRoutine(irp, XenBus_ShutdownIoCancel);
   4.152 +      KeReleaseSpinLock(&dixc->lock, old_irql);
   4.153 +    }
   4.154 +  }
   4.155 +  return status;
   4.156 +}
   4.157 +
   4.158 +NTSTATUS
   4.159 +XenPci_Irp_Write_XenBus(PDEVICE_OBJECT device_object, PIRP irp)
   4.160 +{
   4.161 +  NTSTATUS status;
   4.162 +  PIO_STACK_LOCATION stack;
   4.163 +  PFILE_OBJECT file;
   4.164 +  device_interface_xenbus_context_t *dixc;
   4.165 +  PUCHAR src_ptr;
   4.166 +  ULONG src_len;
   4.167 +  PUCHAR dst_ptr;
   4.168 +  ULONG copy_len;
   4.169 +  struct xsd_sockmsg *rep;
   4.170 +  PXENPCI_DEVICE_DATA xpdd;
   4.171 +  KIRQL old_irql;
   4.172 +  xenbus_read_queue_item_t *list_entry;
   4.173 +  PIRP read_irp;
   4.174 +  NTSTATUS read_status;
   4.175 +  
   4.176 +  xpdd = device_object->DeviceExtension;
   4.177 +  stack = IoGetCurrentIrpStackLocation(irp);
   4.178 +  file = stack->FileObject;
   4.179 +  dixc = file->FsContext;
   4.180 +  
   4.181 +  src_ptr = (PUCHAR)irp->AssociatedIrp.SystemBuffer;
   4.182 +  src_len = stack->Parameters.Write.Length;
   4.183 +  dst_ptr = dixc->u.buffer + dixc->len;
   4.184 +  while (src_len != 0)
   4.185 +  {
   4.186 +    /* get a complete msg header */
   4.187 +    if (dixc->len < sizeof(dixc->u.msg))
   4.188 +    {
   4.189 +      copy_len = min(sizeof(dixc->u.msg) - dixc->len, src_len);
   4.190 +      if (!copy_len)
   4.191 +        continue;
   4.192 +      memcpy(dst_ptr, src_ptr, copy_len);
   4.193 +      dst_ptr += copy_len;
   4.194 +      src_ptr += copy_len;
   4.195 +      src_len -= copy_len;
   4.196 +      dixc->len += copy_len;
   4.197 +    }
   4.198 +    /* exit if we can't get that */
   4.199 +    if (dixc->len < sizeof(dixc->u.msg))
   4.200 +      continue;
   4.201 +    /* get a complete msg body */
   4.202 +    if (dixc->len < sizeof(dixc->u.msg) + dixc->u.msg.len)
   4.203 +    {
   4.204 +      copy_len = min(sizeof(dixc->u.msg) + dixc->u.msg.len - dixc->len, src_len);
   4.205 +      if (!copy_len)
   4.206 +        continue;
   4.207 +      memcpy(dst_ptr, src_ptr, copy_len);
   4.208 +      dst_ptr += copy_len;
   4.209 +      src_ptr += copy_len;
   4.210 +      src_len -= copy_len;
   4.211 +      dixc->len += copy_len;
   4.212 +    }
   4.213 +    /* exit if we can't get that */
   4.214 +    if (dixc->len < sizeof(dixc->u.msg) + dixc->u.msg.len)
   4.215 +    {
   4.216 +      continue;
   4.217 +    }
   4.218 +    
   4.219 +    rep = XenBus_Raw(xpdd, &dixc->u.msg);
   4.220 +    KeAcquireSpinLock(&dixc->lock, &old_irql);
   4.221 +    list_entry = (xenbus_read_queue_item_t *)ExAllocatePoolWithTag(NonPagedPool, sizeof(xenbus_read_queue_item_t), XENPCI_POOL_TAG);
   4.222 +    list_entry->data = rep;
   4.223 +    list_entry->length = sizeof(*rep) + rep->len;
   4.224 +    list_entry->offset = 0;
   4.225 +    InsertTailList(&dixc->read_list_head, (PLIST_ENTRY)list_entry);
   4.226 +    read_irp = dixc->pending_read_irp;
   4.227 +    dixc->pending_read_irp = NULL;
   4.228 +    KeReleaseSpinLock(&dixc->lock, old_irql);
   4.229 +    if (read_irp)
   4.230 +    {
   4.231 +      read_status = XenPci_Irp_Read_XenBus_Complete(dixc, read_irp);
   4.232 +      ASSERT(read_status == STATUS_SUCCESS);
   4.233 +    }
   4.234 +  }
   4.235 +  status = STATUS_SUCCESS;    
   4.236 +  irp->IoStatus.Status = status;
   4.237 +  irp->IoStatus.Information = stack->Parameters.Write.Length;
   4.238 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
   4.239 +  return status;
   4.240 +}
   4.241 +
   4.242 +NTSTATUS
   4.243 +XenPci_Irp_Cleanup_XenBus(PDEVICE_OBJECT device_object, PIRP irp)
   4.244 +{
   4.245 +  PXENPCI_DEVICE_DATA xpdd;
   4.246 +  NTSTATUS status;
   4.247 +
   4.248 +  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   4.249 +  status = STATUS_SUCCESS;    
   4.250 +  irp->IoStatus.Status = status;
   4.251 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
   4.252 +
   4.253 +  return status;
   4.254 +}
     5.1 --- a/xenpci/xenpci.c	Mon Dec 22 22:34:13 2008 +1100
     5.2 +++ b/xenpci/xenpci.c	Mon Dec 22 22:34:52 2008 +1100
     5.3 @@ -103,6 +103,20 @@ XenPci_Irp_Read(PDEVICE_OBJECT device_ob
     5.4  }
     5.5  
     5.6  static DDKAPI NTSTATUS
     5.7 +XenPci_Irp_Write(PDEVICE_OBJECT device_object, PIRP irp)
     5.8 +{
     5.9 +  NTSTATUS status;
    5.10 +  PXENPCI_COMMON common = device_object->DeviceExtension;
    5.11 +  
    5.12 +  if (common->lower_do)
    5.13 +    status = XenPci_Irp_Write_Fdo(device_object, irp);
    5.14 +  else
    5.15 +    status = XenPci_Irp_Write_Pdo(device_object, irp);  
    5.16 +
    5.17 +  return status;
    5.18 +}
    5.19 +
    5.20 +static DDKAPI NTSTATUS
    5.21  XenPci_Irp_Cleanup(PDEVICE_OBJECT device_object, PIRP irp)
    5.22  {
    5.23    NTSTATUS status;
    5.24 @@ -161,6 +175,7 @@ XenPci_AddDevice(PDRIVER_OBJECT DriverOb
    5.25  //  DECLARE_CONST_UNICODE_STRING(SymbolicName, L"\\DosDevices\\XenShutdown");
    5.26  //  WDFDEVICE Device;
    5.27    PXENPCI_DEVICE_DATA xpdd;
    5.28 +  UNICODE_STRING reference;
    5.29    //PWSTR InterfaceList;
    5.30  
    5.31    FUNCTION_ENTER();
    5.32 @@ -203,21 +218,38 @@ XenPci_AddDevice(PDRIVER_OBJECT DriverOb
    5.33  
    5.34    InitializeListHead(&xpdd->child_list);
    5.35  
    5.36 +  RtlInitUnicodeString(&reference, L"legacy");
    5.37    status = IoRegisterDeviceInterface(
    5.38      PhysicalDeviceObject,
    5.39      &GUID_XEN_IFACE,
    5.40 -    NULL,
    5.41 +    &reference,
    5.42 +    &xpdd->legacy_interface_name);
    5.43 +
    5.44 +  if (!NT_SUCCESS(status))
    5.45 +  {
    5.46 +    KdPrint((__DRIVER_NAME "     IoRegisterDeviceInterface(GUID_XEN_IFACE) failed with status 0x%08x\n", status));
    5.47 +  }
    5.48 +  else
    5.49 +  {
    5.50 +    KdPrint((__DRIVER_NAME "     IoRegisterDeviceInterface(GUID_XEN_IFACE) succeeded - %wZ\n", &xpdd->legacy_interface_name));
    5.51 +  }
    5.52 +
    5.53 +  RtlInitUnicodeString(&reference, L"xenbus");
    5.54 +  status = IoRegisterDeviceInterface(
    5.55 +    PhysicalDeviceObject,
    5.56 +    &GUID_XENBUS_IFACE,
    5.57 +    &reference,
    5.58      &xpdd->interface_name);
    5.59  
    5.60    if (!NT_SUCCESS(status))
    5.61    {
    5.62 -    KdPrint((__DRIVER_NAME "     IoRegisterDeviceInterface failed with status 0x%08x\n", status));
    5.63 +    KdPrint((__DRIVER_NAME "     IoRegisterDeviceInterface(GUID_XENBUS_IFACE) failed with status 0x%08x\n", status));
    5.64    }
    5.65    else
    5.66    {
    5.67 -    KdPrint((__DRIVER_NAME "     IoRegisterDeviceInterface succeeded - %wZ\n", &xpdd->interface_name));
    5.68 +    KdPrint((__DRIVER_NAME "     IoRegisterDeviceInterface(GUID_XENBUS_IFACE) succeeded - %wZ\n", &xpdd->interface_name));
    5.69    }
    5.70 -  
    5.71 +
    5.72    fdo->Flags &= ~DO_DEVICE_INITIALIZING;
    5.73  
    5.74    FUNCTION_EXIT();
    5.75 @@ -332,7 +364,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    5.76    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = XenPci_Irp_Cleanup;
    5.77    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = XenPci_Dummy;
    5.78    DriverObject->MajorFunction[IRP_MJ_READ] = XenPci_Irp_Read;
    5.79 -  DriverObject->MajorFunction[IRP_MJ_WRITE] = XenPci_Dummy;
    5.80 +  DriverObject->MajorFunction[IRP_MJ_WRITE] = XenPci_Irp_Write;
    5.81    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = XenPci_SystemControl;
    5.82  
    5.83    FUNCTION_EXIT();
     6.1 --- a/xenpci/xenpci.h	Mon Dec 22 22:34:13 2008 +1100
     6.2 +++ b/xenpci/xenpci.h	Mon Dec 22 22:34:52 2008 +1100
     6.3 @@ -49,6 +49,7 @@ Foundation, Inc., 51 Franklin Street, Fi
     6.4  #include <hvm/hvm_op.h>
     6.5  #include <sched.h>
     6.6  #include <io/xenbus.h>
     6.7 +#include "io/xs_wire.h"
     6.8  
     6.9  #include <xen_public.h>
    6.10  
    6.11 @@ -92,13 +93,6 @@ typedef struct _XENBUS_WATCH_RING
    6.12    char Token[10];
    6.13  } XENBUS_WATCH_RING;
    6.14  
    6.15 -typedef struct _XENBUS_REQ_INFO
    6.16 -{
    6.17 -  int In_Use:1;
    6.18 -  KEVENT WaitEvent;
    6.19 -  void *Reply;
    6.20 -} XENBUS_REQ_INFO;
    6.21 -
    6.22  typedef struct _XENBUS_WATCH_ENTRY {
    6.23    char Path[128];
    6.24    PXENBUS_WATCH_CALLBACK ServiceRoutine;
    6.25 @@ -204,10 +198,12 @@ typedef struct {
    6.26  
    6.27    evtchn_port_t xen_store_evtchn;
    6.28  
    6.29 +  /* grant related */
    6.30    grant_entry_t *gnttab_table;
    6.31    PHYSICAL_ADDRESS gnttab_table_physical;
    6.32    grant_ref_t *gnttab_list;
    6.33    int gnttab_list_free;
    6.34 +  KSPIN_LOCK grant_lock;
    6.35    /* this is the maximum number of grant frames we have memory allocated for */
    6.36    /* after a resume it may not be the actual number of grant frames we have though */
    6.37    ULONG max_grant_frames;
    6.38 @@ -220,29 +216,24 @@ typedef struct {
    6.39    PKTHREAD XenBus_WatchThread;
    6.40    KEVENT XenBus_WatchThreadEvent;
    6.41  
    6.42 -  KSPIN_LOCK xenbus_id_lock;
    6.43 -  KEVENT xenbus_id_event;
    6.44 -  
    6.45    XENBUS_WATCH_RING XenBus_WatchRing[WATCH_RING_SIZE];
    6.46    int XenBus_WatchRingReadIndex;
    6.47    int XenBus_WatchRingWriteIndex;
    6.48  
    6.49    struct xenstore_domain_interface *xen_store_interface;
    6.50  
    6.51 -  XENBUS_REQ_INFO req_info[NR_XB_REQS];
    6.52 -  int nr_live_reqs;
    6.53 +  /* xenbus related */
    6.54    XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
    6.55 -
    6.56 -  FAST_MUTEX watch_mutex;
    6.57 -  FAST_MUTEX xenbus_mutex;
    6.58 -  KSPIN_LOCK grant_lock;
    6.59 -
    6.60 -  //KGUARDED_MUTEX WatchHandlerMutex;
    6.61 -
    6.62 +  FAST_MUTEX xb_watch_mutex;
    6.63 +  FAST_MUTEX xb_request_mutex;
    6.64 +  KEVENT xb_request_complete_event;
    6.65 +  struct xsd_sockmsg *xb_reply;
    6.66 +  
    6.67    LIST_ENTRY child_list;
    6.68    
    6.69    int suspend_state;
    6.70    
    6.71 +  UNICODE_STRING legacy_interface_name;
    6.72    UNICODE_STRING interface_name;
    6.73    BOOLEAN interface_open;
    6.74    
    6.75 @@ -288,6 +279,22 @@ typedef struct
    6.76    PXENPCI_PDO_DEVICE_DATA context;
    6.77  } XEN_CHILD, *PXEN_CHILD;
    6.78  
    6.79 +#define DEVICE_INTERFACE_TYPE_LEGACY 0
    6.80 +#define DEVICE_INTERFACE_TYPE_XENBUS 1
    6.81 +
    6.82 +typedef struct {
    6.83 +  ULONG type;
    6.84 +  KSPIN_LOCK lock;
    6.85 +  ULONG len;
    6.86 +  union {
    6.87 +    struct xsd_sockmsg msg;
    6.88 +    UCHAR buffer[PAGE_SIZE];
    6.89 +  } u;
    6.90 +  LIST_ENTRY read_list_head;
    6.91 +  PIRP pending_read_irp;
    6.92 +} device_interface_xenbus_context_t;
    6.93 +
    6.94 +
    6.95  #include "hypercall.h"
    6.96  
    6.97  #define XBT_NIL ((xenbus_transaction_t)0)
    6.98 @@ -318,11 +325,24 @@ XenPci_Irp_Close_Fdo(PDEVICE_OBJECT devi
    6.99  NTSTATUS
   6.100  XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.101  NTSTATUS
   6.102 +XenPci_Irp_Write_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.103 +NTSTATUS
   6.104  XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.105  NTSTATUS
   6.106  XenPci_SystemControl_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.107  
   6.108  NTSTATUS
   6.109 +XenPci_Irp_Create_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
   6.110 +NTSTATUS
   6.111 +XenPci_Irp_Close_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
   6.112 +NTSTATUS
   6.113 +XenPci_Irp_Read_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
   6.114 +NTSTATUS
   6.115 +XenPci_Irp_Write_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
   6.116 +NTSTATUS
   6.117 +XenPci_Irp_Cleanup_XenBus(PDEVICE_OBJECT device_object, PIRP irp);
   6.118 +
   6.119 +NTSTATUS
   6.120  XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.121  //NTSTATUS
   6.122  //XenPci_Dummy_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.123 @@ -335,6 +355,8 @@ XenPci_Irp_Close_Pdo(PDEVICE_OBJECT devi
   6.124  NTSTATUS
   6.125  XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.126  NTSTATUS
   6.127 +XenPci_Irp_Write_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.128 +NTSTATUS
   6.129  XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.130  NTSTATUS
   6.131  XenPci_SystemControl_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
   6.132 @@ -347,22 +369,24 @@ XenPci_Pdo_Resume(PDEVICE_OBJECT device_
   6.133  VOID
   6.134  XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
   6.135  
   6.136 -char *
   6.137 -XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
   6.138 +struct xsd_sockmsg *
   6.139 +XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
   6.140  char *
   6.141 -XenBus_Write(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *value);
   6.142 +XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
   6.143  char *
   6.144 -XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *fmt, ...);
   6.145 +XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
   6.146 +char *
   6.147 +XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
   6.148  char *
   6.149  XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
   6.150  char *
   6.151  XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
   6.152  char *
   6.153 -XenBus_List(PVOID Context, xenbus_transaction_t xbt, const char *prefix, char ***contents);
   6.154 +XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
   6.155  char *
   6.156 -XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   6.157 +XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   6.158  char *
   6.159 -XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   6.160 +XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
   6.161  //VOID
   6.162  //XenBus_ThreadProc(PVOID StartContext);
   6.163  NTSTATUS
     7.1 --- a/xenpci/xenpci_fdo.c	Mon Dec 22 22:34:13 2008 +1100
     7.2 +++ b/xenpci/xenpci_fdo.c	Mon Dec 22 22:34:52 2008 +1100
     7.3 @@ -678,6 +678,12 @@ XenPci_Pnp_StartDeviceCallback(PDEVICE_O
     7.4    KdPrint((__DRIVER_NAME "     balloon watch response = '%s'\n", response));
     7.5  #endif
     7.6  
     7.7 +  status = IoSetDeviceInterfaceState(&xpdd->legacy_interface_name, TRUE);
     7.8 +  if (!NT_SUCCESS(status))
     7.9 +  {
    7.10 +    KdPrint((__DRIVER_NAME "     IoSetDeviceInterfaceState (legacy) failed with status 0x%08x\n", status));
    7.11 +  }
    7.12 +
    7.13    status = IoSetDeviceInterfaceState(&xpdd->interface_name, TRUE);
    7.14    if (!NT_SUCCESS(status))
    7.15    {
    7.16 @@ -1065,32 +1071,10 @@ XenPci_Pnp_FilterResourceRequirementsCal
    7.17    NTSTATUS status = STATUS_SUCCESS;
    7.18    //PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    7.19    PIRP irp = context;
    7.20 -#if 0
    7.21 -  PIO_RESOURCE_REQUIREMENTS_LIST irrl;
    7.22 -  PIO_RESOURCE_LIST irl;
    7.23 -  PIO_RESOURCE_DESCRIPTOR ird;
    7.24 -  ULONG i;
    7.25 -#endif
    7.26  
    7.27    UNREFERENCED_PARAMETER(device_object);
    7.28  
    7.29    FUNCTION_ENTER();
    7.30 -#if 0
    7.31 -  /* this assumes that AlternativeLists == 1 */
    7.32 -  irrl = (PIO_RESOURCE_REQUIREMENTS_LIST)irp->IoStatus.Information;
    7.33 -  KdPrint(("AlternativeLists = %d\n", irrl->AlternativeLists));
    7.34 -  irl = &irrl->List[0];
    7.35 -  for (i = 0; i < irl->Count; i++)
    7.36 -  {
    7.37 -    ird = &irl->Descriptors[i];
    7.38 -    if (ird->Type == CmResourceTypeInterrupt)
    7.39 -    {
    7.40 -      /* IRQ's < 16 (eg ISA interrupts) don't work reliably, so don't allow them. */
    7.41 -      KdPrint(("MinimumVector = %d, MaximumVector = %d\n", ird->u.Interrupt.MinimumVector, ird->u.Interrupt.MaximumVector));
    7.42 -      ird->u.Interrupt.MinimumVector = 16;
    7.43 -    }
    7.44 -  }
    7.45 -#endif
    7.46    irp->IoStatus.Status = status;
    7.47    IoCompleteRequest (irp, IO_NO_INCREMENT);
    7.48    
    7.49 @@ -1331,14 +1315,28 @@ XenPci_Irp_Create_Fdo(PDEVICE_OBJECT dev
    7.50  {
    7.51    PXENPCI_DEVICE_DATA xpdd;
    7.52    NTSTATUS status;
    7.53 +  PIO_STACK_LOCATION stack;
    7.54 +  PFILE_OBJECT file;
    7.55  
    7.56    FUNCTION_ENTER();
    7.57 -
    7.58 -  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    7.59 -  status = STATUS_SUCCESS;    
    7.60 -  irp->IoStatus.Status = status;
    7.61 -  IoCompleteRequest(irp, IO_NO_INCREMENT);
    7.62 -
    7.63 +  
    7.64 +  stack = IoGetCurrentIrpStackLocation(irp);
    7.65 +  file = stack->FileObject;
    7.66 +  
    7.67 +  KdPrint((__DRIVER_NAME "     filename = %wZ\n", &file->FileName));
    7.68 +  if (wcscmp(L"\\xenbus", file->FileName.Buffer) == 0)
    7.69 +  {
    7.70 +    status = XenPci_Irp_Create_XenBus(device_object, irp);
    7.71 +  }
    7.72 +  else
    7.73 +  {
    7.74 +    // legacy interface
    7.75 +    xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    7.76 +    file->FsContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(ULONG), XENPCI_POOL_TAG);
    7.77 +    status = STATUS_SUCCESS;    
    7.78 +    irp->IoStatus.Status = status;
    7.79 +    IoCompleteRequest(irp, IO_NO_INCREMENT);
    7.80 +  }
    7.81    FUNCTION_EXIT();
    7.82  
    7.83    return status;
    7.84 @@ -1349,15 +1347,27 @@ XenPci_Irp_Close_Fdo(PDEVICE_OBJECT devi
    7.85  {
    7.86    PXENPCI_DEVICE_DATA xpdd;
    7.87    NTSTATUS status;
    7.88 +  PIO_STACK_LOCATION stack;
    7.89 +  PFILE_OBJECT file;
    7.90  
    7.91    FUNCTION_ENTER();
    7.92 +  
    7.93 +  stack = IoGetCurrentIrpStackLocation(irp);
    7.94 +  file = stack->FileObject;
    7.95  
    7.96 -  // wait until pending irp's 
    7.97 -  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    7.98 -  status = STATUS_SUCCESS;    
    7.99 -  irp->IoStatus.Status = status;
   7.100 -  IoCompleteRequest(irp, IO_NO_INCREMENT);
   7.101 -
   7.102 +  if (*(PULONG)file->FsContext == DEVICE_INTERFACE_TYPE_XENBUS)
   7.103 +  {
   7.104 +    status = XenPci_Irp_Close_XenBus(device_object, irp);
   7.105 +  }
   7.106 +  else
   7.107 +  {
   7.108 +    // wait until pending irp's 
   7.109 +    xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   7.110 +    status = STATUS_SUCCESS;    
   7.111 +    irp->IoStatus.Status = status;
   7.112 +    IoCompleteRequest(irp, IO_NO_INCREMENT);
   7.113 +  }
   7.114 +  
   7.115    FUNCTION_EXIT();
   7.116  
   7.117    return status;
   7.118 @@ -1370,49 +1380,101 @@ XenPci_Irp_Read_Fdo(PDEVICE_OBJECT devic
   7.119    NTSTATUS status;
   7.120    PIO_STACK_LOCATION stack;
   7.121    KIRQL old_irql;
   7.122 +  PFILE_OBJECT file;
   7.123  
   7.124    FUNCTION_ENTER();
   7.125 +  
   7.126 +  stack = IoGetCurrentIrpStackLocation(irp);
   7.127 +  file = stack->FileObject;
   7.128 +
   7.129 +  if (*(PULONG)file->FsContext == DEVICE_INTERFACE_TYPE_XENBUS)
   7.130 +  {
   7.131 +    status = XenPci_Irp_Read_XenBus(device_object, irp);
   7.132 +  }
   7.133 +  else
   7.134 +  {
   7.135 +    xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   7.136 +    stack = IoGetCurrentIrpStackLocation(irp);
   7.137 +    if (stack->Parameters.Read.Length == 0)
   7.138 +    {
   7.139 +      irp->IoStatus.Information = 0;
   7.140 +      status = STATUS_SUCCESS;    
   7.141 +      irp->IoStatus.Status = status;
   7.142 +      IoCompleteRequest(irp, IO_NO_INCREMENT);
   7.143 +    }
   7.144 +    else 
   7.145 +    {
   7.146 +      KdPrint((__DRIVER_NAME "     stack = %p\n", stack));
   7.147 +      KdPrint((__DRIVER_NAME "     length = %d, buffer = %p\n", stack->Parameters.Read.Length, irp->AssociatedIrp.SystemBuffer));
   7.148 +      
   7.149 +      KeAcquireSpinLock(&xpdd->shutdown_ring_lock, &old_irql);
   7.150 +      xpdd->shutdown_irp = irp;
   7.151 +      IoSetCancelRoutine(irp, XenBus_ShutdownIoCancel);
   7.152 +      KeReleaseSpinLock(&xpdd->shutdown_ring_lock, old_irql);
   7.153 +      status = XenPci_ProcessShutdownIrp(xpdd);
   7.154 +    }
   7.155 +  }
   7.156 +  FUNCTION_EXIT();
   7.157 +
   7.158 +  return status;
   7.159 +}
   7.160 +
   7.161 +NTSTATUS
   7.162 +XenPci_Irp_Write_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
   7.163 +{
   7.164 +  PXENPCI_DEVICE_DATA xpdd;
   7.165 +  NTSTATUS status;
   7.166 +  PIO_STACK_LOCATION stack;
   7.167 +  PFILE_OBJECT file;
   7.168 +
   7.169 +  FUNCTION_ENTER();
   7.170 +  
   7.171 +  stack = IoGetCurrentIrpStackLocation(irp);
   7.172 +  file = stack->FileObject;
   7.173  
   7.174    xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   7.175    stack = IoGetCurrentIrpStackLocation(irp);
   7.176 -  if (stack->Parameters.Read.Length == 0)
   7.177 +
   7.178 +  if (*(PULONG)file->FsContext == DEVICE_INTERFACE_TYPE_XENBUS)
   7.179    {
   7.180 -    irp->IoStatus.Information = 0;
   7.181 -    status = STATUS_SUCCESS;    
   7.182 +    status = XenPci_Irp_Close_XenBus(device_object, irp);
   7.183 +  }
   7.184 +  else
   7.185 +  {
   7.186 +    status = STATUS_UNSUCCESSFUL;
   7.187      irp->IoStatus.Status = status;
   7.188      IoCompleteRequest(irp, IO_NO_INCREMENT);
   7.189 -  }
   7.190 -  else 
   7.191 -  {
   7.192 -    KdPrint((__DRIVER_NAME "     stack = %p\n", stack));
   7.193 -    KdPrint((__DRIVER_NAME "     length = %d, buffer = %p\n", stack->Parameters.Read.Length, irp->AssociatedIrp.SystemBuffer));
   7.194 -    
   7.195 -    KeAcquireSpinLock(&xpdd->shutdown_ring_lock, &old_irql);
   7.196 -    xpdd->shutdown_irp = irp;
   7.197 -    IoSetCancelRoutine(irp, XenBus_ShutdownIoCancel);
   7.198 -    KeReleaseSpinLock(&xpdd->shutdown_ring_lock, old_irql);
   7.199 -    status = XenPci_ProcessShutdownIrp(xpdd);
   7.200 -  }
   7.201 +  }    
   7.202  
   7.203    FUNCTION_EXIT();
   7.204  
   7.205    return status;
   7.206  }
   7.207  
   7.208 -
   7.209  NTSTATUS
   7.210  XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
   7.211  {
   7.212    NTSTATUS status;
   7.213 +  PIO_STACK_LOCATION stack;
   7.214 +  PFILE_OBJECT file;
   7.215  
   7.216    UNREFERENCED_PARAMETER(device_object);
   7.217  
   7.218    FUNCTION_ENTER();
   7.219    
   7.220 -  status = STATUS_SUCCESS;
   7.221 -  irp->IoStatus.Status = status;
   7.222 -  IoCompleteRequest(irp, IO_NO_INCREMENT);
   7.223 +  stack = IoGetCurrentIrpStackLocation(irp);
   7.224 +  file = stack->FileObject;
   7.225    
   7.226 +  if (*(PULONG)file->FsContext == DEVICE_INTERFACE_TYPE_XENBUS)
   7.227 +  {
   7.228 +    status = XenPci_Irp_Close_XenBus(device_object, irp);
   7.229 +  }
   7.230 +  else
   7.231 +  {
   7.232 +    status = STATUS_SUCCESS;
   7.233 +    irp->IoStatus.Status = status;
   7.234 +    IoCompleteRequest(irp, IO_NO_INCREMENT);
   7.235 +  }
   7.236    FUNCTION_EXIT();
   7.237  
   7.238    return status;
     8.1 --- a/xenpci/xenpci_pdo.c	Mon Dec 22 22:34:13 2008 +1100
     8.2 +++ b/xenpci/xenpci_pdo.c	Mon Dec 22 22:34:52 2008 +1100
     8.3 @@ -397,7 +397,7 @@ XenPci_GntTbl_GetRef(PVOID Context)
     8.4  }
     8.5  
     8.6  PCHAR
     8.7 -XenPci_XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value)
     8.8 +XenPci_XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value)
     8.9  {
    8.10    PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    8.11    PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    8.12 @@ -405,7 +405,7 @@ XenPci_XenBus_Read(PVOID Context, xenbus
    8.13  }
    8.14  
    8.15  PCHAR
    8.16 -XenPci_XenBus_Write(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *value)
    8.17 +XenPci_XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value)
    8.18  {
    8.19    PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    8.20    PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    8.21 @@ -413,7 +413,7 @@ XenPci_XenBus_Write(PVOID Context, xenbu
    8.22  }
    8.23  
    8.24  PCHAR
    8.25 -XenPci_XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *fmt, ...)
    8.26 +XenPci_XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...)
    8.27  {
    8.28    //PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    8.29    //PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    8.30 @@ -442,7 +442,7 @@ XenPci_XenBus_EndTransaction(PVOID Conte
    8.31  }
    8.32  
    8.33  PCHAR
    8.34 -XenPci_XenBus_List(PVOID Context, xenbus_transaction_t xbt, const char *prefix, char ***contents)
    8.35 +XenPci_XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents)
    8.36  {
    8.37    PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    8.38    PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    8.39 @@ -450,7 +450,7 @@ XenPci_XenBus_List(PVOID Context, xenbus
    8.40  }
    8.41  
    8.42  PCHAR
    8.43 -XenPci_XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, const char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
    8.44 +XenPci_XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
    8.45  {
    8.46    PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    8.47    PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    8.48 @@ -471,7 +471,7 @@ XenPci_XenBus_AddWatch(PVOID Context, xe
    8.49  }
    8.50  
    8.51  PCHAR
    8.52 -XenPci_XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, const char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
    8.53 +XenPci_XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext)
    8.54  {
    8.55    PXENPCI_PDO_DEVICE_DATA xppdd = Context;
    8.56    PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    8.57 @@ -1532,6 +1532,23 @@ XenPci_Irp_Read_Pdo(PDEVICE_OBJECT devic
    8.58  }
    8.59  
    8.60  NTSTATUS
    8.61 +XenPci_Irp_Write_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
    8.62 +{
    8.63 +  NTSTATUS status;
    8.64 +
    8.65 +  UNREFERENCED_PARAMETER(device_object);
    8.66 +
    8.67 +  FUNCTION_ENTER();
    8.68 +
    8.69 +  status = irp->IoStatus.Status;
    8.70 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
    8.71 +
    8.72 +  FUNCTION_EXIT();
    8.73 +
    8.74 +  return status;
    8.75 +}
    8.76 +
    8.77 +NTSTATUS
    8.78  XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp)
    8.79  {
    8.80    NTSTATUS status;