mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
libxl_usb: Make libxl__device_usbdev_add uses ev_qmp
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
This commit is contained in:
1 parent
dd0dffb885
commit
40c7eca10a
1 file changed
+80
-17
+80
-17
@@ -395,26 +395,25 @@ static int libxl__device_usbctrl_del_hvm(libxl__gc *gc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send qmp commands to create a usb device in qemu. */
|
/* Send qmp commands to create a usb device in qemu. */
|
||||||
static int libxl__device_usbdev_add_hvm(libxl__gc *gc, uint32_t domid,
|
static int libxl__device_usbdev_add_hvm(libxl__gc *gc, libxl__ev_qmp *qmp,
|
||||||
libxl_device_usbdev *usbdev)
|
libxl_device_usbdev *usbdev)
|
||||||
{
|
{
|
||||||
flexarray_t *qmp_args;
|
libxl__json_object *qmp_args = NULL;
|
||||||
|
|
||||||
qmp_args = flexarray_make(gc, 12, 1);
|
libxl__qmp_param_add_string(gc, &qmp_args, "id",
|
||||||
flexarray_append_pair(qmp_args, "id",
|
GCSPRINTF("xenusb-%d-%d", usbdev->u.hostdev.hostbus,
|
||||||
GCSPRINTF("xenusb-%d-%d",
|
usbdev->u.hostdev.hostaddr));
|
||||||
usbdev->u.hostdev.hostbus,
|
libxl__qmp_param_add_string(gc, &qmp_args, "driver", "usb-host");
|
||||||
usbdev->u.hostdev.hostaddr));
|
libxl__qmp_param_add_string(gc, &qmp_args, "bus",
|
||||||
flexarray_append_pair(qmp_args, "driver", "usb-host");
|
GCSPRINTF("xenusb-%d.0", usbdev->ctrl));
|
||||||
flexarray_append_pair(qmp_args, "bus",
|
libxl__qmp_param_add_string(gc, &qmp_args, "port",
|
||||||
GCSPRINTF("xenusb-%d.0", usbdev->ctrl));
|
GCSPRINTF("%d", usbdev->port));
|
||||||
flexarray_append_pair(qmp_args, "port", GCSPRINTF("%d", usbdev->port));
|
libxl__qmp_param_add_string(gc, &qmp_args, "hostbus",
|
||||||
flexarray_append_pair(qmp_args, "hostbus",
|
GCSPRINTF("%d", usbdev->u.hostdev.hostbus));
|
||||||
GCSPRINTF("%d", usbdev->u.hostdev.hostbus));
|
libxl__qmp_param_add_string(gc, &qmp_args, "hostaddr",
|
||||||
flexarray_append_pair(qmp_args, "hostaddr",
|
GCSPRINTF("%d", usbdev->u.hostdev.hostaddr));
|
||||||
GCSPRINTF("%d", usbdev->u.hostdev.hostaddr));
|
|
||||||
|
|
||||||
return libxl__qmp_run_command_flexarray(gc, domid, "device_add", qmp_args);
|
return libxl__ev_qmp_send(gc, qmp, "device_add", qmp_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send qmp commands to delete a usb device in qemu. */
|
/* Send qmp commands to delete a usb device in qemu. */
|
||||||
@@ -1639,6 +1638,13 @@ out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void device_usbdev_add_qmp_cb(libxl__egc *egc,
|
||||||
|
libxl__ev_qmp *qmp, const libxl__json_object *r, int rc);
|
||||||
|
static void device_usbdev_add_timeout(libxl__egc *egc,
|
||||||
|
libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
|
||||||
|
static void device_usbdev_add_done(libxl__egc *egc,
|
||||||
|
libxl__ao_device *aodev, int rc);
|
||||||
|
|
||||||
/* AO operation to add a usb device.
|
/* AO operation to add a usb device.
|
||||||
*
|
*
|
||||||
* Generally, it does:
|
* Generally, it does:
|
||||||
@@ -1665,9 +1671,14 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
|
|||||||
int num_assigned;
|
int num_assigned;
|
||||||
libxl_device_usbctrl usbctrl;
|
libxl_device_usbctrl usbctrl;
|
||||||
char *busid;
|
char *busid;
|
||||||
|
bool has_callback = false;
|
||||||
|
|
||||||
libxl_device_usbctrl_init(&usbctrl);
|
libxl_device_usbctrl_init(&usbctrl);
|
||||||
|
|
||||||
|
/* Store *usbdev to be used by callbacks */
|
||||||
|
aodev->device_config = usbdev;
|
||||||
|
aodev->device_type = &libxl__usbdev_devtype;
|
||||||
|
|
||||||
/* Currently only support adding USB device from Dom0 backend.
|
/* Currently only support adding USB device from Dom0 backend.
|
||||||
* So, if USB controller is specified, check its backend domain,
|
* So, if USB controller is specified, check its backend domain,
|
||||||
* if it's not Dom0, report error.
|
* if it's not Dom0, report error.
|
||||||
@@ -1751,12 +1762,22 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
|
|||||||
aodev->update_json);
|
aodev->update_json);
|
||||||
if (rc) goto out;
|
if (rc) goto out;
|
||||||
|
|
||||||
rc = libxl__device_usbdev_add_hvm(gc, domid, usbdev);
|
rc = libxl__ev_time_register_rel(ao, &aodev->timeout,
|
||||||
|
device_usbdev_add_timeout,
|
||||||
|
LIBXL_QMP_CMD_TIMEOUT * 1000);
|
||||||
|
if (rc) goto out;
|
||||||
|
|
||||||
|
aodev->qmp.ao = ao;
|
||||||
|
aodev->qmp.domid = domid;
|
||||||
|
aodev->qmp.callback = device_usbdev_add_qmp_cb;
|
||||||
|
aodev->qmp.payload_fd = -1;
|
||||||
|
rc = libxl__device_usbdev_add_hvm(gc, &aodev->qmp, usbdev);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
libxl__device_usbdev_remove_xenstore(gc, domid, usbdev,
|
libxl__device_usbdev_remove_xenstore(gc, domid, usbdev,
|
||||||
LIBXL_USBCTRL_TYPE_DEVICEMODEL);
|
LIBXL_USBCTRL_TYPE_DEVICEMODEL);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
has_callback = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOGD(ERROR, domid, "Unsupported usb controller type");
|
LOGD(ERROR, domid, "Unsupported usb controller type");
|
||||||
@@ -1768,6 +1789,48 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
libxl_device_usbctrl_dispose(&usbctrl);
|
libxl_device_usbctrl_dispose(&usbctrl);
|
||||||
|
/* Only call _done if no callback have been setup */
|
||||||
|
if (!has_callback)
|
||||||
|
device_usbdev_add_done(egc, aodev, rc); /* must be last */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void device_usbdev_add_timeout(libxl__egc *egc,
|
||||||
|
libxl__ev_time *ev,
|
||||||
|
const struct timeval *requested_abs,
|
||||||
|
int rc)
|
||||||
|
{
|
||||||
|
EGC_GC;
|
||||||
|
libxl__ao_device *aodev = CONTAINER_OF(ev, *aodev, timeout);
|
||||||
|
|
||||||
|
if (rc == ERROR_TIMEDOUT)
|
||||||
|
LOGD(ERROR, aodev->qmp.domid,
|
||||||
|
"Adding usbdev to QEMU timed out");
|
||||||
|
device_usbdev_add_qmp_cb(egc, &aodev->qmp, NULL, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void device_usbdev_add_qmp_cb(libxl__egc *egc,
|
||||||
|
libxl__ev_qmp *qmp,
|
||||||
|
const libxl__json_object *r,
|
||||||
|
int rc)
|
||||||
|
{
|
||||||
|
EGC_GC;
|
||||||
|
libxl__ao_device *aodev = CONTAINER_OF(qmp, *aodev, qmp);
|
||||||
|
libxl_device_usbdev *const usbdev = aodev->device_config;
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
libxl__device_usbdev_remove_xenstore(gc, qmp->domid,
|
||||||
|
usbdev, LIBXL_USBCTRL_TYPE_DEVICEMODEL);
|
||||||
|
device_usbdev_add_done(egc, aodev, rc); /* must be last */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void device_usbdev_add_done(libxl__egc *egc,
|
||||||
|
libxl__ao_device *aodev,
|
||||||
|
int rc)
|
||||||
|
{
|
||||||
|
EGC_GC;
|
||||||
|
|
||||||
|
libxl__ev_time_deregister(gc, &aodev->timeout);
|
||||||
|
libxl__ev_qmp_dispose(gc, &aodev->qmp);
|
||||||
aodev->rc = rc;
|
aodev->rc = rc;
|
||||||
aodev->callback(egc, aodev);
|
aodev->callback(egc, aodev);
|
||||||
}
|
}
|
||||||
|
|||||||