summaryrefslogtreecommitdiff
path: root/bin/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'bin/util.h')
-rw-r--r--bin/util.h79
1 files changed, 65 insertions, 14 deletions
diff --git a/bin/util.h b/bin/util.h
index af6feac44..c3f6edfef 100644
--- a/bin/util.h
+++ b/bin/util.h
@@ -12,7 +12,7 @@
static const char *u_drv;
static const char *u_cfg;
static const char *u_dbg;
-static u64 u_dev = ~0ULL;
+static int u_dev = 0;
static inline bool
u_option(int c)
@@ -30,30 +30,81 @@ u_option(int c)
static inline int
u_client(const char *drv, const char *name, const char *dbg,
- bool detect, bool mmio, u64 subdev,
- struct nvif_client **pclient)
+ bool detect, bool mmio, u64 subdev, struct nvif_client *client)
{
os_device_detect = detect;
os_device_mmio = mmio;
os_device_subdev = subdev;
- return nvif_client_new(u_drv ? u_drv : drv, name, u_dev, u_cfg,
- u_dbg ? u_dbg : dbg, pclient);
+ return nvif_client_init(u_drv ? u_drv : drv, name, ~0ULL, u_cfg,
+ u_dbg ? u_dbg : dbg, client);
+}
+
+static inline struct nv_client_devlist_v0 *
+u_device_list(struct nvif_client *client)
+{
+ struct nvif_object *object = &client->object;
+ struct nv_client_devlist_v0 *args;
+ int count = 0;
+
+ for (;;) {
+ u32 size = sizeof(*args) + count * sizeof(args->device[0]);
+ if (!(args = malloc(size)))
+ return NULL;
+ args->version = 0;
+ args->count = count;
+
+ if (nvif_object_mthd(object, NV_CLIENT_DEVLIST, args, size)) {
+ free(args);
+ return NULL;
+ }
+
+ if (args->count == count)
+ return args;
+ count = args->count;
+ free(args);
+ }
+}
+
+static inline void
+u_device_show(struct nvif_client *client)
+{
+ struct nv_client_devlist_v0 *args = u_device_list(client);
+ int i;
+ printf("device(s):\n");
+ for (i = 0; args && i < args->count; i++)
+ printf("%2d: %016llx\n", i, args->device[i]);
+ free(args);
+}
+
+static inline u64
+u_device_name(struct nvif_client *client, int idx)
+{
+ struct nv_client_devlist_v0 *args = u_device_list(client);
+ u64 device = ~0ULL;
+ if (args) {
+ if (idx >= 0 && idx < args->count)
+ device = args->device[idx];
+ else
+ u_device_show(client);
+ free(args);
+ }
+ return device;
}
static inline int
u_device(const char *drv, const char *name, const char *dbg,
bool detect, bool mmio, u64 subdev, u32 handle,
- struct nvif_device **pdevice)
+ struct nvif_client *client, struct nvif_device *pdevice)
{
- struct nvif_client *client;
- int ret = u_client(drv, name, dbg, detect, mmio, subdev, &client);
+ int ret = u_client(drv, name, dbg, detect, mmio, subdev, client);
if (ret == 0) {
- ret = nvif_device_new(client->object, handle, NV_DEVICE,
- &(struct nv_device_v0) {
- .device = ~0ULL,
- }, sizeof(struct nv_device_v0),
- pdevice);
- nvif_client_ref(NULL, &client);
+ ret = nvif_device_init(&client->object, handle, NV_DEVICE,
+ &(struct nv_device_v0) {
+ .device = u_device_name(client, u_dev),
+ }, sizeof(struct nv_device_v0),
+ pdevice);
+ if (ret)
+ nvif_client_fini(client);
}
return ret;
}