sis_ds.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*-
  2.  * Created: Mon Jan  4 10:05:05 1999 by sclin@sis.com.tw
  3.  *
  4.  * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
  5.  * All rights reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  * 
  14.  * The above copyright notice and this permission notice (including the next
  15.  * paragraph) shall be included in all copies or substantial portions of the
  16.  * Software.
  17.  * 
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  22.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  23.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24.  * DEALINGS IN THE SOFTWARE.
  25.  * 
  26.  * Authors:
  27.  *    Sung-Ching Lin <sclin@sis.com.tw>
  28.  * 
  29.  */
  30. #include <linux/module.h>
  31. #include <linux/delay.h>
  32. #include <linux/errno.h>
  33. #include <linux/kernel.h>
  34. #include <linux/slab.h>
  35. #include <linux/poll.h>
  36. #include <asm/io.h>
  37. #include <linux/pci.h>
  38. #include "sis_ds.h"
  39. /* Set Data Structure, not check repeated value
  40.  * temporarily used
  41.  */
  42. set_t *setInit(void)
  43. {
  44.   int i;
  45.   set_t *set;
  46.   set = (set_t *)MALLOC(sizeof(set_t));
  47.   if (set) {
  48.     for(i = 0; i < SET_SIZE; i++){
  49.       set->list[i].free_next = i+1;    
  50.       set->list[i].alloc_next = -1;
  51.     }    
  52.     set->list[SET_SIZE-1].free_next = -1;
  53.     set->free = 0;
  54.     set->alloc = -1;
  55.     set->trace = -1;
  56.   }
  57.   return set;
  58. }
  59. int setAdd(set_t *set, ITEM_TYPE item)
  60. {
  61.   int free = set->free;
  62.   
  63.   if(free != -1){
  64.     set->list[free].val = item;
  65.     set->free = set->list[free].free_next;
  66.   }
  67.   else{
  68.     return 0;
  69.   }
  70.   set->list[free].alloc_next = set->alloc;
  71.   set->alloc = free;  
  72.   set->list[free].free_next = -1;    
  73.   return 1;
  74. }
  75. int setDel(set_t *set, ITEM_TYPE item)
  76. {
  77.   int alloc = set->alloc;
  78.   int prev = -1;  
  79.   
  80.   while(alloc != -1){
  81.     if(set->list[alloc].val == item){
  82.       if(prev != -1)      
  83.         set->list[prev].alloc_next = set->list[alloc].alloc_next; 
  84.       else
  85.         set->alloc = set->list[alloc].alloc_next;
  86.       break;
  87.     }
  88.     prev = alloc;
  89.     alloc = set->list[alloc].alloc_next;      
  90.   }
  91.   if(alloc == -1)
  92.     return 0;
  93.   
  94.   set->list[alloc].free_next = set->free;
  95.   set->free = alloc;
  96.   set->list[alloc].alloc_next = -1;   
  97.   return 1;
  98. }
  99. /* setFirst -> setAdd -> setNext is wrong */
  100. int setFirst(set_t *set, ITEM_TYPE *item)
  101. {
  102.   if(set->alloc == -1)
  103.     return 0;
  104.   *item = set->list[set->alloc].val;
  105.   set->trace = set->list[set->alloc].alloc_next; 
  106.   return 1;
  107. }
  108. int setNext(set_t *set, ITEM_TYPE *item)
  109. {
  110.   if(set->trace == -1)
  111.     return 0;
  112.   
  113.   *item = set->list[set->trace].val;
  114.   set->trace = set->list[set->trace].alloc_next;      
  115.   return 1;
  116. }
  117. int setDestroy(set_t *set)
  118. {
  119.   FREE(set);
  120.   return 1;
  121. }
  122. /*
  123.  * GLX Hardware Device Driver common code
  124.  * Copyright (C) 1999 Keith Whitwell
  125.  *
  126.  * Permission is hereby granted, free of charge, to any person obtaining a
  127.  * copy of this software and associated documentation files (the "Software"),
  128.  * to deal in the Software without restriction, including without limitation
  129.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  130.  * and/or sell copies of the Software, and to permit persons to whom the
  131.  * Software is furnished to do so, subject to the following conditions:
  132.  *
  133.  * The above copyright notice and this permission notice shall be included
  134.  * in all copies or substantial portions of the Software.
  135.  *
  136.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  137.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  138.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  139.  * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
  140.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
  141.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
  142.  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  143.  *
  144.  */
  145. #define ISFREE(bptr) ((bptr)->free)
  146. #define PRINTF(fmt, arg...) do{}while(0)
  147. #define fprintf(fmt, arg...) do{}while(0)
  148. static void *calloc(size_t nmemb, size_t size)
  149. {
  150.   void *addr;
  151.   addr = kmalloc(nmemb*size, GFP_KERNEL);
  152.   if (addr)
  153.     memset(addr, 0, nmemb*size);
  154.   return addr;
  155. }
  156. #define free(n) kfree(n)
  157.            
  158. void mmDumpMemInfo( memHeap_t *heap )
  159. {
  160.   TMemBlock *p;
  161.   PRINTF ("Memory heap %p:n", heap);
  162.   if (heap == 0) {
  163.     PRINTF ("  heap == 0n");
  164.   } else {
  165.     p = (TMemBlock *)heap;
  166.     while (p) {
  167.       PRINTF ("  Offset:%08x, Size:%08x, %c%cn",p->ofs,p->size,
  168.      p->free ? '.':'U',
  169.      p->reserved ? 'R':'.');
  170.       p = p->next;
  171.     }
  172.   }
  173.   PRINTF ("End of memory blocksn");
  174. }
  175. memHeap_t *mmInit(int ofs,
  176.   int size)
  177. {
  178.    PMemBlock blocks;
  179.   
  180.    if (size <= 0) {
  181.       return 0;
  182.    }
  183.    blocks = (TMemBlock *) calloc(1,sizeof(TMemBlock));
  184.    if (blocks) {
  185.       blocks->ofs = ofs;
  186.       blocks->size = size;
  187.       blocks->free = 1;
  188.       return (memHeap_t *)blocks;
  189.    } else
  190.       return 0;
  191. }
  192. /* Kludgey workaround for existing i810 server.  Remove soon.
  193.  */
  194. memHeap_t *mmAddRange( memHeap_t *heap,
  195.        int ofs,
  196.        int size )
  197. {
  198.    PMemBlock blocks;
  199.    blocks = (TMemBlock *) calloc(2,sizeof(TMemBlock));
  200.    if (blocks) {
  201.       blocks[0].size = size;
  202.       blocks[0].free = 1;
  203.       blocks[0].ofs = ofs;
  204.       blocks[0].next = &blocks[1];
  205.       /* Discontinuity - stops JoinBlock from trying to join non-adjacent
  206.        * ranges.
  207.        */
  208.       blocks[1].size = 0;
  209.       blocks[1].free = 0;
  210.       blocks[1].ofs = ofs+size;
  211.       blocks[1].next = (PMemBlock) heap;      
  212.       return (memHeap_t *)blocks;
  213.    } 
  214.    else
  215.       return heap;
  216. }
  217. static TMemBlock* SliceBlock(TMemBlock *p, 
  218.      int startofs, int size, 
  219.      int reserved, int alignment)
  220. {
  221.   TMemBlock *newblock;
  222.   /* break left */
  223.   if (startofs > p->ofs) {
  224.     newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
  225.     newblock->ofs = startofs;
  226.     newblock->size = p->size - (startofs - p->ofs);
  227.     newblock->free = 1;
  228.     newblock->next = p->next;
  229.     p->size -= newblock->size;
  230.     p->next = newblock;
  231.     p = newblock;
  232.   }
  233.   /* break right */
  234.   if (size < p->size) {
  235.     newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
  236.     newblock->ofs = startofs + size;
  237.     newblock->size = p->size - size;
  238.     newblock->free = 1;
  239.     newblock->next = p->next;
  240.     p->size = size;
  241.     p->next = newblock;
  242.   }
  243.   /* p = middle block */
  244.   p->align = alignment;
  245.   p->free = 0;
  246.   p->reserved = reserved;
  247.   return p;
  248. }
  249. PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
  250. {
  251.   int mask,startofs,endofs;
  252.   TMemBlock *p;
  253.   if (!heap || align2 < 0 || size <= 0)
  254.     return NULL;
  255.   mask = (1 << align2)-1;
  256.   startofs = 0;
  257.   p = (TMemBlock *)heap;
  258.   while (p) {
  259.     if (ISFREE(p)) {
  260.       startofs = (p->ofs + mask) & ~mask;
  261.       if ( startofs < startSearch ) {
  262.        startofs = startSearch;
  263.       }
  264.       endofs = startofs+size;
  265.       if (endofs <= (p->ofs+p->size))
  266. break;
  267.     }
  268.     p = p->next;
  269.   }
  270.   if (!p)
  271.     return NULL;
  272.   p = SliceBlock(p,startofs,size,0,mask+1);
  273.   p->heap = heap;
  274.   return p;
  275. }
  276. static __inline__ int Join2Blocks(TMemBlock *p)
  277. {
  278.   if (p->free && p->next && p->next->free) {
  279.     TMemBlock *q = p->next;
  280.     p->size += q->size;
  281.     p->next = q->next;
  282.     free(q);
  283.     return 1;
  284.   }
  285.   return 0;
  286. }
  287. int mmFreeMem(PMemBlock b)
  288. {
  289.   TMemBlock *p,*prev;
  290.   if (!b)
  291.     return 0;
  292.   if (!b->heap) {
  293.      fprintf(stderr, "no heapn");
  294.      return -1;
  295.   }
  296.   p = b->heap;
  297.   prev = NULL;
  298.   while (p && p != b) {
  299.     prev = p;
  300.     p = p->next;
  301.   }
  302.   if (!p || p->free || p->reserved) {
  303.      if (!p)
  304. fprintf(stderr, "block not found in heapn");
  305.      else if (p->free)
  306. fprintf(stderr, "block already freen");
  307.      else
  308. fprintf(stderr, "block is reservedn");
  309.     return -1;
  310.   }
  311.   p->free = 1;
  312.   Join2Blocks(p);
  313.   if (prev)
  314.     Join2Blocks(prev);
  315.   return 0;
  316. }
  317. int mmReserveMem(memHeap_t *heap, int offset,int size)
  318. {
  319.   int endofs;
  320.   TMemBlock *p;
  321.   if (!heap || size <= 0)
  322.     return -1;
  323.   endofs = offset+size;
  324.   p = (TMemBlock *)heap;
  325.   while (p && p->ofs <= offset) {
  326.     if (ISFREE(p) && endofs <= (p->ofs+p->size)) {
  327.       SliceBlock(p,offset,size,1,1);
  328.       return 0;
  329.     }
  330.     p = p->next;
  331.   }
  332.   return -1;
  333. }
  334. int mmFreeReserved(memHeap_t *heap, int offset)
  335. {
  336.   TMemBlock *p,*prev;
  337.   if (!heap)
  338.     return -1;
  339.   p = (TMemBlock *)heap;
  340.   prev = NULL;
  341.   while (p && p->ofs != offset) {
  342.     prev = p;
  343.     p = p->next;
  344.   }
  345.   if (!p || !p->reserved)
  346.     return -1;
  347.   p->free = 1;
  348.   p->reserved = 0;
  349.   Join2Blocks(p);
  350.   if (prev)
  351.     Join2Blocks(prev);
  352.   return 0;
  353. }
  354. void mmDestroy(memHeap_t *heap)
  355. {
  356.   TMemBlock *p,*q;
  357.   if (!heap)
  358.     return;
  359.   p = (TMemBlock *)heap;
  360.   while (p) {
  361.     q = p->next;
  362.     free(p);
  363.     p = q;
  364.   }
  365. }