Parcourir la source

drm/nouveau/client: add method to retrieve device list

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Ben Skeggs il y a 11 ans
Parent
commit
803c1787ef

+ 42 - 0
drivers/gpu/drm/nouveau/core/core/client.c

@@ -26,6 +26,7 @@
 #include <core/client.h>
 #include <core/handle.h>
 #include <core/option.h>
+#include <nvif/unpack.h>
 #include <nvif/class.h>
 
 #include <nvif/unpack.h>
@@ -139,6 +140,46 @@ nvkm_client_notify_new(struct nouveau_client *client,
 	return 0;
 }
 
+static int
+nouveau_client_devlist(struct nouveau_object *object, void *data, u32 size)
+{
+	union {
+		struct nv_client_devlist_v0 v0;
+	} *args = data;
+	int ret;
+
+	nv_ioctl(object, "client devlist size %d\n", size);
+	if (nvif_unpack(args->v0, 0, 0, true)) {
+		nv_ioctl(object, "client devlist vers %d count %d\n",
+			 args->v0.version, args->v0.count);
+		if (size == sizeof(args->v0.device[0]) * args->v0.count) {
+			ret = nouveau_device_list(args->v0.device,
+						  args->v0.count);
+			if (ret >= 0) {
+				args->v0.count = ret;
+				ret = 0;
+			}
+		} else {
+			ret = -EINVAL;
+		}
+	}
+
+	return ret;
+}
+
+static int
+nouveau_client_mthd(struct nouveau_object *object, u32 mthd,
+		    void *data, u32 size)
+{
+	switch (mthd) {
+	case NV_CLIENT_DEVLIST:
+		return nouveau_client_devlist(object, data, size);
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
 static void
 nouveau_client_dtor(struct nouveau_object *object)
 {
@@ -155,6 +196,7 @@ static struct nouveau_oclass
 nouveau_client_oclass = {
 	.ofuncs = &(struct nouveau_ofuncs) {
 		.dtor = nouveau_client_dtor,
+		.mthd = nouveau_client_mthd,
 	},
 };
 

+ 14 - 0
drivers/gpu/drm/nouveau/core/engine/device/base.c

@@ -54,6 +54,20 @@ nouveau_device_find(u64 name)
 	return match;
 }
 
+int
+nouveau_device_list(u64 *name, int size)
+{
+	struct nouveau_device *device;
+	int nr = 0;
+	mutex_lock(&nv_devices_mutex);
+	list_for_each_entry(device, &nv_devices, head) {
+		if (nr++ < size)
+			name[nr - 1] = device->handle;
+	}
+	mutex_unlock(&nv_devices_mutex);
+	return nr;
+}
+
 /******************************************************************************
  * nouveau_devobj (0x0080): class implementation
  *****************************************************************************/

+ 2 - 0
drivers/gpu/drm/nouveau/core/include/core/device.h

@@ -101,6 +101,8 @@ struct nouveau_device {
 	} acpi;
 };
 
+int nouveau_device_list(u64 *name, int size);
+
 static inline struct nouveau_device *
 nv_device(void *obj)
 {

+ 14 - 0
drivers/gpu/drm/nouveau/nvif/class.h

@@ -9,6 +9,20 @@
 #define NV_DEVICE                                                    0x00000080
 
 
+/*******************************************************************************
+ * client
+ ******************************************************************************/
+
+#define NV_CLIENT_DEVLIST                                                  0x00
+
+struct nv_client_devlist_v0 {
+	__u8  version;
+	__u8  count;
+	__u8  pad02[6];
+	__u64 device[];
+};
+
+
 /*******************************************************************************
  * device
  ******************************************************************************/