@@ -136,6 +136,25 @@
*/
#define PCID_CMD_REVERT_ASSIGNABLE "revert_assignable"
+/*
+ *******************************************************************************
+ * Check is device assigned
+ *
+ * This command checks device is assigned
+ *
+ * Request (see other mandatory fields above):
+ * - "cmd" field of the request must be set to "is_device_assigned".
+ * - "sbdf" SBDF of the device in format defined by PCID_SBDF_FMT.
+ *
+ * Response (see other mandatory fields above):
+ * - "resp" field of the response must be set to "is_device_assigned".
+ * Command specific response data:
+ * +-------------+--------------+----------------------------------------------+
+ * | result | bool | true if device assigned |
+ * +-------------+--------------+----------------------------------------------+
+ */
+#define PCID_CMD_IS_ASSIGNED "is_device_assigned"
+#define PCID_MSG_FIELD_RESULT "result"
int libxl_pcid_process(libxl_ctx *ctx);
@@ -86,7 +86,9 @@ static int pci_handle_response(libxl__gc *gc,
*result = libxl__json_object_alloc(gc, JSON_NULL);
else if (strcmp(command_name, PCID_CMD_REVERT_ASSIGNABLE) == 0)
*result = libxl__json_object_alloc(gc, JSON_NULL);
-
+ else if (strcmp(command_name, PCID_CMD_IS_ASSIGNED) == 0)
+ *result = (libxl__json_object *)libxl__json_map_get(PCID_MSG_FIELD_RESULT,
+ response, JSON_BOOL);
return ret;
}
@@ -753,30 +755,31 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
{
- char * spath;
+ struct vchan_info *vchan;
int rc;
- struct stat st;
+ libxl__json_object *args, *result;
- if ( access(SYSFS_PCIBACK_DRIVER, F_OK) < 0 ) {
- if ( errno == ENOENT ) {
- LOG(ERROR, "Looks like pciback driver is not loaded");
- } else {
- LOGE(ERROR, "Can't access "SYSFS_PCIBACK_DRIVER);
- }
- return -1;
+ vchan = pci_vchan_get_client(gc);
+ if (!vchan) {
+ rc = ERROR_NOT_READY;
+ goto out;
}
- spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
- pci->domain, pci->bus,
- pci->dev, pci->func);
- rc = lstat(spath, &st);
+ args = libxl__vchan_start_args(gc);
- if( rc == 0 )
- return 1;
- if ( rc < 0 && errno == ENOENT )
- return 0;
- LOGE(ERROR, "Accessing %s", spath);
- return -1;
+ libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_SBDF,
+ GCSPRINTF(PCID_SBDF_FMT, pci->domain,
+ pci->bus, pci->dev, pci->func));
+
+ result = vchan_send_command(gc, vchan, PCID_CMD_IS_ASSIGNED, args);
+ if (!result) {
+ rc = ERROR_FAIL;
+ }
+ rc = result->u.b;
+ pci_vchan_free(gc, vchan);
+
+out:
+ return rc;
}
static int libxl__device_pci_assignable_add(libxl__gc *gc,
@@ -147,7 +147,7 @@ static int pciback_dev_is_assigned(libxl__gc *gc, unsigned int domain,
if (rc < 0 && errno == ENOENT)
return 0;
LOGE(ERROR, "Accessing %s", spath);
- return -1;
+ return 0;
}
#define PCID_INFO_PATH "pcid"
@@ -335,6 +335,35 @@ static int pciback_dev_assign(libxl__gc *gc, unsigned int domain,
return 0;
}
+static int process_pciback_dev_is_assigned(libxl__gc *gc, yajl_gen gen,
+ char *command_name,
+ const struct libxl__json_object *request,
+ struct libxl__json_object **response)
+{
+ const struct libxl__json_object *json_o;
+ unsigned int dom, bus, dev, func;
+ int rc;
+
+ libxl__yajl_gen_asciiz(gen, PCID_MSG_FIELD_RESULT);
+ *response = libxl__json_object_alloc(gc, JSON_BOOL);
+ json_o = libxl__json_map_get(PCID_MSG_FIELD_SBDF, request, JSON_STRING);
+ if (!json_o) {
+ make_error_reply(gc, gen, "No mandatory parameter 'sbdf'", command_name);
+ return ERROR_FAIL;
+ }
+
+ if (sscanf(libxl__json_object_get_string(json_o), PCID_SBDF_FMT,
+ &dom, &bus, &dev, &func) != 4) {
+ make_error_reply(gc, gen, "Can't parse SBDF", command_name);
+ return ERROR_FAIL;
+ }
+ rc = pciback_dev_is_assigned(gc, dom, bus, dev, func);
+ if (rc < 0)
+ return ERROR_FAIL;
+ (*response)->u.b = rc;
+ return 0;
+}
+
static int process_make_assignable(libxl__gc *gc, yajl_gen gen,
char *command_name,
const struct libxl__json_object *request,
@@ -538,6 +567,9 @@ static int pcid_handle_request(libxl__gc *gc, yajl_gen gen,
else if (strcmp(command_name, PCID_CMD_REVERT_ASSIGNABLE) == 0)
ret = process_revert_assignable(gc, gen, command_name,
request, &command_response);
+ else if (strcmp(command_name, PCID_CMD_IS_ASSIGNED) == 0)
+ ret = process_pciback_dev_is_assigned(gc, gen, command_name,
+ request, &command_response);
else {
/*
* This is an unsupported command: make a reply and proceed over