int nvrm_mthd_context_disable_device(struct nvrm_context *ctx, uint32_t handle, uint32_t gpu_id) { struct nvrm_mthd_context_disable_device arg = { .gpu_id = gpu_id, .unk04 = { 0xffffffff }, }; return nvrm_ioctl_call(ctx, handle, NVRM_MTHD_CONTEXT_DISABLE_DEVICE, &arg, sizeof arg); }
int nvrm_device_get_gpc_mask(struct nvrm_device *dev, uint32_t *mask) { struct nvrm_mthd_subdevice_get_gpc_mask arg = { }; int res = nvrm_ioctl_call(dev->ctx, dev->osubdev, NVRM_MTHD_SUBDEVICE_GET_GPC_MASK, &arg, sizeof arg); if (res) return res; *mask = arg.gpc_mask; return 0; }
int nvrm_device_get_chipset(struct nvrm_device *dev, uint32_t *major, uint32_t *minor, uint32_t *stepping) { struct nvrm_mthd_subdevice_get_chipset arg; int res = nvrm_ioctl_call(dev->ctx, dev->osubdev, NVRM_MTHD_SUBDEVICE_GET_CHIPSET, &arg, sizeof arg); if (res) return res; if (major) *major = arg.major; if (minor) *minor = arg.minor; if (stepping) *stepping = arg.stepping; return 0; }
int nvrm_mthd_context_list_devices(struct nvrm_context *ctx, uint32_t handle, uint32_t *gpu_id) { struct nvrm_mthd_context_list_devices arg = { }; int res = nvrm_ioctl_call(ctx, handle, NVRM_MTHD_CONTEXT_LIST_DEVICES, &arg, sizeof arg); int i; if (res) return res; for (i = 0; i < 32; i++) gpu_id[i] = arg.gpu_id[i]; return 0; }
struct nvrm_device *nvrm_device_open(struct nvrm_context *ctx, int idx) { idx = nvrm_xlat_device(ctx, idx); struct nvrm_device *dev = &ctx->devs[idx]; if (dev->open++) { if (!dev->open) { fprintf(stderr, "nvrm: open counter overflow\n"); abort(); } return 0; } if (nvrm_mthd_context_enable_device(ctx, ctx->cid, dev->gpu_id)) { goto out_enable; } char buf[20]; snprintf(buf, 20, "/dev/nvidia%d", idx); dev->fd = nvrm_open_file(buf); if (dev->fd < 0) goto out_open; #if 0 if (nvrm_ioctl_unk4d(ctx, ctx->cid)) goto out_unk4d; #endif struct nvrm_create_device arg = { .idx = idx, .cid = ctx->cid, }; dev->odev = nvrm_handle_alloc(ctx); if (nvrm_ioctl_create(ctx, ctx->cid, dev->odev, NVRM_CLASS_DEVICE_0, &arg)) goto out_dev; dev->osubdev = nvrm_handle_alloc(ctx); if (nvrm_ioctl_create(ctx, dev->odev, dev->osubdev, NVRM_CLASS_SUBDEVICE_0, 0)) goto out_subdev; return dev; out_subdev: nvrm_handle_free(ctx, dev->osubdev); nvrm_ioctl_destroy(ctx, ctx->cid, dev->odev); out_dev: nvrm_handle_free(ctx, dev->odev); close(dev->fd); out_open: nvrm_mthd_context_disable_device(ctx, ctx->cid, dev->gpu_id); out_enable: dev->open--; return 0; } void nvrm_device_close(struct nvrm_device *dev) { struct nvrm_context *ctx = dev->ctx; int idx = dev->idx; if (!dev->open) { fprintf(stderr, "nvrm: closing closed device %d\n", idx); abort(); } if (--dev->open) { return; } nvrm_ioctl_call(ctx, dev->osubdev, NVRM_MTHD_SUBDEVICE_UNK0146, 0, 0); nvrm_ioctl_destroy(ctx, dev->odev, dev->osubdev); nvrm_handle_free(ctx, dev->osubdev); nvrm_ioctl_destroy(ctx, ctx->cid, dev->odev); nvrm_handle_free(ctx, dev->odev); close(dev->fd); nvrm_mthd_context_disable_device(ctx, ctx->cid, dev->gpu_id); }