summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2015-08-20 14:54:05 +1000
committerBen Skeggs <bskeggs@redhat.com>2015-08-28 12:37:26 +1000
commitcf43fc0391a257fb17414d8b41746b9e16093578 (patch)
tree389b7f77db26a321fe0368262aa8888edcb55a5c
parenta1d7077da37dfe2c3f89d1445f5b78e63de5666c (diff)
lib: various tweaks
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--bin/nv_disp.c2
-rw-r--r--bin/nv_perfmon.c2
-rw-r--r--bin/nv_rd08.c2
-rw-r--r--bin/nv_rd16.c2
-rw-r--r--bin/nv_rd32.c2
-rw-r--r--bin/nv_rdfunc.h6
-rw-r--r--bin/nv_rf08.c2
-rw-r--r--bin/nv_rf16.c2
-rw-r--r--bin/nv_rf32.c2
-rw-r--r--bin/nv_ri08.c2
-rw-r--r--bin/nv_ri16.c2
-rw-r--r--bin/nv_ri32.c2
-rw-r--r--bin/nv_rs08.c2
-rw-r--r--bin/nv_rs16.c2
-rw-r--r--bin/nv_rs32.c2
-rw-r--r--bin/nv_rv08.c2
-rw-r--r--bin/nv_rv16.c2
-rw-r--r--bin/nv_rv32.c2
-rw-r--r--bin/nv_wf08.c2
-rw-r--r--bin/nv_wf16.c2
-rw-r--r--bin/nv_wf32.c2
-rw-r--r--bin/nv_wi08.c2
-rw-r--r--bin/nv_wi16.c2
-rw-r--r--bin/nv_wi32.c2
-rw-r--r--bin/nv_wr08.c2
-rw-r--r--bin/nv_wr16.c2
-rw-r--r--bin/nv_wr32.c2
-rw-r--r--bin/nv_wrfunc.h7
-rw-r--r--bin/nv_ws08.c2
-rw-r--r--bin/nv_ws16.c2
-rw-r--r--bin/nv_ws32.c2
-rw-r--r--bin/nv_wv08.c2
-rw-r--r--bin/nv_wv16.c2
-rw-r--r--bin/nv_wv32.c2
-rw-r--r--drm/nouveau/nvkm/engine/device/base.c2
-rw-r--r--lib/Makefile8
-rw-r--r--lib/bit.c28
-rw-r--r--lib/drm.c21
-rw-r--r--lib/include/nvif/list.h3
-rw-r--r--lib/include/nvif/os.h105
-rw-r--r--lib/main.c89
-rw-r--r--lib/null.c2
-rw-r--r--lib/work.c107
43 files changed, 271 insertions, 171 deletions
diff --git a/bin/nv_disp.c b/bin/nv_disp.c
index 9a6c481f..9141bed6 100644
--- a/bin/nv_disp.c
+++ b/bin/nv_disp.c
@@ -28,7 +28,7 @@ nv_disp(struct nvif_device *device, u16 mthd, u32 data)
}
}
-#define FMTADDR "0x%04lx"
+#define FMTADDR "0x%04llx"
#define FMTDATA "0x%08x"
#define NAME "nv_disp"
#define CAST u32
diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
index ddb05101..c04fd5e5 100644
--- a/bin/nv_perfmon.c
+++ b/bin/nv_perfmon.c
@@ -588,7 +588,7 @@ ui_main_redraw(struct ui_table *t)
set_field_userptr(f[0], item);
field_opts_on(f[0], O_VISIBLE | O_ACTIVE);
- snprintf(b, sizeof(b), "%10u %10u %6.2f %16"PRIu64,
+ snprintf(b, sizeof(b), "%10u %10u %6.2f %16llx",
item->clk, item->ctr,
(float)item->ctr * 100.0 / item->clk, item->incr);
set_field_buffer(f[1], 0, b);
diff --git a/bin/nv_rd08.c b/bin/nv_rd08.c
index f368951f..30196d41 100644
--- a/bin/nv_rd08.c
+++ b/bin/nv_rd08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%06lx"
+#define FMTADDR "0x%06llx"
#define FMTDATA "0x%02x"
#define NAME "nv_rd08"
#define CAST u8
diff --git a/bin/nv_rd16.c b/bin/nv_rd16.c
index 0b48a0b4..61079bcd 100644
--- a/bin/nv_rd16.c
+++ b/bin/nv_rd16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%06lx"
+#define FMTADDR "0x%06llx"
#define FMTDATA "0x%04x"
#define NAME "nv_rd16"
#define CAST u16
diff --git a/bin/nv_rd32.c b/bin/nv_rd32.c
index 88022a95..f0373952 100644
--- a/bin/nv_rd32.c
+++ b/bin/nv_rd32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%06lx"
+#define FMTADDR "0x%06llx"
#define FMTDATA "0x%08x"
#define NAME "nv_rd32"
#define CAST u32
diff --git a/bin/nv_rdfunc.h b/bin/nv_rdfunc.h
index 7af8cb37..4668bf49 100644
--- a/bin/nv_rdfunc.h
+++ b/bin/nv_rdfunc.h
@@ -70,10 +70,10 @@ main(int argc, char **argv)
return ret;
while (rstr && *rstr != '\0') {
- unsigned long cnt = 1;
- unsigned long reg;
+ u32 cnt = 1;
+ u64 reg;
- if ((reg = strtoul(rstr, &rstr, 0)) == ULONG_MAX)
+ if ((reg = strtoull(rstr, &rstr, 0)) == ULONG_MAX)
return 1;
if (*rstr == '/') {
diff --git a/bin/nv_rf08.c b/bin/nv_rf08.c
index 864b98ca..467851ed 100644
--- a/bin/nv_rf08.c
+++ b/bin/nv_rf08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%02x"
#define NAME "nv_rf08"
#define CAST u8
diff --git a/bin/nv_rf16.c b/bin/nv_rf16.c
index d40c6e20..adaab2a0 100644
--- a/bin/nv_rf16.c
+++ b/bin/nv_rf16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%04x"
#define NAME "nv_rf16"
#define CAST u16
diff --git a/bin/nv_rf32.c b/bin/nv_rf32.c
index c84c77b0..6a04a648 100644
--- a/bin/nv_rf32.c
+++ b/bin/nv_rf32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%08x"
#define NAME "nv_rf32"
#define CAST u32
diff --git a/bin/nv_ri08.c b/bin/nv_ri08.c
index 5cb4fe74..4bf670ee 100644
--- a/bin/nv_ri08.c
+++ b/bin/nv_ri08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%02x"
#define NAME "nv_ri08"
#define CAST u8
diff --git a/bin/nv_ri16.c b/bin/nv_ri16.c
index 81aa0489..e2407638 100644
--- a/bin/nv_ri16.c
+++ b/bin/nv_ri16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%04x"
#define NAME "nv_ri16"
#define CAST u16
diff --git a/bin/nv_ri32.c b/bin/nv_ri32.c
index 25a98f56..ca378c1f 100644
--- a/bin/nv_ri32.c
+++ b/bin/nv_ri32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%08x"
#define NAME "nv_ri32"
#define CAST u32
diff --git a/bin/nv_rs08.c b/bin/nv_rs08.c
index 63ad4f20..8d872ffa 100644
--- a/bin/nv_rs08.c
+++ b/bin/nv_rs08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%02x"
#define NAME "nv_rs08"
#define CAST u8
diff --git a/bin/nv_rs16.c b/bin/nv_rs16.c
index 148ee85c..79ce2748 100644
--- a/bin/nv_rs16.c
+++ b/bin/nv_rs16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%04x"
#define NAME "nv_rs16"
#define CAST u16
diff --git a/bin/nv_rs32.c b/bin/nv_rs32.c
index d29eb875..d4fc6380 100644
--- a/bin/nv_rs32.c
+++ b/bin/nv_rs32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%08x"
#define NAME "nv_rs32"
#define CAST u32
diff --git a/bin/nv_rv08.c b/bin/nv_rv08.c
index 92a5ffbf..b3ea27e6 100644
--- a/bin/nv_rv08.c
+++ b/bin/nv_rv08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%02x"
#define NAME "nv_rv08"
#define CAST u8
diff --git a/bin/nv_rv16.c b/bin/nv_rv16.c
index c39e02da..4b0186b5 100644
--- a/bin/nv_rv16.c
+++ b/bin/nv_rv16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%04x"
#define NAME "nv_rv16"
#define CAST u16
diff --git a/bin/nv_rv32.c b/bin/nv_rv32.c
index f8320bea..02183dd2 100644
--- a/bin/nv_rv32.c
+++ b/bin/nv_rv32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%08x"
#define NAME "nv_rv32"
#define CAST u32
diff --git a/bin/nv_wf08.c b/bin/nv_wf08.c
index f05a7e7c..82378e9f 100644
--- a/bin/nv_wf08.c
+++ b/bin/nv_wf08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%02x"
#define NAME "nv_wf08"
#define CAST u8
diff --git a/bin/nv_wf16.c b/bin/nv_wf16.c
index c1b747cc..af30974d 100644
--- a/bin/nv_wf16.c
+++ b/bin/nv_wf16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%04x"
#define NAME "nv_wf16"
#define CAST u16
diff --git a/bin/nv_wf32.c b/bin/nv_wf32.c
index 88140064..892ff3f7 100644
--- a/bin/nv_wf32.c
+++ b/bin/nv_wf32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%08x"
#define NAME "nv_wf32"
#define CAST u32
diff --git a/bin/nv_wi08.c b/bin/nv_wi08.c
index ebd5fb53..358b94bc 100644
--- a/bin/nv_wi08.c
+++ b/bin/nv_wi08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%02x"
#define NAME "nv_wi08"
#define CAST u8
diff --git a/bin/nv_wi16.c b/bin/nv_wi16.c
index dc815e7e..217afee9 100644
--- a/bin/nv_wi16.c
+++ b/bin/nv_wi16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%04x"
#define NAME "nv_wi16"
#define CAST u16
diff --git a/bin/nv_wi32.c b/bin/nv_wi32.c
index a2420fac..b9bba5b2 100644
--- a/bin/nv_wi32.c
+++ b/bin/nv_wi32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%08x"
#define NAME "nv_wi32"
#define CAST u32
diff --git a/bin/nv_wr08.c b/bin/nv_wr08.c
index c81b69a7..a0be3ee6 100644
--- a/bin/nv_wr08.c
+++ b/bin/nv_wr08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%06lx"
+#define FMTADDR "0x%06llx"
#define FMTDATA "0x%02x"
#define NAME "nv_wr08"
#define CAST u8
diff --git a/bin/nv_wr16.c b/bin/nv_wr16.c
index 004b198a..122bc82c 100644
--- a/bin/nv_wr16.c
+++ b/bin/nv_wr16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%06lx"
+#define FMTADDR "0x%06llx"
#define FMTDATA "0x%04x"
#define NAME "nv_wr16"
#define CAST u16
diff --git a/bin/nv_wr32.c b/bin/nv_wr32.c
index 2b8b60f3..910c9282 100644
--- a/bin/nv_wr32.c
+++ b/bin/nv_wr32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%06lx"
+#define FMTADDR "0x%06llx"
#define FMTDATA "0x%08x"
#define NAME "nv_wr32"
#define CAST u32
diff --git a/bin/nv_wrfunc.h b/bin/nv_wrfunc.h
index 31855e1a..fb39c460 100644
--- a/bin/nv_wrfunc.h
+++ b/bin/nv_wrfunc.h
@@ -64,11 +64,10 @@ MAIN(int argc, char **argv)
return ret;
while (rstr && *rstr != '\0') {
- unsigned long cnt = 1;
- unsigned long reg;
- unsigned long val;
+ u32 cnt = 1, val;
+ u64 reg;
- if ((reg = strtoul(rstr, &rstr, 0)) == ULONG_MAX)
+ if ((reg = strtoull(rstr, &rstr, 0)) == ULONG_MAX)
return 1;
if (*rstr == '/') {
diff --git a/bin/nv_ws08.c b/bin/nv_ws08.c
index 3a301d3e..d7d9a597 100644
--- a/bin/nv_ws08.c
+++ b/bin/nv_ws08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%02x"
#define NAME "nv_rs08"
#define CAST u8
diff --git a/bin/nv_ws16.c b/bin/nv_ws16.c
index d53d1f6c..83275736 100644
--- a/bin/nv_ws16.c
+++ b/bin/nv_ws16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%04x"
#define NAME "nv_ws16"
#define CAST u16
diff --git a/bin/nv_ws32.c b/bin/nv_ws32.c
index 26103e06..ca108eb0 100644
--- a/bin/nv_ws32.c
+++ b/bin/nv_ws32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%08x"
#define NAME "nv_ws32"
#define CAST u32
diff --git a/bin/nv_wv08.c b/bin/nv_wv08.c
index 7c032b4f..1556d8a7 100644
--- a/bin/nv_wv08.c
+++ b/bin/nv_wv08.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%02x"
#define NAME "nv_wv08"
#define CAST u8
diff --git a/bin/nv_wv16.c b/bin/nv_wv16.c
index 85333065..0d5333e8 100644
--- a/bin/nv_wv16.c
+++ b/bin/nv_wv16.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%04x"
#define NAME "nv_wv16"
#define CAST u16
diff --git a/bin/nv_wv32.c b/bin/nv_wv32.c
index e414246c..235c666a 100644
--- a/bin/nv_wv32.c
+++ b/bin/nv_wv32.c
@@ -1,4 +1,4 @@
-#define FMTADDR "0x%08lx"
+#define FMTADDR "0x%08llx"
#define FMTDATA "0x%08x"
#define NAME "nv_wv32"
#define CAST u32
diff --git a/drm/nouveau/nvkm/engine/device/base.c b/drm/nouveau/nvkm/engine/device/base.c
index 63d8e52f..0f6ce374 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -727,7 +727,7 @@ nvkm_device_create_(void *dev, enum nv_bus_type type, u64 name,
nv_subdev(device)->debug = nvkm_dbgopt(device->dbgopt, "DEVICE");
nv_engine(device)->sclass = nvkm_device_sclass;
- list_add(&device->head, &nv_devices);
+ list_add_tail(&device->head, &nv_devices);
ret = nvkm_event_init(&nvkm_device_event_func, 1, 1, &device->event);
done:
diff --git a/lib/Makefile b/lib/Makefile
index 82706f87..ca3be266 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,4 +1,4 @@
-LIBNVIF_CC := $(CFLAGS) -I$(drm) -fPIC
+LIBNVIF_CC := $(CFLAGS) -I$(drm) -fPIC -Wframe-larger-than=1024
LIBNVIF_LD := $(LDFLAGS) -shared -lpciaccess -lpthread -ldrm
src := $(drm)
@@ -26,10 +26,12 @@ fucs := $(drm)/nvkm/engine/ce/fuc/gt215.fuc3.h \
$(drm)/nvkm/engine/sec/fuc/g98.fuc0s.h
drms := $(addprefix $(lib)/, $(nvif-y)) \
$(addprefix $(lib)/, $(nvkm-y))
-srcs := $(lib)/drm.o \
+srcs := $(lib)/bit.o \
+ $(lib)/drm.o \
$(lib)/intr.o \
$(lib)/main.o \
- $(lib)/null.o
+ $(lib)/null.o \
+ $(lib)/work.o
outp := $(lib)/libnvif.so
deps-fuc := $(fucs:$(drm)/%.h=$(lib)/%.d)
diff --git a/lib/bit.c b/lib/bit.c
new file mode 100644
index 00000000..520aecd6
--- /dev/null
+++ b/lib/bit.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+#include "priv.h"
+
+const struct i2c_algorithm
+i2c_bit_algo = {
+};
diff --git a/lib/drm.c b/lib/drm.c
index ac68e1f8..bb96a7f2 100644
--- a/lib/drm.c
+++ b/lib/drm.c
@@ -170,8 +170,8 @@ drm_client_init(const char *name, u64 device, const char *cfg,
int ret, minor;
char path[128];
- if (ret = -ENOMEM, !(drm = *ppriv = malloc(sizeof(*drm))))
- goto fail;
+ if (!(drm = *ppriv = calloc(1, sizeof(*drm))))
+ return -ENOMEM;
for (minor = DRM_RENDER_MIN; minor <= DRM_RENDER_MAX; minor++) {
snprintf(path, sizeof(path), "/dev/dri/renderD%d", minor);
@@ -181,27 +181,24 @@ drm_client_init(const char *name, u64 device, const char *cfg,
continue;
if (!strcmp(ver->name, "nouveau"))
break;
- free(ver);
+ drmFreeVersion(ver);
}
- if (ret = -ENODEV, minor > DRM_RENDER_MAX)
- goto fail;
+ if (minor > DRM_RENDER_MAX)
+ return -ENODEV;
drm->version = (ver->version_major << 24) |
(ver->version_minor << 8) |
ver->version_patchlevel;
- free(ver);
- if (ret = -ENOSYS, drm->version < 0x01000200)
- goto fail;
+ drmFreeVersion(ver);
+ if (drm->version < 0x01000200)
+ return -ENOSYS;
if ((ret = pthread_create(&drm->event, NULL, drm_client_event, drm)))
- goto fail;
+ return ret;
drm->done = true;
return 0;
-fail:
- drm_client_fini(drm);
- return ret;
}
const struct nvif_driver
diff --git a/lib/include/nvif/list.h b/lib/include/nvif/list.h
index f273376e..2bed23c2 100644
--- a/lib/include/nvif/list.h
+++ b/lib/include/nvif/list.h
@@ -252,7 +252,8 @@ list_empty(struct list_head *head)
*/
#ifndef container_of
#define container_of(ptr, type, member) ({ \
- (type *)((char *)(ptr) - (char *) &((type *)0)->member); \
+ typeof(((type *)0)->member) *__mptr = (ptr); \
+ (type *)((char *)(__mptr) - (char *) &((type *)0)->member); \
})
#endif
diff --git a/lib/include/nvif/os.h b/lib/include/nvif/os.h
index 71a369ec..bd958403 100644
--- a/lib/include/nvif/os.h
+++ b/lib/include/nvif/os.h
@@ -34,22 +34,22 @@
#include <limits.h>
#include <ctype.h>
-typedef uint64_t u64;
+__extension__ typedef unsigned long long u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
-typedef int64_t s64;
+__extension__ typedef long long s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
#ifndef _ASM_GENERIC_INT_LL64_H
-typedef uint64_t __u64;
+__extension__ typedef unsigned long long __u64;
typedef uint32_t __u32;
typedef uint16_t __u16;
typedef uint8_t __u8;
-typedef int64_t __s64;
+__extension__ typedef long long __s64;
typedef int32_t __s32;
typedef int16_t __s16;
typedef int8_t __s8;
@@ -266,28 +266,28 @@ typedef struct atomic {
/******************************************************************************
* ktime
*****************************************************************************/
-#include <sys/time.h>
+#include <time.h>
-typedef struct timeval ktime_t;
+typedef struct timespec ktime_t;
static inline ktime_t
ktime_get(void)
{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return tv;
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return ts;
}
static inline s64
-ktime_to_us(ktime_t kt)
+ktime_to_ns(ktime_t kt)
{
- return kt.tv_sec * 1000000 + kt.tv_usec;
+ return (s64)kt.tv_sec * 1000000000 + kt.tv_nsec;
}
static inline s64
-ktime_to_ns(ktime_t kt)
+ktime_to_us(ktime_t kt)
{
- return ktime_to_us(kt) * 1000;
+ return ktime_to_ns(kt) / 1000;
}
/******************************************************************************
@@ -424,17 +424,19 @@ get_num_physpages(void)
static inline void
nvos_backtrace(void)
{
- void *buffer[512];
+ void **buffer;
char **sinfo;
int ninfo, i;
- ninfo = backtrace(buffer, sizeof(buffer));
+ buffer = malloc(sizeof(*buffer) * 512);
+ ninfo = backtrace(buffer, 512);
sinfo = backtrace_symbols(buffer, ninfo);
if (sinfo) {
for (i = 0; i < ninfo; i++)
printf("%s\n", sinfo[i]);
free(sinfo);
}
+ free(buffer);
}
#define BUG() do { \
@@ -497,7 +499,9 @@ typedef struct spinlock_t {
#define DEFINE_SPINLOCK(a) spinlock_t a = { .lock = PTHREAD_MUTEX_INITIALIZER }
-#define spin_lock_init(a) pthread_mutex_init(&(a)->lock, NULL)
+#define spin_lock_init(a) do { \
+ (a)->lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; \
+} while(0)
#define spin_lock(a) pthread_mutex_lock(&(a)->lock)
#define spin_unlock(a) pthread_mutex_unlock(&(a)->lock)
#define spin_lock_irqsave(a,b) do { (b) = 1; spin_lock((a)); } while (0)
@@ -939,7 +943,7 @@ request_firmware(const struct firmware **pfw, const char *name,
return 0;
}
free(fw);
- return errno;
+ return -EINVAL;
}
static inline void
@@ -952,60 +956,20 @@ release_firmware(const struct firmware *fw)
/******************************************************************************
* workqueues
*****************************************************************************/
-struct work_struct;
-
-typedef void (*work_func_t)(struct work_struct *);
-
struct work_struct {
- work_func_t func;
- pthread_mutex_t mutex;
- pthread_t thread;
- bool pending;
+ union {
+ void (*func)(struct work_struct *);
+ void (*exec)(void *);
+ };
+ struct nvos_work *nvos;
};
-static inline void
-INIT_WORK(struct work_struct *work, work_func_t func)
-{
- pthread_mutex_init(&work->mutex, NULL);
- work->func = func;
- work->pending = false;
-}
+#define INIT_WORK(a,b) ((a)->func = (b), (a)->nvos = NULL)
+#define schedule_work(a) BUG_ON(!nvos_work_init((a)->exec, (a), &(a)->nvos))
+#define flush_work(a) nvos_work_fini(&(a)->nvos)
-static inline void *
-os_work(void *arg)
-{
- struct work_struct *work = arg;
- work_func_t func;
- do {
- pthread_mutex_lock(&work->mutex);
- if (work->pending) {
- work->pending = false;
- func = work->func;
- } else {
- func = NULL;
- }
- pthread_mutex_unlock(&work->mutex);
- if (func)
- func(work);
- } while (func);
- return NULL;
-}
-
-static inline void
-schedule_work(struct work_struct *work)
-{
- pthread_mutex_lock(&work->mutex);
- if (!work->pending) {
- work->pending = true;
- assert(!pthread_create(&work->thread, NULL, os_work, work));
- }
- pthread_mutex_unlock(&work->mutex);
-}
-
-static inline void
-flush_work(struct work_struct *work)
-{
-}
+bool nvos_work_init(void (*)(void *), void *, struct nvos_work **);
+void nvos_work_fini(struct nvos_work **);
/******************************************************************************
* waitqueues
@@ -1140,10 +1104,6 @@ i2c_transfer(struct i2c_adapter *a, struct i2c_msg *m, int num)
* i2c bit-bang
*****************************************************************************/
-static struct i2c_algorithm
-i2c_bit_algo = {
-};
-
struct i2c_algo_bit_data {
int udelay;
unsigned long timeout;
@@ -1159,10 +1119,11 @@ struct i2c_algo_bit_data {
static inline int
i2c_bit_add_bus(struct i2c_adapter *a)
{
- (void)i2c_bit_algo;
return 0;
}
+extern const struct i2c_algorithm i2c_bit_algo;
+
/******************************************************************************
* delay
*****************************************************************************/
diff --git a/lib/main.c b/lib/main.c
index ac03c968..6201c3ca 100644
--- a/lib/main.c
+++ b/lib/main.c
@@ -47,6 +47,7 @@ static int os_client_nr = 0;
/******************************************************************************
* horrific stuff to implement linux's ioremap interface on top of pciaccess
*****************************************************************************/
+static DEFINE_MUTEX(os_ioremap_mutex);
static struct os_ioremap_info {
struct pci_device *pdev;
int refs;
@@ -56,54 +57,54 @@ static struct os_ioremap_info {
} os_ioremap[32];
void __iomem *
-nvos_ioremap(u64 addr, u64 size)
+nvos_ioremap_bar(struct pci_device *pdev, int bar, u64 addr)
{
- struct pci_device *pdev = NULL;
- struct os_ioremap_info *info;
- struct os_device *odev;
- u64 m_page = addr & 0xfff;
- u64 m_addr = addr & ~0xfff;
- u64 m_size = (size + 0xfff) & ~0xfff;
+ u64 base = pdev->regions[bar].base_addr;
+ u64 size = pdev->regions[bar].size;
+ u64 offset = addr - base;
+ void __iomem *ptr = NULL;
int i;
- list_for_each_entry(odev, &os_device_list, head) {
- for (i = 0; i < 6; i++) {
- pdev = odev->base.pdev->pdev;
- if (m_addr >= pdev->regions[i].base_addr &&
- m_addr + m_size <= pdev->regions[i].base_addr +
- pdev->regions[i].size)
- break;
- pdev = NULL;
+ mutex_lock(&os_ioremap_mutex);
+ for (i = 0; !ptr && i < ARRAY_SIZE(os_ioremap); i++) {
+ if (os_ioremap[i].refs && os_ioremap[i].addr == base) {
+ os_ioremap[i].refs++;
+ ptr = os_ioremap[i].ptr + offset;
}
- if (pdev)
- break;
}
- for (i = 0, info = NULL; pdev && i < ARRAY_SIZE(os_ioremap); i++) {
- if (os_ioremap[i].refs) {
- if (os_ioremap[i].addr != m_addr ||
- os_ioremap[i].size != m_size)
- continue;
- } else {
- info = &os_ioremap[i];
- continue;
+ for (i = 0; !ptr && i < ARRAY_SIZE(os_ioremap); i++) {
+ if (!os_ioremap[i].refs &&
+ !pci_device_map_range(pdev, base, size,
+ PCI_DEV_MAP_FLAG_WRITABLE,
+ &os_ioremap[i].ptr)) {
+ os_ioremap[i].pdev = pdev;
+ os_ioremap[i].refs = 1;
+ os_ioremap[i].addr = base;
+ os_ioremap[i].size = size;
+ ptr = os_ioremap[i].ptr + offset;
}
-
- os_ioremap[i].refs++;
- return os_ioremap[i].ptr + m_page;
}
+ mutex_unlock(&os_ioremap_mutex);
+
+ return ptr;
+}
- if (info) {
- if (pci_device_map_range(pdev, m_addr, m_size,
- PCI_DEV_MAP_FLAG_WRITABLE,
- &info->ptr))
- return NULL;
-
- info->pdev = pdev;
- info->refs = 1;
- info->addr = m_addr;
- info->size = m_size;
- return info->ptr + m_page;
+void __iomem *
+nvos_ioremap(u64 addr, u64 size)
+{
+ struct os_device *odev;
+ int i;
+
+ list_for_each_entry(odev, &os_device_list, head) {
+ struct pci_device *pdev = odev->base.pdev->pdev;
+ for (i = 0; i < ARRAY_SIZE(pdev->regions); i++) {
+ if (addr >= pdev->regions[i].base_addr &&
+ addr + size <= pdev->regions[i].base_addr +
+ pdev->regions[i].size) {
+ return nvos_ioremap_bar(pdev, i, addr);
+ }
+ }
}
return NULL;
@@ -114,17 +115,20 @@ nvos_iounmap(void __iomem *ptr)
{
int i;
+ mutex_lock(&os_ioremap_mutex);
for (i = 0; ptr && i < ARRAY_SIZE(os_ioremap); i++) {
if (os_ioremap[i].refs &&
ptr >= os_ioremap[i].ptr &&
ptr < os_ioremap[i].ptr + os_ioremap[i].size) {
if (!--os_ioremap[i].refs) {
- pci_device_unmap_range(os_ioremap[i].pdev, ptr,
+ pci_device_unmap_range(os_ioremap[i].pdev,
+ os_ioremap[i].ptr,
os_ioremap[i].size);
}
break;
}
}
+ mutex_unlock(&os_ioremap_mutex);
}
/******************************************************************************
@@ -152,7 +156,7 @@ os_init_device(struct pci_device *pdev, u64 handle, const char *cfg, const char
return -EEXIST;
}
- ldev = malloc(sizeof(*ldev));
+ ldev = calloc(1, sizeof(*ldev));
ldev->pdev = pdev;
ldev->device = pdev->dev;
ldev->subsystem_vendor = pdev->subvendor_id;
@@ -163,6 +167,7 @@ os_init_device(struct pci_device *pdev, u64 handle, const char *cfg, const char
cfg, dbg, &odev);
if (ret) {
fprintf(stderr, "failed to create device, %d\n", ret);
+ free(name);
return ret;
}
@@ -196,7 +201,7 @@ os_init(const char *cfg, const char *dbg, bool init)
(pdev->dev << 8) | pdev->func;
if (!init) {
- printf("%d: 0x%010"PRIx64" PCI:%04x:%02x:%02x:%02x "
+ printf("%d: 0x%010llx PCI:%04x:%02x:%02x:%02x "
"(%04x:%04x)\n", n++, handle, pdev->domain,
pdev->bus, pdev->dev, pdev->func,
pdev->vendor_id, pdev->device_id);
diff --git a/lib/null.c b/lib/null.c
index 45f613e8..8f35b944 100644
--- a/lib/null.c
+++ b/lib/null.c
@@ -105,7 +105,7 @@ static int
null_client_init(const char *name, u64 device, const char *cfg,
const char *dbg, void **ppriv)
{
- struct nvkm_client *client;
+ struct nvkm_client *client = NULL;
int ret;
mutex_lock(&null_mutex);
diff --git a/lib/work.c b/lib/work.c
new file mode 100644
index 00000000..3311023e
--- /dev/null
+++ b/lib/work.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2015 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+#include "priv.h"
+
+struct nvos_work {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ pthread_t thread;
+ bool done;
+
+ void (*func)(void *);
+ void *priv;
+};
+
+static void *
+nvos_work(void *data)
+{
+ struct nvos_work *work = data;
+
+ do {
+ pthread_mutex_lock(&work->mutex);
+ while (!work->priv && !work->done)
+ pthread_cond_wait(&work->cond, &work->mutex);
+ if (work->priv) {
+ work->func(work->priv);
+ work->priv = NULL;
+ }
+ pthread_mutex_unlock(&work->mutex);
+ } while (!work->done);
+
+ return NULL;
+}
+
+void
+nvos_work_fini(struct nvos_work **pwork)
+{
+ struct nvos_work *work = *pwork;
+ if (work) {
+ pthread_mutex_lock(&work->mutex);
+ work->done = true;
+ pthread_cond_signal(&work->cond);
+ pthread_mutex_unlock(&work->mutex);
+
+ pthread_join(work->thread, NULL);
+ pthread_cond_destroy(&work->cond);
+ pthread_mutex_destroy(&work->mutex);
+ free(*pwork);
+ *pwork = NULL;
+ }
+}
+
+bool
+nvos_work_init(void (*func)(void *), void *priv, struct nvos_work **pwork)
+{
+ struct nvos_work *work = *pwork;
+
+ if (unlikely(work == NULL)) {
+ if (!(work = calloc(1, sizeof(*work))))
+ return false;
+ work->func = func;
+ work->priv = NULL;
+ work->done = false;
+
+ if (pthread_mutex_init(&work->mutex, NULL))
+ goto fail_mutex;
+ if (pthread_cond_init(&work->cond, NULL))
+ goto fail_cond;
+ if (pthread_create(&work->thread, NULL, nvos_work, work))
+ goto fail_thread;
+ *pwork = work;
+ }
+
+ pthread_mutex_lock(&work->mutex);
+ work->priv = priv;
+ pthread_cond_signal(&work->cond);
+ pthread_mutex_unlock(&work->mutex);
+ return true;
+
+fail_thread:
+ pthread_cond_destroy(&work->cond);
+fail_cond:
+ pthread_mutex_destroy(&work->mutex);
+fail_mutex:
+ free(work);
+ return false;
+}