source: sbliveos2/trunk/sblive/emuadxmg.c@ 144

Last change on this file since 144 was 142, checked in by ktk, 25 years ago

Import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.1 KB
Line 
1/* $Id: emuadxmg.c 142 2000-04-23 14:55:46Z ktk $ */
2
3
4/*
5 **********************************************************************
6 * emuadxmg.c - Address space manager for emu10k1 driver
7 * Copyright 1999, 2000 Creative Labs, Inc.
8 *
9 **********************************************************************
10 *
11 * Date Author Summary of changes
12 * ---- ------ ------------------
13 * October 20, 1999 Bertrand Lee base code release
14 *
15 **********************************************************************
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public
28 * License along with this program; if not, write to the Free
29 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
30 * USA.
31 *
32 **********************************************************************
33 */
34
35#include "hwaccess.h"
36
37/* Allocates emu address space */
38
39int emu10k1_addxmgr_alloc(u32 size, struct emu10k1_card *card)
40{
41 u16 *pagetable = card->emupagetable;
42 u16 index = 0;
43 u16 numpages;
44 unsigned long flags;
45
46 /* Convert bytes to pages */
47 numpages = (size / EMUPAGESIZE) + ((size % EMUPAGESIZE) ? 1 : 0);
48
49 while (index < (MAXPAGES - RESERVED - 1)) {
50 if (pagetable[index] & 0x8000) {
51 /* This block of pages is in use, jump to the start of the next block. */
52 index += (pagetable[index] & 0x7fff);
53 } else {
54 /* Found free block */
55 if (pagetable[index] >= numpages) {
56 spin_lock_irqsave(&card->lock, flags);
57
58 /* Block is large enough */
59
60 /* If free block is larger than the block requested
61 * then adjust the size of the block remaining */
62 if (pagetable[index] > numpages)
63 pagetable[index + numpages] = pagetable[index] - numpages;
64
65 pagetable[index] = (numpages | 0x8000); /* Mark block as used */
66
67 spin_unlock_irqrestore(&card->lock, flags);
68
69 return index;
70 } else {
71 /* Block too small, jump to the start of the next block */
72 index += pagetable[index];
73 }
74 }
75 }
76
77 return -1;
78}
79
80/* Frees a previously allocated emu address space. */
81
82void emu10k1_addxmgr_free(struct emu10k1_card *card, int index)
83{
84 u16 *pagetable = card->emupagetable;
85 u16 origsize = 0;
86 unsigned long flags;
87
88 spin_lock_irqsave(&card->lock, flags);
89
90 if (pagetable[index] & 0x8000) {
91 /* Block is allocated - mark block as free */
92 origsize = pagetable[index] & 0x7fff;
93 pagetable[index] = origsize;
94
95 /* If next block is free, we concat both blocks */
96 if (!(pagetable[index + origsize] & 0x8000))
97 pagetable[index] += pagetable[index + origsize] & 0x7fff;
98 }
99
100 spin_unlock_irqrestore(&card->lock, flags);
101
102 return;
103}
Note: See TracBrowser for help on using the repository browser.