* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-#define __NO_VERSION__
-#include "via.h"
#include "drmP.h"
#include "via_drm.h"
#include "via_drv.h"
#define MAX_CONTEXT 100
-unsigned int VIA_DEBUG = 1;
-
typedef struct {
- int used;
- int context;
- set_t *sets[2]; /* 0 for frame buffer, 1 for AGP , 2 for System*/
+ int used;
+ int context;
+ set_t *sets[2]; /* 0 for frame buffer, 1 for AGP , 2 for System */
} via_context_t;
static via_context_t global_ppriv[MAX_CONTEXT];
-static int add_alloc_set(int context, int type, unsigned int val)
+static int via_agp_alloc(drm_via_mem_t * mem);
+static int via_agp_free(drm_via_mem_t * mem);
+static int via_fb_alloc(drm_via_mem_t * mem);
+static int via_fb_free(drm_via_mem_t * mem);
+
+static int add_alloc_set(int context, int type, unsigned long val)
{
- int i, retval = 0;
-
- for (i = 0; i < MAX_CONTEXT; i++) {
- if (global_ppriv[i].used &&
- global_ppriv[i].context == context) {
- retval = via_setAdd(global_ppriv[i].sets[type], val);
- break;
- }
- }
-
- return retval;
+ int i, retval = 0;
+
+ for (i = 0; i < MAX_CONTEXT; i++) {
+ if (global_ppriv[i].used && global_ppriv[i].context == context) {
+ retval = via_setAdd(global_ppriv[i].sets[type], val);
+ break;
+ }
+ }
+
+ return retval;
}
-static int del_alloc_set(int context, int type, unsigned int val)
-{
- int i, retval = 0;
-
- for (i = 0; i < MAX_CONTEXT; i++)
- if (global_ppriv[i].used &&
- global_ppriv[i].context == context) {
- retval = via_setDel(global_ppriv[i].sets[type], val);
- break;
- }
-
- return retval;
+static int del_alloc_set(int context, int type, unsigned long val)
+{
+ int i, retval = 0;
+
+ for (i = 0; i < MAX_CONTEXT; i++)
+ if (global_ppriv[i].used && global_ppriv[i].context == context) {
+ retval = via_setDel(global_ppriv[i].sets[type], val);
+ break;
+ }
+
+ return retval;
}
-/* agp memory management */
+/* agp memory management */
static memHeap_t *AgpHeap = NULL;
-int via_agp_init( DRM_IOCTL_ARGS )
+int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- drm_via_agp_t agp;
-
- DRM_COPY_FROM_USER_IOCTL(agp, (drm_via_agp_t *)data, sizeof(agp));
+ drm_via_agp_t *agp = data;
+
+ AgpHeap = via_mmInit(agp->offset, agp->size);
- AgpHeap = via_mmInit(agp.offset, agp.size);
+ DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp->offset,
+ (unsigned long)agp->size);
- DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
-
- return 0;
+ return 0;
}
-/* fb memory management */
+/* fb memory management */
static memHeap_t *FBHeap = NULL;
-int via_fb_init( DRM_IOCTL_ARGS )
+int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- drm_via_fb_t fb;
-
-
- DRM_COPY_FROM_USER_IOCTL(fb, (drm_via_fb_t *)data, sizeof(fb));
+ drm_via_fb_t *fb = data;
- FBHeap = via_mmInit(fb.offset, fb.size);
+ FBHeap = via_mmInit(fb.offset, fb.size);
- DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
+ DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset,
+ (unsigned long)fb.size);
- return 0;
+ return 0;
}
int via_init_context(struct drm_device *dev, int context)
{
- int i;
-
- for (i = 0; i < MAX_CONTEXT ; i++)
- if (global_ppriv[i].used &&
- (global_ppriv[i].context == context))
- break;
-
- if (i >= MAX_CONTEXT) {
- for (i = 0; i < MAX_CONTEXT ; i++) {
- if (!global_ppriv[i].used) {
- global_ppriv[i].context = context;
- global_ppriv[i].used = 1;
- global_ppriv[i].sets[0] = via_setInit();
- global_ppriv[i].sets[1] = via_setInit();
- DRM_DEBUG("init allocation set, socket=%d,"
- " context = %d\n", i, context);
- break;
- }
- }
-
- if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
- (global_ppriv[i].sets[1] == NULL)) {
- return 0;
- }
- }
-
- return 1;
+ int i;
+
+ for (i = 0; i < MAX_CONTEXT; i++)
+ if (global_ppriv[i].used &&
+ (global_ppriv[i].context == context))
+ break;
+
+ if (i >= MAX_CONTEXT) {
+ for (i = 0; i < MAX_CONTEXT; i++) {
+ if (!global_ppriv[i].used) {
+ global_ppriv[i].context = context;
+ global_ppriv[i].used = 1;
+ global_ppriv[i].sets[0] = via_setInit();
+ global_ppriv[i].sets[1] = via_setInit();
+ DRM_DEBUG("init allocation set, socket=%d,"
+ " context = %d\n", i, context);
+ break;
+ }
+ }
+
+ if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
+ (global_ppriv[i].sets[1] == NULL)) {
+ return 0;
+ }
+ }
+
+ return 1;
}
int via_final_context(struct drm_device *dev, int context)
-{
+{
int i;
- for (i=0; i<MAX_CONTEXT; i++)
- if (global_ppriv[i].used &&
- (global_ppriv[i].context == context))
- break;
-
- if (i < MAX_CONTEXT) {
- set_t *set;
- unsigned int item;
- int retval;
-
- DRM_DEBUG("find socket %d, context = %d\n", i, context);
-
- /* Video Memory */
- set = global_ppriv[i].sets[0];
- retval = via_setFirst(set, &item);
- while (retval) {
- DRM_DEBUG("free video memory 0x%x\n", item);
- via_mmFreeMem((PMemBlock)item);
- retval = via_setNext(set, &item);
- }
- via_setDestroy(set);
-
- /* AGP Memory */
- set = global_ppriv[i].sets[1];
- retval = via_setFirst(set, &item);
- while (retval) {
- DRM_DEBUG("free agp memory 0x%x\n", item);
- via_mmFreeMem((PMemBlock)item);
- retval = via_setNext(set, &item);
- }
- via_setDestroy(set);
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+
+ for (i = 0; i < MAX_CONTEXT; i++)
+ if (global_ppriv[i].used &&
+ (global_ppriv[i].context == context))
+ break;
+
+ if (i < MAX_CONTEXT) {
+ set_t *set;
+ ITEM_TYPE item;
+ int retval;
+
+ DRM_DEBUG("find socket %d, context = %d\n", i, context);
+
+ /* Video Memory */
+ set = global_ppriv[i].sets[0];
+ retval = via_setFirst(set, &item);
+ while (retval) {
+ DRM_DEBUG("free video memory 0x%lx\n", item);
+ via_mmFreeMem((PMemBlock) item);
+ retval = via_setNext(set, &item);
+ }
+ via_setDestroy(set);
+
+ /* AGP Memory */
+ set = global_ppriv[i].sets[1];
+ retval = via_setFirst(set, &item);
+ while (retval) {
+ DRM_DEBUG("free agp memory 0x%lx\n", item);
+ via_mmFreeMem((PMemBlock) item);
+ retval = via_setNext(set, &item);
+ }
+ via_setDestroy(set);
+ global_ppriv[i].used = 0;
+ }
+ via_release_futex(dev_priv, context);
- global_ppriv[i].used = 0;
- }
-
- return 1;
+#if defined(__linux__)
+ /* Linux specific until context tracking code gets ported to BSD */
+ /* Last context, perform cleanup */
+ if (dev->ctx_count == 1 && dev->dev_private) {
+ DRM_DEBUG("Last Context\n");
+ if (dev->irq)
+ drm_irq_uninstall(dev);
+
+ via_cleanup_futex(dev_priv);
+ via_do_cleanup_map(dev);
+ }
+#endif
+
+ return 1;
}
-int via_mem_alloc( DRM_IOCTL_ARGS)
+
+int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- drm_via_mem_t mem;
-
- DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t *)data, sizeof(mem));
- switch (mem.type) {
- case VIDEO :
- if (via_fb_alloc(&mem) < 0)
- return -EFAULT;
- DRM_COPY_TO_USER_IOCTL((drm_via_mem_t *)data, mem,
- sizeof(mem));
- return 0;
- case AGP :
- if (via_agp_alloc(&mem) < 0)
- return -EFAULT;
- DRM_COPY_TO_USER_IOCTL((drm_via_mem_t *)data, mem,
- sizeof(mem));
- return 0;
- }
-
- return -EFAULT;
+ drm_via_mem_t *mem = data;
+
+ switch (mem.type) {
+ case VIA_MEM_VIDEO:
+ if (via_fb_alloc(mem) < 0)
+ return -EFAULT;
+ return 0;
+ case VIA_MEM_AGP:
+ if (via_agp_alloc(mem) < 0)
+ return -EFAULT;
+ return 0;
+ }
+
+ return -EFAULT;
}
-int via_fb_alloc(drm_via_mem_t* mem)
+static int via_fb_alloc(drm_via_mem_t * mem)
{
- drm_via_mm_t fb;
- PMemBlock block;
- int retval = 0;
-
- if (!FBHeap)
- return -1;
-
- fb.size = mem->size;
- fb.context = mem->context;
-
- block = via_mmAllocMem(FBHeap, fb.size, 5, 0);
- if (block) {
- fb.offset = block->ofs;
- fb.free = (unsigned int)block;
- if (!add_alloc_set(fb.context, VIDEO, fb.free)) {
- DRM_DEBUG("adding to allocation set fails\n");
- via_mmFreeMem((PMemBlock)fb.free);
- retval = -1;
- }
- }
- else {
- fb.offset = 0;
- fb.size = 0;
- fb.free = 0;
- retval = -1;
- }
-
- mem->offset = fb.offset;
- mem->index = fb.free;
-
- DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size,
- (int)fb.offset);
-
- return retval;
+ drm_via_mm_t fb;
+ PMemBlock block;
+ int retval = 0;
+
+ if (!FBHeap)
+ return -1;
+
+ fb.size = mem->size;
+ fb.context = mem->context;
+
+ block = via_mmAllocMem(FBHeap, fb.size, 5, 0);
+ if (block) {
+ fb.offset = block->ofs;
+ fb.free = (unsigned long)block;
+ if (!add_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) {
+ DRM_DEBUG("adding to allocation set fails\n");
+ via_mmFreeMem((PMemBlock) fb.free);
+ retval = -1;
+ }
+ } else {
+ fb.offset = 0;
+ fb.size = 0;
+ fb.free = 0;
+ retval = -1;
+ }
+
+ mem->offset = fb.offset;
+ mem->index = fb.free;
+
+ DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size,
+ (int)fb.offset);
+
+ return retval;
}
-int via_agp_alloc(drm_via_mem_t* mem)
+
+static int via_agp_alloc(drm_via_mem_t * mem)
{
- drm_via_mm_t agp;
- PMemBlock block;
- int retval = 0;
-
- if (!AgpHeap)
- return -1;
-
- agp.size = mem->size;
- agp.context = mem->context;
-
- block = via_mmAllocMem(AgpHeap, agp.size, 5, 0);
- if (block) {
- agp.offset = block->ofs;
- agp.free = (unsigned int)block;
- if (!add_alloc_set(agp.context, AGP, agp.free)) {
- DRM_DEBUG("adding to allocation set fails\n");
- via_mmFreeMem((PMemBlock)agp.free);
- retval = -1;
- }
- }
- else {
- agp.offset = 0;
- agp.size = 0;
- agp.free = 0;
- }
-
- mem->offset = agp.offset;
- mem->index = agp.free;
-
- DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size,
- (unsigned int)agp.offset);
- return retval;
+ drm_via_mm_t agp;
+ PMemBlock block;
+ int retval = 0;
+
+ if (!AgpHeap)
+ return -1;
+
+ agp.size = mem->size;
+ agp.context = mem->context;
+
+ block = via_mmAllocMem(AgpHeap, agp.size, 5, 0);
+ if (block) {
+ agp.offset = block->ofs;
+ agp.free = (unsigned long)block;
+ if (!add_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) {
+ DRM_DEBUG("adding to allocation set fails\n");
+ via_mmFreeMem((PMemBlock) agp.free);
+ retval = -1;
+ }
+ } else {
+ agp.offset = 0;
+ agp.size = 0;
+ agp.free = 0;
+ }
+
+ mem->offset = agp.offset;
+ mem->index = agp.free;
+
+ DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size,
+ (unsigned int)agp.offset);
+ return retval;
}
-int via_mem_free( DRM_IOCTL_ARGS )
+int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- drm_via_mem_t mem;
-
- DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t *)data, sizeof(mem));
-
- switch (mem.type) {
-
- case VIDEO :
- if (via_fb_free(&mem) == 0)
- return 0;
- break;
- case AGP :
- if (via_agp_free(&mem) == 0)
- return 0;
- break;
- }
-
- return -EFAULT;
+ drm_via_mem_t *mem = data;
+
+ switch (mem->type) {
+
+ case VIA_MEM_VIDEO:
+ if (via_fb_free(mem) == 0)
+ return 0;
+ break;
+ case VIA_MEM_AGP:
+ if (via_agp_free(mem) == 0)
+ return 0;
+ break;
+ }
+
+ return -EFAULT;
}
-int via_fb_free(drm_via_mem_t* mem)
-{
- drm_via_mm_t fb;
- int retval = 0;
-
-
- if (!FBHeap) {
- return -1;
- }
-
- fb.free = mem->index;
- fb.context = mem->context;
-
- if (!fb.free)
- {
- return -1;
-
- }
-
- via_mmFreeMem((PMemBlock)fb.free);
-
- if (!del_alloc_set(fb.context, VIDEO, fb.free))
- {
- retval = -1;
- }
-
- DRM_DEBUG("free fb, free = %d\n", fb.free);
-
- return retval;
-}
-int via_agp_free(drm_via_mem_t* mem)
+
+static int via_fb_free(drm_via_mem_t * mem)
{
- drm_via_mm_t agp;
-
- int retval = 0;
-
- agp.free = mem->index;
- agp.context = mem->context;
-
- if (!agp.free)
- return -1;
-
- via_mmFreeMem((PMemBlock)agp.free);
-
- if (!del_alloc_set(agp.context, AGP, agp.free)) {
- retval = -1;
+ drm_via_mm_t fb;
+ int retval = 0;
+
+ if (!FBHeap) {
+ return -1;
}
- DRM_DEBUG("free agp, free = %d\n", agp.free);
-
- return retval;
-}
+ fb.free = mem->index;
+ fb.context = mem->context;
+
+ if (!fb.free) {
+ return -1;
-EXPORT_SYMBOL(via_fb_alloc);
-EXPORT_SYMBOL(via_fb_free);
+ }
+
+ via_mmFreeMem((PMemBlock) fb.free);
-void DRM(driver_register_fns)(drm_device_t *dev)
+ if (!del_alloc_set(fb.context, VIA_MEM_VIDEO, fb.free)) {
+ retval = -1;
+ }
+
+ DRM_DEBUG("free fb, free = %ld\n", fb.free);
+
+ return retval;
+}
+
+static int via_agp_free(drm_via_mem_t * mem)
{
- dev->fn_tbl.context_ctor = via_init_context;
- dev->fn_tbl.context_dtor = via_final_context;
+ drm_via_mm_t agp;
+
+ int retval = 0;
+
+ agp.free = mem->index;
+ agp.context = mem->context;
+
+ if (!agp.free)
+ return -1;
+
+ via_mmFreeMem((PMemBlock) agp.free);
+
+ if (!del_alloc_set(agp.context, VIA_MEM_AGP, agp.free)) {
+ retval = -1;
+ }
+
+ DRM_DEBUG("free agp, free = %ld\n", agp.nfree);
+
+ return retval;
}