Commit 9647fd4e authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

rpc: add method for listing PCI devices



This RPC lists all PCI devices attached to an SPDK application.  Each
device is identified by a BDF and contains a buffer with a copy of its
config space.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I852f421fde105d975458f8e63b8da4f92ed2c69b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10652


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Community-CI: Mellanox Build Bot
parent 2c9895de
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -9095,3 +9095,47 @@ Example response:
  }
}
~~

### framework_get_pci_devices

List PCIe devices attached to an SPDK application and the contents of their config space.

#### Parameters

This method has no parameters.

#### Response

The response is an array of attached PCIe devices.

#### Example

Example request:
~~
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "framework_get_pci_devices"
}
~~

Example response:
Note that the config space buffer was trimmed.
~~
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    [
      {
        "address": "0000:00:04.0",
        "config_space": "8680455807051000...0000000000000000"
      },
      {
        "address": "0000:00:03.0",
        "config_space": "8680455807051000...0000000000000000"
      }
    ]
  }
}
~~
+53 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include "spdk/string.h"
#include "spdk/util.h"
#include "spdk/env.h"
#include "spdk/log.h"

#include "spdk_internal/init.h"

@@ -119,3 +120,55 @@ rpc_framework_get_config(struct spdk_jsonrpc_request *request,

SPDK_RPC_REGISTER("framework_get_config", rpc_framework_get_config, SPDK_RPC_RUNTIME)
SPDK_RPC_REGISTER_ALIAS_DEPRECATED(framework_get_config, get_subsystem_config)

static void
dump_pci_device(void *ctx, struct spdk_pci_device *dev)
{
	struct spdk_json_write_ctx *w = ctx;
	struct spdk_pci_addr addr;
	char config[4096], bdf[14];
	int rc;

	addr = spdk_pci_device_get_addr(dev);
	spdk_pci_addr_fmt(bdf, sizeof(bdf), &addr);

	rc = spdk_pci_device_cfg_read(dev, config, sizeof(config), 0);
	if (rc != 0) {
		SPDK_ERRLOG("Failed to read config space of device: %s\n", bdf);
		return;
	}

	spdk_json_write_object_begin(w);
	spdk_json_write_named_string(w, "address", bdf);

	/* Don't write the extended config space if it's all zeroes */
	if (spdk_mem_all_zero(&config[256], sizeof(config) - 256)) {
		spdk_json_write_named_bytearray(w, "config_space", config, 256);
	} else {
		spdk_json_write_named_bytearray(w, "config_space", config, sizeof(config));
	}

	spdk_json_write_object_end(w);
}

static void
rpc_framework_get_pci_devices(struct spdk_jsonrpc_request *request,
			      const struct spdk_json_val *params)
{
	struct spdk_json_write_ctx *w;

	if (params != NULL) {
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
						 "framework_get_pci_devices doesn't accept any parameters.\n");
		return;
	}

	w = spdk_jsonrpc_begin_result(request);

	spdk_json_write_array_begin(w);
	spdk_pci_for_each_device(w, dump_pci_device);
	spdk_json_write_array_end(w);

	spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("framework_get_pci_devices", rpc_framework_get_pci_devices, SPDK_RPC_RUNTIME)
+6 −0
Original line number Diff line number Diff line
@@ -2690,6 +2690,12 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
    p.add_argument('-i', '--impl', help='Socket implementation name, e.g. posix', required=True)
    p.set_defaults(func=sock_set_default_impl)

    def framework_get_pci_devices(args):
        print_json(rpc.subsystem.framework_get_pci_devices(args.client))

    p = subparsers.add_parser('framework_get_pci_devices', help='''Get a list of attached PCI devices''')
    p.set_defaults(func=framework_get_pci_devices)

    def check_called_name(name):
        if name in deprecated_aliases:
            print("{} is deprecated, use {} instead.".format(name, deprecated_aliases[name]), file=sys.stderr)
+4 −0
Original line number Diff line number Diff line
@@ -10,3 +10,7 @@ def framework_get_subsystems(client):
def framework_get_config(client, name):
    params = {'name': name}
    return client.call('framework_get_config', params)


def framework_get_pci_devices(client):
    return client.call('framework_get_pci_devices')