static VOID
XenBus_EvtFileCleanup(WDFFILEOBJECT file_object)
{
  PXENPCI_DEVICE_INTERFACE_DATA xpdid = GetXpdid(file_object);
  PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfFileObjectGetDevice(file_object));
  watch_context_t *watch_context;
  KIRQL old_irql;
  PCHAR msg;

  FUNCTION_ENTER();

  KeAcquireSpinLock(&xpdid->lock, &old_irql);

  while (!IsListEmpty(&xpdid->xenbus.watch_list_head))
  {
    watch_context = (watch_context_t *)RemoveHeadList(&xpdid->xenbus.watch_list_head);
    KeReleaseSpinLock(&xpdid->lock, old_irql);
    msg = XenBus_RemWatch(xpdd, XBT_NIL, watch_context->path, XenPci_IoWatch, watch_context);
    if (msg != NULL)
    {
      KdPrint((__DRIVER_NAME "     Error freeing watch (%s)\n", msg));
      XenPci_FreeMem(msg);
    }
    ExFreePoolWithTag(watch_context, XENPCI_POOL_TAG);
    WdfObjectDereference(file_object);
    KeAcquireSpinLock(&xpdid->lock, &old_irql);
  }

  KeReleaseSpinLock(&xpdid->lock, old_irql);
  
  FUNCTION_EXIT();
}
Exemplo n.º 2
0
/*
Called at PASSIVE_LEVEL(?)
Called during restore
*/
static ULONG
XenPci_ReadBackendState(PXENPCI_PDO_DEVICE_DATA xppdd)
{
  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  char path[128];
  char *value;
  char *err;
  ULONG backend_state;
  
  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
  err = XenBus_Read(xpdd, XBT_NIL, path, &value);
  if (err)
  {
    XenPci_FreeMem(err);
    return XenbusStateUnknown;
  }
  else
  {
    backend_state = atoi(value);
    XenPci_FreeMem(value);
    return backend_state;
  }
}
Exemplo n.º 3
0
static NTSTATUS
XenPci_GetBackendDetails(WDFDEVICE device)
{
  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  PXENPCI_DEVICE_DATA xpdd = GetXpdd(xppdd->wdf_device_bus_fdo);
  char path[128];
  PCHAR res;
  PCHAR value;

  FUNCTION_ENTER();
  /* Get backend path */
  RtlStringCbPrintfA(path, ARRAY_SIZE(path),
    "%s/backend", xppdd->path);
  res = XenBus_Read(xpdd, XBT_NIL, path, &value);
  if (res)
  {
    FUNCTION_MSG("Failed to read backend path\n");
    XenPci_FreeMem(res);
    return STATUS_UNSUCCESSFUL;
  }
  RtlStringCbCopyA(xppdd->backend_path, ARRAY_SIZE(xppdd->backend_path), value);
  XenPci_FreeMem(value);

  /* Get backend id */
  RtlStringCbPrintfA(path, ARRAY_SIZE(path),
    "%s/backend-id", xppdd->path);
  res = XenBus_Read(xpdd, XBT_NIL, path, &value);
  if (res) {
    FUNCTION_MSG("Failed to read backend id\n");
    XenPci_FreeMem(res);
    return STATUS_UNSUCCESSFUL;
  }
  xppdd->backend_id = (domid_t)atoi(value);
  XenPci_FreeMem(value);
  FUNCTION_EXIT();  
  return STATUS_SUCCESS;
}
Exemplo n.º 4
0
NTSTATUS
XenPci_SuspendPdo(WDFDEVICE device) {
  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  PCHAR response;
  CHAR path[128];

  if (xppdd->device_callback) {
    FUNCTION_MSG("Suspending %s\n", xppdd->device);
    xppdd->device_callback(xppdd->device_callback_context, XN_DEVICE_CALLBACK_SUSPEND, NULL);
    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
    response = XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
    if (response) {
      FUNCTION_MSG("XnRemWatch - %s = %s\n", path, response);
      XenPci_FreeMem(response);
    }
  }
  return STATUS_SUCCESS;
}
Exemplo n.º 5
0
NTSTATUS
XenPci_ResumePdo(WDFDEVICE device) {
  PXENPCI_PDO_DEVICE_DATA xppdd = GetXppdd(device);
  PXENPCI_DEVICE_DATA xpdd = xppdd->xpdd;
  PCHAR response;
  CHAR path[128];

  XenPci_GetBackendDetails(device);
  if (xppdd->device_callback) {
    FUNCTION_MSG("Resuming %s\n", xppdd->device);
    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
    response = XenBus_AddWatch(xpdd, XBT_NIL, path, XenPci_BackendStateCallback, xppdd);
    if (response) {
      FUNCTION_MSG("XnAddWatch - %s = %s\n", path, response);
      XenPci_FreeMem(response);
      xppdd->device_callback = NULL;
      xppdd->device_callback_context = NULL;
      FUNCTION_EXIT();
      return STATUS_UNSUCCESSFUL;
    }
    xppdd->device_callback(xppdd->device_callback_context, XN_DEVICE_CALLBACK_RESUME, NULL);
  }
  return STATUS_SUCCESS;
}
Exemplo n.º 6
0
/* If Initialize fails then the watch still gets called but the waits will never be acked... */
static VOID
XenScsi_DevWatch(PCHAR path, PVOID DeviceExtension)
{
  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
  CHAR tmp_path[128];
  PCHAR msg;
  PCHAR *devices;
  PCHAR value;
  scsi_dev_t *dev;
  ULONG i;
  ULONG dev_no;
  ULONG state;
  LARGE_INTEGER wait_time;
  #if DBG
  ULONG oldpause;
  #endif

  UNREFERENCED_PARAMETER(path);
  
  /* this can only be called from a watch and so is always serialised */
  FUNCTION_ENTER();

  #if DBG
  oldpause =
  #endif
    InterlockedExchange(&xsdd->shared_paused, SHARED_PAUSED_PASSIVE_PAUSED);
  ASSERT(oldpause == SHARED_PAUSED_SCSIPORT_UNPAUSED);
  
  while (InterlockedCompareExchange(&xsdd->shared_paused, SHARED_PAUSED_SCSIPORT_PAUSED, SHARED_PAUSED_SCSIPORT_PAUSED) != SHARED_PAUSED_SCSIPORT_PAUSED)
  {
    KdPrint((__DRIVER_NAME "     Waiting for pause...\n"));
    wait_time.QuadPart = -100 * 1000 * 10; /* 100ms */
    KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
  }
  
  KdPrint((__DRIVER_NAME "     Watch triggered on %s\n", path));
  RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.backend_path);
  RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/vscsi-devs");
  msg = xsdd->vectors.XenBus_List(xsdd->vectors.context, XBT_NIL, tmp_path, &devices);
  if (msg)
  {
    /* this is pretty fatal ... */
    KdPrint((__DRIVER_NAME "     cannot read - %s\n", msg));
    return;
  }
  for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
    dev != (scsi_dev_t *)&xsdd->dev_list_head;
    dev = (scsi_dev_t *)dev->entry.Flink)
  {
    dev->validated = FALSE;
  }
  
  for (i = 0; devices[i]; i++)
  {
    if (strncmp(devices[i], "dev-", 4) != 0)
    {
      XenPci_FreeMem(devices[i]);
      break; /* not a dev so we are not interested */
    }
    dev_no = atoi(devices[i] + 4);
    RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.backend_path);
    RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/vscsi-devs/");
    RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), devices[i]);
    RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/state");
    msg = xsdd->vectors.XenBus_Read(xsdd->vectors.context, XBT_NIL, tmp_path, &value);
    if (msg)
    {
      KdPrint((__DRIVER_NAME "     failed to read state for device %d\n", dev_no));
      state = 0;
    }
    else
      state = atoi(value);
    for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
      dev != (scsi_dev_t *)&xsdd->dev_list_head;
      dev = (scsi_dev_t * )dev->entry.Flink)
    {
      if (dev->dev_no == dev_no)
        break;
    }
    if (dev == (scsi_dev_t *)&xsdd->dev_list_head)
    {
      KdPrint((__DRIVER_NAME "     new dev %d\n", dev_no));
      dev = ExAllocatePoolWithTag(NonPagedPool, sizeof(scsi_dev_t), XENSCSI_POOL_TAG);
      dev->dev_no = dev_no;
      dev->state = state;
      dev->validated = TRUE;
      RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.backend_path);
      RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/vscsi-devs/");
      RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), devices[i]);
      RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/v-dev");
      msg = xsdd->vectors.XenBus_Read(xsdd->vectors.context, XBT_NIL, tmp_path, &value);
      if (msg)
      {
        KdPrint((__DRIVER_NAME "     failed to read v-dev for device %d\n", dev_no));
        continue;
      }
      else
      {
        XenScsi_ParseBackendDevice(dev, value);
        // should verify that the controller = this
      }
      RtlStringCbCopyA(tmp_path, ARRAY_SIZE(tmp_path), xsdd->vectors.path);
      RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/vscsi-devs/");
      RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), devices[i]);
      RtlStringCbCatA(tmp_path, ARRAY_SIZE(tmp_path), "/state");
      msg = xsdd->vectors.XenBus_Write(xsdd->vectors.context, XBT_NIL, tmp_path, "4");
      if (msg)
      {
        KdPrint((__DRIVER_NAME "     failed to write state %d to %s\n", 4, tmp_path));
        continue;
      }
      KdPrint((__DRIVER_NAME "     setting changes[%d]\n", dev->channel));
      xsdd->bus_changes[dev->channel] = 1;
      InsertTailList(&xsdd->dev_list_head, (PLIST_ENTRY)dev);
    }
    else
    {
      // need to manage state change
      // and write frontend state
      dev->state = state;
      dev->validated = TRUE;
      KdPrint((__DRIVER_NAME "     existing dev %d state = %d\n", dev_no, dev->state));
    }
    XenPci_FreeMem(devices[i]);
  }
  XenPci_FreeMem(devices);

  #if DBG
  oldpause =
  #endif
    InterlockedExchange(&xsdd->shared_paused, SHARED_PAUSED_PASSIVE_UNPAUSED);
  ASSERT(oldpause == SHARED_PAUSED_SCSIPORT_PAUSED);

  while (InterlockedCompareExchange(&xsdd->shared_paused, SHARED_PAUSED_SCSIPORT_UNPAUSED, SHARED_PAUSED_SCSIPORT_UNPAUSED) != SHARED_PAUSED_SCSIPORT_UNPAUSED)
  {
    KdPrint((__DRIVER_NAME "     Waiting for unpause...\n"));
    wait_time.QuadPart = -100 * 1000 * 10; /* 100ms */
    KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
  }
  KdPrint((__DRIVER_NAME "     Unpaused\n"));

  FUNCTION_EXIT();
}