sis_mm.c revision 182080
19517SBill.Taylor@Sun.COM/* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*-
29517SBill.Taylor@Sun.COM * Created: Mon Jan  4 10:05:05 1999 by sclin@sis.com.tw
39517SBill.Taylor@Sun.COM *
49517SBill.Taylor@Sun.COM * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
59517SBill.Taylor@Sun.COM * All rights reserved.
69517SBill.Taylor@Sun.COM *
79517SBill.Taylor@Sun.COM * Permission is hereby granted, free of charge, to any person obtaining a
89517SBill.Taylor@Sun.COM * copy of this software and associated documentation files (the "Software"),
99517SBill.Taylor@Sun.COM * to deal in the Software without restriction, including without limitation
109517SBill.Taylor@Sun.COM * the rights to use, copy, modify, merge, publish, distribute, sublicense,
119517SBill.Taylor@Sun.COM * and/or sell copies of the Software, and to permit persons to whom the
129517SBill.Taylor@Sun.COM * Software is furnished to do so, subject to the following conditions:
139517SBill.Taylor@Sun.COM *
149517SBill.Taylor@Sun.COM * The above copyright notice and this permission notice (including the next
159517SBill.Taylor@Sun.COM * paragraph) shall be included in all copies or substantial portions of the
169517SBill.Taylor@Sun.COM * Software.
179517SBill.Taylor@Sun.COM *
189517SBill.Taylor@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
199517SBill.Taylor@Sun.COM * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
209517SBill.Taylor@Sun.COM * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
219517SBill.Taylor@Sun.COM * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
229517SBill.Taylor@Sun.COM * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2312965SWilliam.Taylor@Oracle.COM * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
249517SBill.Taylor@Sun.COM * DEALINGS IN THE SOFTWARE.
259517SBill.Taylor@Sun.COM *
269517SBill.Taylor@Sun.COM * Authors:
279517SBill.Taylor@Sun.COM *    Sung-Ching Lin <sclin@sis.com.tw>
289517SBill.Taylor@Sun.COM *
299517SBill.Taylor@Sun.COM */
309517SBill.Taylor@Sun.COM
319517SBill.Taylor@Sun.COM#include <sys/cdefs.h>
329517SBill.Taylor@Sun.COM__FBSDID("$FreeBSD: head/sys/dev/drm/sis_mm.c 182080 2008-08-23 20:59:12Z rnoland $");
339517SBill.Taylor@Sun.COM
349517SBill.Taylor@Sun.COM#if defined(__linux__) && defined(CONFIG_FB_SIS)
359517SBill.Taylor@Sun.COM#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
369517SBill.Taylor@Sun.COM#include <video/sisfb.h>
379517SBill.Taylor@Sun.COM#else
389517SBill.Taylor@Sun.COM#include <linux/sisfb.h>
399517SBill.Taylor@Sun.COM#endif
409517SBill.Taylor@Sun.COM#endif
419517SBill.Taylor@Sun.COM#include "dev/drm/drmP.h"
429517SBill.Taylor@Sun.COM#include "dev/drm/sis_drm.h"
439517SBill.Taylor@Sun.COM#include "dev/drm/sis_drv.h"
449517SBill.Taylor@Sun.COM#include "dev/drm/sis_ds.h"
459517SBill.Taylor@Sun.COM
469517SBill.Taylor@Sun.COM#define MAX_CONTEXT 100
479517SBill.Taylor@Sun.COM#define VIDEO_TYPE 0
489517SBill.Taylor@Sun.COM#define AGP_TYPE 1
499517SBill.Taylor@Sun.COM
509517SBill.Taylor@Sun.COMtypedef struct {
519517SBill.Taylor@Sun.COM	int used;
529517SBill.Taylor@Sun.COM	int context;
539517SBill.Taylor@Sun.COM	set_t *sets[2];		/* 0 for video, 1 for AGP */
549517SBill.Taylor@Sun.COM} sis_context_t;
559517SBill.Taylor@Sun.COM
569517SBill.Taylor@Sun.COMstatic sis_context_t global_ppriv[MAX_CONTEXT];
579517SBill.Taylor@Sun.COM
589517SBill.Taylor@Sun.COMstatic int add_alloc_set(int context, int type, unsigned int val)
599517SBill.Taylor@Sun.COM{
609517SBill.Taylor@Sun.COM	int i, retval = 0;
619517SBill.Taylor@Sun.COM
629517SBill.Taylor@Sun.COM	for (i = 0; i < MAX_CONTEXT; i++) {
639517SBill.Taylor@Sun.COM		if (global_ppriv[i].used && global_ppriv[i].context == context) {
649517SBill.Taylor@Sun.COM			retval = setAdd(global_ppriv[i].sets[type], val);
659517SBill.Taylor@Sun.COM			break;
669517SBill.Taylor@Sun.COM		}
679517SBill.Taylor@Sun.COM	}
689517SBill.Taylor@Sun.COM	return retval;
699517SBill.Taylor@Sun.COM}
709517SBill.Taylor@Sun.COM
719517SBill.Taylor@Sun.COMstatic int del_alloc_set(int context, int type, unsigned int val)
729517SBill.Taylor@Sun.COM{
739517SBill.Taylor@Sun.COM	int i, retval = 0;
749517SBill.Taylor@Sun.COM
759517SBill.Taylor@Sun.COM	for (i = 0; i < MAX_CONTEXT; i++) {
769517SBill.Taylor@Sun.COM		if (global_ppriv[i].used && global_ppriv[i].context == context) {
779517SBill.Taylor@Sun.COM			retval = setDel(global_ppriv[i].sets[type], val);
789517SBill.Taylor@Sun.COM			break;
799517SBill.Taylor@Sun.COM		}
809517SBill.Taylor@Sun.COM	}
819517SBill.Taylor@Sun.COM	return retval;
829517SBill.Taylor@Sun.COM}
839517SBill.Taylor@Sun.COM
849517SBill.Taylor@Sun.COM/* fb management via fb device */
859517SBill.Taylor@Sun.COM#if defined(__linux__) && defined(CONFIG_FB_SIS)
869517SBill.Taylor@Sun.COM
879517SBill.Taylor@Sun.COMstatic int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
889517SBill.Taylor@Sun.COM{
899517SBill.Taylor@Sun.COM	return 0;
909517SBill.Taylor@Sun.COM}
919517SBill.Taylor@Sun.COM
929517SBill.Taylor@Sun.COMstatic int sis_fb_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
939517SBill.Taylor@Sun.COM{
949517SBill.Taylor@Sun.COM	drm_sis_mem_t *fb = data;
959517SBill.Taylor@Sun.COM	struct sis_memreq req;
969517SBill.Taylor@Sun.COM	int retval = 0;
979517SBill.Taylor@Sun.COM
989517SBill.Taylor@Sun.COM	req.size = fb->size;
999517SBill.Taylor@Sun.COM	sis_malloc(&req);
1009517SBill.Taylor@Sun.COM	if (req.offset) {
1019517SBill.Taylor@Sun.COM		/* TODO */
1029517SBill.Taylor@Sun.COM		fb->offset = req.offset;
1039517SBill.Taylor@Sun.COM		fb->free = req.offset;
1049517SBill.Taylor@Sun.COM		if (!add_alloc_set(fb->context, VIDEO_TYPE, fb->free)) {
1059517SBill.Taylor@Sun.COM			DRM_DEBUG("adding to allocation set fails\n");
1069517SBill.Taylor@Sun.COM			sis_free(req.offset);
1079517SBill.Taylor@Sun.COM			retval = -EINVAL;
1089517SBill.Taylor@Sun.COM		}
1099517SBill.Taylor@Sun.COM	} else {
1109517SBill.Taylor@Sun.COM		fb->offset = 0;
1119517SBill.Taylor@Sun.COM		fb->size = 0;
1129517SBill.Taylor@Sun.COM		fb->free = 0;
1139517SBill.Taylor@Sun.COM	}
1149517SBill.Taylor@Sun.COM
1159517SBill.Taylor@Sun.COM	DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb->size, req.offset);
1169517SBill.Taylor@Sun.COM
1179517SBill.Taylor@Sun.COM	return retval;
1189517SBill.Taylor@Sun.COM}
1199517SBill.Taylor@Sun.COM
1209517SBill.Taylor@Sun.COMstatic int sis_fb_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
1219517SBill.Taylor@Sun.COM{
1229517SBill.Taylor@Sun.COM	drm_sis_mem_t fb;
1239517SBill.Taylor@Sun.COM	int retval = 0;
1249517SBill.Taylor@Sun.COM
1259517SBill.Taylor@Sun.COM	if (!fb->free)
1269517SBill.Taylor@Sun.COM		return -EINVAL;
1279517SBill.Taylor@Sun.COM
1289517SBill.Taylor@Sun.COM	if (!del_alloc_set(fb->context, VIDEO_TYPE, fb->free))
1299517SBill.Taylor@Sun.COM		retval = -EINVAL;
1309517SBill.Taylor@Sun.COM	sis_free(fb->free);
1319517SBill.Taylor@Sun.COM
1329517SBill.Taylor@Sun.COM	DRM_DEBUG("free fb, offset = 0x%lx\n", fb->free);
1339517SBill.Taylor@Sun.COM
1349517SBill.Taylor@Sun.COM	return retval;
1359517SBill.Taylor@Sun.COM}
1369517SBill.Taylor@Sun.COM
1379517SBill.Taylor@Sun.COM#else
1389517SBill.Taylor@Sun.COM
1399517SBill.Taylor@Sun.COM/* Called by the X Server to initialize the FB heap.  Allocations will fail
1409517SBill.Taylor@Sun.COM * unless this is called.  Offset is the beginning of the heap from the
1419517SBill.Taylor@Sun.COM * framebuffer offset (MaxXFBMem in XFree86).
1429517SBill.Taylor@Sun.COM *
1439517SBill.Taylor@Sun.COM * Memory layout according to Thomas Winischofer:
1449517SBill.Taylor@Sun.COM * |------------------|DDDDDDDDDDDDDDDDDDDDDDDDDDDDD|HHHH|CCCCCCCCCCC|
1459517SBill.Taylor@Sun.COM *
1469517SBill.Taylor@Sun.COM *    X driver/sisfb                                  HW-   Command-
1479517SBill.Taylor@Sun.COM *  framebuffer memory           DRI heap           Cursor   queue
1489517SBill.Taylor@Sun.COM */
1499517SBill.Taylor@Sun.COMstatic int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
1509517SBill.Taylor@Sun.COM{
1519517SBill.Taylor@Sun.COM	drm_sis_private_t *dev_priv = dev->dev_private;
1529517SBill.Taylor@Sun.COM	drm_sis_fb_t *fb = data;
1539517SBill.Taylor@Sun.COM
1549517SBill.Taylor@Sun.COM	if (dev_priv == NULL) {
1559517SBill.Taylor@Sun.COM		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
1569517SBill.Taylor@Sun.COM					      DRM_MEM_DRIVER);
1579517SBill.Taylor@Sun.COM		dev_priv = dev->dev_private;
1589517SBill.Taylor@Sun.COM		if (dev_priv == NULL)
1599517SBill.Taylor@Sun.COM			return ENOMEM;
1609517SBill.Taylor@Sun.COM	}
1619517SBill.Taylor@Sun.COM
1629517SBill.Taylor@Sun.COM	if (dev_priv->FBHeap != NULL)
1639517SBill.Taylor@Sun.COM		return -EINVAL;
1649517SBill.Taylor@Sun.COM
1659517SBill.Taylor@Sun.COM	dev_priv->FBHeap = mmInit(fb->offset, fb->size);
1669517SBill.Taylor@Sun.COM
1679517SBill.Taylor@Sun.COM	DRM_DEBUG("offset = %u, size = %u", fb->offset, fb->size);
16812965SWilliam.Taylor@Oracle.COM
16912965SWilliam.Taylor@Oracle.COM	return 0;
17012965SWilliam.Taylor@Oracle.COM}
17112965SWilliam.Taylor@Oracle.COM
1729517SBill.Taylor@Sun.COMstatic int sis_fb_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
1739517SBill.Taylor@Sun.COM{
1749517SBill.Taylor@Sun.COM	drm_sis_private_t *dev_priv = dev->dev_private;
1759517SBill.Taylor@Sun.COM	drm_sis_mem_t *fb = data;
1769517SBill.Taylor@Sun.COM	PMemBlock block;
1779517SBill.Taylor@Sun.COM	int retval = 0;
1789517SBill.Taylor@Sun.COM
1799517SBill.Taylor@Sun.COM	if (dev_priv == NULL || dev_priv->FBHeap == NULL)
1809517SBill.Taylor@Sun.COM		return -EINVAL;
1819517SBill.Taylor@Sun.COM
1829517SBill.Taylor@Sun.COM	block = mmAllocMem(dev_priv->FBHeap, fb->size, 0, 0);
1839517SBill.Taylor@Sun.COM	if (block) {
1849517SBill.Taylor@Sun.COM		/* TODO */
1859517SBill.Taylor@Sun.COM		fb->offset = block->ofs;
1869517SBill.Taylor@Sun.COM		fb->free = (unsigned long)block;
1879517SBill.Taylor@Sun.COM		if (!add_alloc_set(fb->context, VIDEO_TYPE, fb->free)) {
1889517SBill.Taylor@Sun.COM			DRM_DEBUG("adding to allocation set fails\n");
1899517SBill.Taylor@Sun.COM			mmFreeMem((PMemBlock) fb->free);
1909517SBill.Taylor@Sun.COM			retval = -EINVAL;
1919517SBill.Taylor@Sun.COM		}
1929517SBill.Taylor@Sun.COM	} else {
1939517SBill.Taylor@Sun.COM		fb->offset = 0;
1949517SBill.Taylor@Sun.COM		fb->size = 0;
1959517SBill.Taylor@Sun.COM		fb->free = 0;
1969517SBill.Taylor@Sun.COM	}
1979517SBill.Taylor@Sun.COM
1989517SBill.Taylor@Sun.COM	DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb->size, fb->offset);
1999517SBill.Taylor@Sun.COM
2009517SBill.Taylor@Sun.COM	return retval;
2019517SBill.Taylor@Sun.COM}
2029517SBill.Taylor@Sun.COM
2039517SBill.Taylor@Sun.COMstatic int sis_fb_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
2049517SBill.Taylor@Sun.COM{
2059517SBill.Taylor@Sun.COM	drm_sis_private_t *dev_priv = dev->dev_private;
2069517SBill.Taylor@Sun.COM	drm_sis_mem_t *fb = data;
2079517SBill.Taylor@Sun.COM
2089517SBill.Taylor@Sun.COM	if (dev_priv == NULL || dev_priv->FBHeap == NULL)
2099517SBill.Taylor@Sun.COM		return -EINVAL;
2109517SBill.Taylor@Sun.COM
2119517SBill.Taylor@Sun.COM	if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock) fb->free))
2129517SBill.Taylor@Sun.COM		return -EINVAL;
2139517SBill.Taylor@Sun.COM
2149517SBill.Taylor@Sun.COM	if (!del_alloc_set(fb->context, VIDEO_TYPE, fb->free))
2159517SBill.Taylor@Sun.COM		return -EINVAL;
2169517SBill.Taylor@Sun.COM	mmFreeMem((PMemBlock) fb->free);
2179517SBill.Taylor@Sun.COM
2189517SBill.Taylor@Sun.COM	DRM_DEBUG("free fb, free = 0x%lx\n", fb->free);
2199517SBill.Taylor@Sun.COM
2209517SBill.Taylor@Sun.COM	return 0;
2219517SBill.Taylor@Sun.COM}
2229517SBill.Taylor@Sun.COM
2239517SBill.Taylor@Sun.COM#endif
2249517SBill.Taylor@Sun.COM
2259517SBill.Taylor@Sun.COM/* agp memory management */
2269517SBill.Taylor@Sun.COM
2279517SBill.Taylor@Sun.COMstatic int sis_ioctl_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
2289517SBill.Taylor@Sun.COM{
2299517SBill.Taylor@Sun.COM	drm_sis_private_t *dev_priv = dev->dev_private;
2309517SBill.Taylor@Sun.COM	drm_sis_agp_t *agp = data;
2319517SBill.Taylor@Sun.COM
2329517SBill.Taylor@Sun.COM	if (dev_priv == NULL) {
2339517SBill.Taylor@Sun.COM		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
2349517SBill.Taylor@Sun.COM					      DRM_MEM_DRIVER);
2359517SBill.Taylor@Sun.COM		dev_priv = dev->dev_private;
2369517SBill.Taylor@Sun.COM		if (dev_priv == NULL)
2379517SBill.Taylor@Sun.COM			return ENOMEM;
2389517SBill.Taylor@Sun.COM	}
2399517SBill.Taylor@Sun.COM
2409517SBill.Taylor@Sun.COM	if (dev_priv->AGPHeap != NULL)
2419517SBill.Taylor@Sun.COM		return -EINVAL;
2429517SBill.Taylor@Sun.COM
2439517SBill.Taylor@Sun.COM	dev_priv->AGPHeap = mmInit(agp->offset, agp->size);
2449517SBill.Taylor@Sun.COM
2459517SBill.Taylor@Sun.COM	DRM_DEBUG("offset = %u, size = %u", agp->offset, agp->size);
2469517SBill.Taylor@Sun.COM
2479517SBill.Taylor@Sun.COM	return 0;
2489517SBill.Taylor@Sun.COM}
2499517SBill.Taylor@Sun.COM
2509517SBill.Taylor@Sun.COMstatic int sis_ioctl_agp_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
2519517SBill.Taylor@Sun.COM{
2529517SBill.Taylor@Sun.COM	drm_sis_private_t *dev_priv = dev->dev_private;
2539517SBill.Taylor@Sun.COM	drm_sis_mem_t *agp = data;
2549517SBill.Taylor@Sun.COM	PMemBlock block;
2559517SBill.Taylor@Sun.COM	int retval = 0;
2569517SBill.Taylor@Sun.COM
2579517SBill.Taylor@Sun.COM	if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
2589517SBill.Taylor@Sun.COM		return -EINVAL;
2599517SBill.Taylor@Sun.COM
2609517SBill.Taylor@Sun.COM	block = mmAllocMem(dev_priv->AGPHeap, agp->size, 0, 0);
2619517SBill.Taylor@Sun.COM	if (block) {
2629517SBill.Taylor@Sun.COM		/* TODO */
2639517SBill.Taylor@Sun.COM		agp->offset = block->ofs;
2649517SBill.Taylor@Sun.COM		agp->free = (unsigned long)block;
2659517SBill.Taylor@Sun.COM		if (!add_alloc_set(agp->context, AGP_TYPE, agp->free)) {
2669517SBill.Taylor@Sun.COM			DRM_DEBUG("adding to allocation set fails\n");
2679517SBill.Taylor@Sun.COM			mmFreeMem((PMemBlock) agp->free);
2689517SBill.Taylor@Sun.COM			retval = -1;
2699517SBill.Taylor@Sun.COM		}
2709517SBill.Taylor@Sun.COM	} else {
2719517SBill.Taylor@Sun.COM		agp->offset = 0;
2729517SBill.Taylor@Sun.COM		agp->size = 0;
2739517SBill.Taylor@Sun.COM		agp->free = 0;
2749517SBill.Taylor@Sun.COM	}
2759517SBill.Taylor@Sun.COM
2769517SBill.Taylor@Sun.COM	DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp->size,
2779517SBill.Taylor@Sun.COM	    agp->offset);
2789517SBill.Taylor@Sun.COM
2799517SBill.Taylor@Sun.COM	return retval;
2809517SBill.Taylor@Sun.COM}
2819517SBill.Taylor@Sun.COM
2829517SBill.Taylor@Sun.COMstatic int sis_ioctl_agp_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
2839517SBill.Taylor@Sun.COM{
2849517SBill.Taylor@Sun.COM	drm_sis_private_t *dev_priv = dev->dev_private;
2859517SBill.Taylor@Sun.COM	drm_sis_mem_t *agp = data;
2869517SBill.Taylor@Sun.COM
2879517SBill.Taylor@Sun.COM	if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
2889517SBill.Taylor@Sun.COM		return -EINVAL;
2899517SBill.Taylor@Sun.COM
2909517SBill.Taylor@Sun.COM	if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock) agp->free))
2919517SBill.Taylor@Sun.COM		return -EINVAL;
2929517SBill.Taylor@Sun.COM
2939517SBill.Taylor@Sun.COM	mmFreeMem((PMemBlock) agp->free);
2949517SBill.Taylor@Sun.COM	if (!del_alloc_set(agp->context, AGP_TYPE, agp->free))
2959517SBill.Taylor@Sun.COM		return -EINVAL;
2969517SBill.Taylor@Sun.COM
2979517SBill.Taylor@Sun.COM	DRM_DEBUG("free agp, free = 0x%lx\n", agp->free);
2989517SBill.Taylor@Sun.COM
2999517SBill.Taylor@Sun.COM	return 0;
3009517SBill.Taylor@Sun.COM}
3019517SBill.Taylor@Sun.COM
3029517SBill.Taylor@Sun.COMint sis_init_context(struct drm_device *dev, int context)
3039517SBill.Taylor@Sun.COM{
3049517SBill.Taylor@Sun.COM	int i;
3059517SBill.Taylor@Sun.COM
3069517SBill.Taylor@Sun.COM	for (i = 0; i < MAX_CONTEXT; i++) {
3079517SBill.Taylor@Sun.COM		if (global_ppriv[i].used &&
3089517SBill.Taylor@Sun.COM		    (global_ppriv[i].context == context))
3099517SBill.Taylor@Sun.COM			break;
3109517SBill.Taylor@Sun.COM	}
3119517SBill.Taylor@Sun.COM
3129517SBill.Taylor@Sun.COM	if (i >= MAX_CONTEXT) {
3139517SBill.Taylor@Sun.COM		for (i = 0; i < MAX_CONTEXT; i++) {
3149517SBill.Taylor@Sun.COM			if (!global_ppriv[i].used) {
3159517SBill.Taylor@Sun.COM				global_ppriv[i].context = context;
3169517SBill.Taylor@Sun.COM				global_ppriv[i].used = 1;
3179517SBill.Taylor@Sun.COM				global_ppriv[i].sets[0] = setInit();
3189517SBill.Taylor@Sun.COM				global_ppriv[i].sets[1] = setInit();
3199517SBill.Taylor@Sun.COM				DRM_DEBUG("init allocation set, socket=%d, "
3209517SBill.Taylor@Sun.COM					  "context = %d\n", i, context);
3219517SBill.Taylor@Sun.COM				break;
3229517SBill.Taylor@Sun.COM			}
3239517SBill.Taylor@Sun.COM		}
3249517SBill.Taylor@Sun.COM		if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
3259517SBill.Taylor@Sun.COM		    (global_ppriv[i].sets[1] == NULL)) {
3269517SBill.Taylor@Sun.COM			return 0;
3279517SBill.Taylor@Sun.COM		}
3289517SBill.Taylor@Sun.COM	}
3299517SBill.Taylor@Sun.COM
3309517SBill.Taylor@Sun.COM	return 1;
3319517SBill.Taylor@Sun.COM}
3329517SBill.Taylor@Sun.COM
3339517SBill.Taylor@Sun.COMint sis_final_context(struct drm_device *dev, int context)
3349517SBill.Taylor@Sun.COM{
3359517SBill.Taylor@Sun.COM	int i;
3369517SBill.Taylor@Sun.COM
3379517SBill.Taylor@Sun.COM	for (i = 0; i < MAX_CONTEXT; i++) {
3389517SBill.Taylor@Sun.COM		if (global_ppriv[i].used &&
3399517SBill.Taylor@Sun.COM		    (global_ppriv[i].context == context))
3409517SBill.Taylor@Sun.COM			break;
3419517SBill.Taylor@Sun.COM	}
3429517SBill.Taylor@Sun.COM
3439517SBill.Taylor@Sun.COM	if (i < MAX_CONTEXT) {
3449517SBill.Taylor@Sun.COM		set_t *set;
3459517SBill.Taylor@Sun.COM		ITEM_TYPE item;
3469517SBill.Taylor@Sun.COM		int retval;
3479517SBill.Taylor@Sun.COM
3489517SBill.Taylor@Sun.COM		DRM_DEBUG("find socket %d, context = %d\n", i, context);
3499517SBill.Taylor@Sun.COM
3509517SBill.Taylor@Sun.COM		/* Video Memory */
3519517SBill.Taylor@Sun.COM		set = global_ppriv[i].sets[0];
3529517SBill.Taylor@Sun.COM		retval = setFirst(set, &item);
3539517SBill.Taylor@Sun.COM		while (retval) {
3549517SBill.Taylor@Sun.COM			DRM_DEBUG("free video memory 0x%lx\n", item);
3559517SBill.Taylor@Sun.COM#if defined(__linux__) && defined(CONFIG_FB_SIS)
3569517SBill.Taylor@Sun.COM			sis_free(item);
3579517SBill.Taylor@Sun.COM#else
3589517SBill.Taylor@Sun.COM			mmFreeMem((PMemBlock) item);
3599517SBill.Taylor@Sun.COM#endif
3609517SBill.Taylor@Sun.COM			retval = setNext(set, &item);
3619517SBill.Taylor@Sun.COM		}
3629517SBill.Taylor@Sun.COM		setDestroy(set);
3639517SBill.Taylor@Sun.COM
3649517SBill.Taylor@Sun.COM		/* AGP Memory */
3659517SBill.Taylor@Sun.COM		set = global_ppriv[i].sets[1];
3669517SBill.Taylor@Sun.COM		retval = setFirst(set, &item);
3679517SBill.Taylor@Sun.COM		while (retval) {
3689517SBill.Taylor@Sun.COM			DRM_DEBUG("free agp memory 0x%lx\n", item);
3699517SBill.Taylor@Sun.COM			mmFreeMem((PMemBlock) item);
3709517SBill.Taylor@Sun.COM			retval = setNext(set, &item);
3719517SBill.Taylor@Sun.COM		}
3729517SBill.Taylor@Sun.COM		setDestroy(set);
3739517SBill.Taylor@Sun.COM
3749517SBill.Taylor@Sun.COM		global_ppriv[i].used = 0;
3759517SBill.Taylor@Sun.COM	}
3769517SBill.Taylor@Sun.COM
3779517SBill.Taylor@Sun.COM	return 1;
3789517SBill.Taylor@Sun.COM}
3799517SBill.Taylor@Sun.COM
38012965SWilliam.Taylor@Oracle.COMdrm_ioctl_desc_t sis_ioctls[] = {
38112965SWilliam.Taylor@Oracle.COM	DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH),
38212965SWilliam.Taylor@Oracle.COM	DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_fb_free, DRM_AUTH),
3839517SBill.Taylor@Sun.COM	DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3849517SBill.Taylor@Sun.COM	DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH),
3859517SBill.Taylor@Sun.COM	DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_ioctl_agp_free, DRM_AUTH),
3869517SBill.Taylor@Sun.COM	DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY)
3879517SBill.Taylor@Sun.COM};
3889517SBill.Taylor@Sun.COM
389int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
390