Release 4.8 drivers/gpu/drm/drm_context.c
/*
* Legacy: Generic DRM Contexts
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Author: Rickard E. (Rik) Faith <faith@valinux.com>
* Author: Gareth Hughes <gareth@valinux.com>
*
* 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 (including the next
* paragraph) 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
*/
#include <drm/drmP.h>
#include "drm_legacy.h"
struct drm_ctx_list {
struct list_head head;
drm_context_t handle;
struct drm_file *tag;
};
/******************************************************************/
/** \name Context bitmap support */
/*@{*/
/**
* Free a handle from the context bitmap.
*
* \param dev DRM device.
* \param ctx_handle context handle.
*
* Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
* in drm_device::ctx_idr, while holding the drm_device::struct_mutex
* lock.
*/
void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
{
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return;
mutex_lock(&dev->struct_mutex);
idr_remove(&dev->ctx_idr, ctx_handle);
mutex_unlock(&dev->struct_mutex);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
peter antoine | peter antoine | 18 | 31.58% | 1 | 14.29% |
pre-git | pre-git | 15 | 26.32% | 1 | 14.29% |
linus torvalds | linus torvalds | 12 | 21.05% | 1 | 14.29% |
dave airlie | dave airlie | 11 | 19.30% | 3 | 42.86% |
david herrmann | david herrmann | 1 | 1.75% | 1 | 14.29% |
| Total | 57 | 100.00% | 7 | 100.00% |
/**
* Context bitmap allocation.
*
* \param dev DRM device.
* \return (non-negative) context handle on success or a negative number on failure.
*
* Allocate a new idr from drm_device::ctx_idr while holding the
* drm_device::struct_mutex lock.
*/
static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
{
int ret;
mutex_lock(&dev->struct_mutex);
ret = idr_alloc(&dev->ctx_idr, NULL, DRM_RESERVED_CONTEXTS, 0,
GFP_KERNEL);
mutex_unlock(&dev->struct_mutex);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave airlie | dave airlie | 16 | 31.37% | 4 | 40.00% |
pre-git | pre-git | 14 | 27.45% | 1 | 10.00% |
linus torvalds | linus torvalds | 13 | 25.49% | 2 | 20.00% |
tejun heo | tejun heo | 4 | 7.84% | 1 | 10.00% |
ville syrjala | ville syrjala | 3 | 5.88% | 1 | 10.00% |
david herrmann | david herrmann | 1 | 1.96% | 1 | 10.00% |
| Total | 51 | 100.00% | 10 | 100.00% |
/**
* Context bitmap initialization.
*
* \param dev DRM device.
*
* Initialise the drm_device::ctx_idr
*/
void drm_legacy_ctxbitmap_init(struct drm_device * dev)
{
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return;
idr_init(&dev->ctx_idr);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
peter antoine | peter antoine | 17 | 47.22% | 1 | 16.67% |
linus torvalds | linus torvalds | 12 | 33.33% | 1 | 16.67% |
dave airlie | dave airlie | 4 | 11.11% | 2 | 33.33% |
daniel vetter | daniel vetter | 2 | 5.56% | 1 | 16.67% |
david herrmann | david herrmann | 1 | 2.78% | 1 | 16.67% |
| Total | 36 | 100.00% | 6 | 100.00% |
/**
* Context bitmap cleanup.
*
* \param dev DRM device.
*
* Free all idr members using drm_ctx_sarea_free helper function
* while holding the drm_device::struct_mutex lock.
*/
void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
{
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return;
mutex_lock(&dev->struct_mutex);
idr_destroy(&dev->ctx_idr);
mutex_unlock(&dev->struct_mutex);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
peter antoine | peter antoine | 18 | 34.62% | 1 | 12.50% |
linus torvalds | linus torvalds | 14 | 26.92% | 1 | 12.50% |
pre-git | pre-git | 10 | 19.23% | 1 | 12.50% |
dave airlie | dave airlie | 8 | 15.38% | 3 | 37.50% |
david herrmann | david herrmann | 1 | 1.92% | 1 | 12.50% |
tejun heo | tejun heo | 1 | 1.92% | 1 | 12.50% |
| Total | 52 | 100.00% | 8 | 100.00% |
/**
* drm_ctxbitmap_flush() - Flush all contexts owned by a file
* @dev: DRM device to operate on
* @file: Open file to flush contexts for
*
* This iterates over all contexts on @dev and drops them if they're owned by
* @file. Note that after this call returns, new contexts might be added if
* the file is still alive.
*/
void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
{
struct drm_ctx_list *pos, *tmp;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return;
mutex_lock(&dev->ctxlist_mutex);
list_for_each_entry_safe(pos, tmp, &dev->ctxlist, head) {
if (pos->tag == file &&
pos->handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev, pos->handle);
drm_legacy_ctxbitmap_free(dev, pos->handle);
list_del(&pos->head);
kfree(pos);
}
}
mutex_unlock(&dev->ctxlist_mutex);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david herrmann | david herrmann | 110 | 85.94% | 2 | 66.67% |
peter antoine | peter antoine | 18 | 14.06% | 1 | 33.33% |
| Total | 128 | 100.00% | 3 | 100.00% |
/*@}*/
/******************************************************************/
/** \name Per Context SAREA Support */
/*@{*/
/**
* Get per-context SAREA.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_priv_map structure.
* \return zero on success or a negative number on failure.
*
* Gets the map from drm_device::ctx_idr with the handle specified and
* returns its handle.
*/
int drm_legacy_getsareactx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx_priv_map *request = data;
struct drm_local_map *map;
struct drm_map_list *_entry;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
mutex_lock(&dev->struct_mutex);
map = idr_find(&dev->ctx_idr, request->ctx_id);
if (!map) {
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
request->handle = NULL;
list_for_each_entry(_entry, &dev->maplist, head) {
if (_entry->map == map) {
request->handle =
(void *)(unsigned long)_entry->user_token;
break;
}
}
mutex_unlock(&dev->struct_mutex);
if (request->handle == NULL)
return -EINVAL;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave airlie | dave airlie | 72 | 43.90% | 9 | 47.37% |
linus torvalds | linus torvalds | 35 | 21.34% | 2 | 10.53% |
peter antoine | peter antoine | 21 | 12.80% | 1 | 5.26% |
eric anholt | eric anholt | 14 | 8.54% | 2 | 10.53% |
pre-git | pre-git | 11 | 6.71% | 1 | 5.26% |
ilija hadzic | ilija hadzic | 8 | 4.88% | 1 | 5.26% |
al viro | al viro | 1 | 0.61% | 1 | 5.26% |
david herrmann | david herrmann | 1 | 0.61% | 1 | 5.26% |
benjamin herrenschmidt | benjamin herrenschmidt | 1 | 0.61% | 1 | 5.26% |
| Total | 164 | 100.00% | 19 | 100.00% |
/**
* Set per-context SAREA.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_priv_map structure.
* \return zero on success or a negative number on failure.
*
* Searches the mapping specified in \p arg and update the entry in
* drm_device::ctx_idr with it.
*/
int drm_legacy_setsareactx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx_priv_map *request = data;
struct drm_local_map *map = NULL;
struct drm_map_list *r_list = NULL;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
mutex_lock(&dev->struct_mutex);
list_for_each_entry(r_list, &dev->maplist, head) {
if (r_list->map
&& r_list->user_token == (unsigned long) request->handle)
goto found;
}
bad:
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
found:
map = r_list->map;
if (!map)
goto bad;
if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id)))
goto bad;
mutex_unlock(&dev->struct_mutex);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 48 | 29.45% | 4 | 22.22% |
pre-git | pre-git | 47 | 28.83% | 1 | 5.56% |
dave airlie | dave airlie | 32 | 19.63% | 8 | 44.44% |
peter antoine | peter antoine | 21 | 12.88% | 1 | 5.56% |
eric anholt | eric anholt | 13 | 7.98% | 2 | 11.11% |
david herrmann | david herrmann | 1 | 0.61% | 1 | 5.56% |
benjamin herrenschmidt | benjamin herrenschmidt | 1 | 0.61% | 1 | 5.56% |
| Total | 163 | 100.00% | 18 | 100.00% |
/*@}*/
/******************************************************************/
/** \name The actual DRM context handling routines */
/*@{*/
/**
* Switch context.
*
* \param dev DRM device.
* \param old old context handle.
* \param new new context handle.
* \return zero on success or a negative number on failure.
*
* Attempt to set drm_device::context_flag.
*/
static int drm_context_switch(struct drm_device * dev, int old, int new)
{
if (test_and_set_bit(0, &dev->context_flag)) {
DRM_ERROR("Reentering -- FIXME\n");
return -EBUSY;
}
DRM_DEBUG("Context switch from %d to %d\n", old, new);
if (new == dev->last_context) {
clear_bit(0, &dev->context_flag);
return 0;
}
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 56 | 74.67% | 2 | 33.33% |
pre-git | pre-git | 15 | 20.00% | 1 | 16.67% |
dave airlie | dave airlie | 4 | 5.33% | 3 | 50.00% |
| Total | 75 | 100.00% | 6 | 100.00% |
/**
* Complete context switch.
*
* \param dev DRM device.
* \param new new context handle.
* \return zero on success or a negative number on failure.
*
* Updates drm_device::last_context and drm_device::last_switch. Verifies the
* hardware lock is held, clears the drm_device::context_flag and wakes up
* drm_device::context_wait.
*/
static int drm_context_switch_complete(struct drm_device *dev,
struct drm_file *file_priv, int new)
{
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock)) {
DRM_ERROR("Lock isn't held after context switch\n");
}
/* If a context switch is ever initiated
when the kernel holds the lock, release
that lock here. */
clear_bit(0, &dev->context_flag);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 32 | 50.79% | 1 | 14.29% |
pre-git | pre-git | 18 | 28.57% | 1 | 14.29% |
dave airlie | dave airlie | 13 | 20.63% | 5 | 71.43% |
| Total | 63 | 100.00% | 7 | 100.00% |
/**
* Reserve contexts.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_res structure.
* \return zero on success or a negative number on failure.
*/
int drm_legacy_resctx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx_res *res = data;
struct drm_ctx ctx;
int i;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
if (res->count >= DRM_RESERVED_CONTEXTS) {
memset(&ctx, 0, sizeof(ctx));
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
ctx.handle = i;
if (copy_to_user(&res->contexts[i], &ctx, sizeof(ctx)))
return -EFAULT;
}
}
res->count = DRM_RESERVED_CONTEXTS;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 61 | 46.21% | 1 | 11.11% |
pre-git | pre-git | 27 | 20.45% | 1 | 11.11% |
peter antoine | peter antoine | 21 | 15.91% | 1 | 11.11% |
eric anholt | eric anholt | 13 | 9.85% | 2 | 22.22% |
dave airlie | dave airlie | 6 | 4.55% | 2 | 22.22% |
al viro | al viro | 3 | 2.27% | 1 | 11.11% |
david herrmann | david herrmann | 1 | 0.76% | 1 | 11.11% |
| Total | 132 | 100.00% | 9 | 100.00% |
/**
* Add context.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Get a new handle for the context and copy to userspace.
*/
int drm_legacy_addctx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx_list *ctx_entry;
struct drm_ctx *ctx = data;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
ctx->handle = drm_legacy_ctxbitmap_next(dev);
if (ctx->handle == DRM_KERNEL_CONTEXT) {
/* Skip kernel's context and get a new one. */
ctx->handle = drm_legacy_ctxbitmap_next(dev);
}
DRM_DEBUG("%d\n", ctx->handle);
if (ctx->handle == -1) {
DRM_DEBUG("Not enough free contexts.\n");
/* Should this return -EBUSY instead? */
return -ENOMEM;
}
ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL);
if (!ctx_entry) {
DRM_DEBUG("out of memory\n");
return -ENOMEM;
}
INIT_LIST_HEAD(&ctx_entry->head);
ctx_entry->handle = ctx->handle;
ctx_entry->tag = file_priv;
mutex_lock(&dev->ctxlist_mutex);
list_add(&ctx_entry->head, &dev->ctxlist);
mutex_unlock(&dev->ctxlist_mutex);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave airlie | dave airlie | 83 | 42.78% | 5 | 41.67% |
linus torvalds | linus torvalds | 65 | 33.51% | 1 | 8.33% |
peter antoine | peter antoine | 21 | 10.82% | 1 | 8.33% |
eric anholt | eric anholt | 19 | 9.79% | 3 | 25.00% |
al viro | al viro | 3 | 1.55% | 1 | 8.33% |
david herrmann | david herrmann | 3 | 1.55% | 1 | 8.33% |
| Total | 194 | 100.00% | 12 | 100.00% |
/**
* Get context.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*/
int drm_legacy_getctx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
/* This is 0, because we don't handle any context flags */
ctx->flags = 0;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 21 | 36.84% | 1 | 14.29% |
peter antoine | peter antoine | 21 | 36.84% | 1 | 14.29% |
eric anholt | eric anholt | 11 | 19.30% | 2 | 28.57% |
dave airlie | dave airlie | 2 | 3.51% | 1 | 14.29% |
david herrmann | david herrmann | 1 | 1.75% | 1 | 14.29% |
al viro | al viro | 1 | 1.75% | 1 | 14.29% |
| Total | 57 | 100.00% | 7 | 100.00% |
/**
* Switch context.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Calls context_switch().
*/
int drm_legacy_switchctx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
DRM_DEBUG("%d\n", ctx->handle);
return drm_context_switch(dev, dev->last_context, ctx->handle);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 32 | 45.71% | 1 | 12.50% |
peter antoine | peter antoine | 21 | 30.00% | 1 | 12.50% |
eric anholt | eric anholt | 13 | 18.57% | 2 | 25.00% |
dave airlie | dave airlie | 3 | 4.29% | 3 | 37.50% |
david herrmann | david herrmann | 1 | 1.43% | 1 | 12.50% |
| Total | 70 | 100.00% | 8 | 100.00% |
/**
* New context.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Calls context_switch_complete().
*/
int drm_legacy_newctx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
DRM_DEBUG("%d\n", ctx->handle);
drm_context_switch_complete(dev, file_priv, ctx->handle);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 26 | 37.14% | 1 | 11.11% |
peter antoine | peter antoine | 21 | 30.00% | 1 | 11.11% |
eric anholt | eric anholt | 13 | 18.57% | 2 | 22.22% |
dave airlie | dave airlie | 9 | 12.86% | 4 | 44.44% |
david herrmann | david herrmann | 1 | 1.43% | 1 | 11.11% |
| Total | 70 | 100.00% | 9 | 100.00% |
/**
* Remove context.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* If not the special kernel context, calls ctxbitmap_free() to free the specified context.
*/
int drm_legacy_rmctx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;
if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
DRM_DEBUG("%d\n", ctx->handle);
if (ctx->handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev, ctx->handle);
drm_legacy_ctxbitmap_free(dev, ctx->handle);
}
mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n;
list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
if (pos->handle == ctx->handle) {
list_del(&pos->head);
kfree(pos);
}
}
}
mutex_unlock(&dev->ctxlist_mutex);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave airlie | dave airlie | 93 | 53.76% | 9 | 56.25% |
linus torvalds | linus torvalds | 40 | 23.12% | 2 | 12.50% |
peter antoine | peter antoine | 21 | 12.14% | 1 | 6.25% |
eric anholt | eric anholt | 17 | 9.83% | 3 | 18.75% |
david herrmann | david herrmann | 2 | 1.16% | 1 | 6.25% |
| Total | 173 | 100.00% | 16 | 100.00% |
/*@}*/
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 478 | 31.12% | 7 | 17.07% |
dave airlie | dave airlie | 363 | 23.63% | 19 | 46.34% |
peter antoine | peter antoine | 239 | 15.56% | 1 | 2.44% |
pre-git | pre-git | 159 | 10.35% | 1 | 2.44% |
david herrmann | david herrmann | 147 | 9.57% | 2 | 4.88% |
eric anholt | eric anholt | 121 | 7.88% | 3 | 7.32% |
al viro | al viro | 8 | 0.52% | 1 | 2.44% |
ilija hadzic | ilija hadzic | 8 | 0.52% | 1 | 2.44% |
tejun heo | tejun heo | 5 | 0.33% | 2 | 4.88% |
ville syrjala | ville syrjala | 3 | 0.20% | 1 | 2.44% |
daniel vetter | daniel vetter | 2 | 0.13% | 1 | 2.44% |
benjamin herrenschmidt | benjamin herrenschmidt | 2 | 0.13% | 1 | 2.44% |
david howells | david howells | 1 | 0.07% | 1 | 2.44% |
| Total | 1536 | 100.00% | 41 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.