diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 14:54:05 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 12:37:26 +1000 |
commit | cf43fc0391a257fb17414d8b41746b9e16093578 (patch) | |
tree | 389b7f77db26a321fe0368262aa8888edcb55a5c | |
parent | a1d7077da37dfe2c3f89d1445f5b78e63de5666c (diff) |
lib: various tweaks
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
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 = { +}; @@ -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 *****************************************************************************/ @@ -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); @@ -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; +} |