diff options
Diffstat (limited to 'bin/util.h')
-rw-r--r-- | bin/util.h | 79 |
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; } |