patch-2.1.27 linux/drivers/isdn/hisax/buffers.c

Next file: linux/drivers/isdn/hisax/callc.c
Previous file: linux/drivers/isdn/hisax/avm_a1.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.26/linux/drivers/isdn/hisax/buffers.c linux/drivers/isdn/hisax/buffers.c
@@ -0,0 +1,326 @@
+/* $Id: buffers.c,v 1.1 1996/10/13 20:04:49 keil Exp $
+ *
+ * Author       Karsten Keil (keil@temic-ech.spacenet.de)
+ *              based on the teles driver from Jan den Ouden
+ *
+ * Thanks to    Jan den Ouden
+ *              Fritz Elfert
+ *
+ * $Log: buffers.c,v $
+ * Revision 1.1  1996/10/13 20:04:49  keil
+ * Initial revision
+ *
+ *
+ */
+#define __NO_VERSION__
+#include "hisax.h"
+#include <linux/mm.h>
+#include <linux/malloc.h>
+
+#undef SMALLOC_DEBUG
+
+void
+BufPoolInit(struct BufPool *bp, int order, int bpps,
+	    int maxpages)
+{
+#ifdef DEBUG_MAGIC
+	generateerror
+	    bp->magic = 010167;
+#endif
+
+#if 0
+	printk(KERN_DEBUG "BufPoolInit bp %x\n", bp);
+#endif
+
+	bp->freelist = NULL;
+	bp->pageslist = NULL;
+	bp->pageorder = order;
+	bp->pagescount = 0;
+	bp->bpps = bpps;
+	bp->bufsize = BUFFER_SIZE(order, bpps);
+	bp->maxpages = maxpages;
+}
+
+int
+BufPoolAdd(struct BufPool *bp, int priority)
+{
+	struct Pages   *ptr;
+	byte           *bptr;
+	int             i;
+	struct BufHeader *bh = NULL, *prev, *first;
+
+#if 0
+	printk(KERN_DEBUG "BufPoolAdd bp %x\n", bp);
+#endif
+
+	ptr = (struct Pages *) __get_free_pages(priority, bp->pageorder, 0);
+	if (!ptr) {
+		printk(KERN_WARNING "BufPoolAdd couldn't get pages!\n");
+		return (-1);
+	}
+#if 0
+	printk(KERN_DEBUG "Order %d pages allocated at %x\n", bp->pageorder, ptr);
+#endif
+
+	ptr->next = bp->pageslist;
+	bp->pageslist = ptr;
+	bp->pagescount++;
+
+	bptr = (byte *) ptr + sizeof(struct Pages *);
+
+	i = bp->bpps;
+	first = (struct BufHeader *) bptr;
+	prev = NULL;
+	while (i--) {
+		bh = (struct BufHeader *) bptr;
+#ifdef DEBUG_MAGIC
+		bh->magic = 020167;
+#endif
+		bh->next = prev;
+		prev = bh;
+		bh->bp = bp;
+		bptr += PART_SIZE(bp->pageorder, bp->bpps);
+	}
+
+	first->next = bp->freelist;
+	bp->freelist = bh;
+	return (0);
+}
+
+void
+BufPoolFree(struct BufPool *bp)
+{
+	struct Pages   *p;
+
+#if 0
+	printk(KERN_DEBUG "BufPoolFree bp %x\n", bp);
+#endif
+
+	while (bp->pagescount--) {
+		p = bp->pageslist->next;
+		free_pages((unsigned long) bp->pageslist, bp->pageorder);
+#if 0
+		printk(KERN_DEBUG "Free pages %x order %d\n", bp->pageslist, bp->pageorder);
+#endif
+		bp->pageslist = p;
+	}
+}
+
+int
+BufPoolGet(struct BufHeader **bh,
+	   struct BufPool *bp, int priority, void *heldby, int where)
+{
+	long            flags;
+	int             i;
+
+#ifdef DEBUG_MAGIC
+	if (bp->magic != 010167) {
+		printk(KERN_DEBUG "BufPoolGet: not a BufHeader\n");
+		return (-1);
+	}
+#endif
+
+	save_flags(flags);
+	cli();
+	i = 0;
+	while (!0) {
+		if (bp->freelist) {
+			*bh = bp->freelist;
+			bp->freelist = bp->freelist->next;
+			(*bh)->heldby = heldby;
+			(*bh)->where = where;
+			restore_flags(flags);
+			return (0);
+		}
+		if ((i == 0) && (bp->pagescount < bp->maxpages)) {
+                        if (BufPoolAdd(bp, priority)) {
+                                restore_flags(flags);
+                                return -1;
+                        }
+			i++;
+		} else {
+			*bh = NULL;
+			restore_flags(flags);
+			return (-1);
+		}
+	}
+
+}
+
+void
+BufPoolRelease(struct BufHeader *bh)
+{
+	struct BufPool *bp;
+	long            flags;
+
+#ifdef DEBUG_MAGIC
+	if (bh->magic != 020167) {
+		printk(KERN_DEBUG "BufPoolRelease: not a BufHeader\n");
+		printk(KERN_DEBUG "called from %x\n", __builtin_return_address(0));
+		return;
+	}
+#endif
+
+	bp = bh->bp;
+
+#ifdef DEBUG_MAGIC
+	if (bp->magic != 010167) {
+		printk(KERN_DEBUG "BufPoolRelease: not a BufPool\n");
+		return;
+	}
+#endif
+
+	save_flags(flags);
+	cli();
+	bh->next = bp->freelist;
+	bp->freelist = bh;
+	restore_flags(flags);
+}
+
+void
+BufQueueLink(struct BufQueue *bq,
+	     struct BufHeader *bh)
+{
+	unsigned long   flags;
+
+	save_flags(flags);
+	cli();
+	if (!bq->head)
+		bq->head = bh;
+	if (bq->tail)
+		bq->tail->next = bh;
+	bq->tail = bh;
+	bh->next = NULL;
+	restore_flags(flags);
+}
+
+void
+BufQueueLinkFront(struct BufQueue *bq,
+		  struct BufHeader *bh)
+{
+	unsigned long   flags;
+
+	save_flags(flags);
+	cli();
+	bh->next = bq->head;
+	bq->head = bh;
+	if (!bq->tail)
+		bq->tail = bh;
+	restore_flags(flags);
+}
+
+int
+BufQueueUnlink(struct BufHeader **bh, struct BufQueue *bq)
+{
+	long            flags;
+
+	save_flags(flags);
+	cli();
+
+	if (bq->head) {
+		if (bq->tail == bq->head)
+			bq->tail = NULL;
+		*bh = bq->head;
+		bq->head = (*bh)->next;
+		restore_flags(flags);
+		return (0);
+	} else {
+		restore_flags(flags);
+		return (-1);
+	}
+}
+
+void
+BufQueueInit(struct BufQueue *bq)
+{
+#ifdef DEBUG_MAGIC
+	bq->magic = 030167;
+#endif
+	bq->head = NULL;
+	bq->tail = NULL;
+}
+
+void
+BufQueueRelease(struct BufQueue *bq)
+{
+	struct BufHeader *bh;
+
+	while (bq->head) {
+		BufQueueUnlink(&bh, bq);
+		BufPoolRelease(bh);
+	}
+}
+
+int
+BufQueueLength(struct BufQueue *bq)
+{
+	int             i = 0;
+	struct BufHeader *bh;
+
+	bh = bq->head;
+	while (bh) {
+		i++;
+		bh = bh->next;
+	}
+	return (i);
+}
+
+void
+BufQueueDiscard(struct BufQueue *q, int pr, void *heldby,
+		int releasetoo)
+{
+	long            flags;
+	struct BufHeader *sp;
+
+	save_flags(flags);
+	cli();
+
+	while (!0) {
+		sp = q->head;
+		if (!sp)
+			break;
+		if ((sp->primitive == pr) && (sp->heldby == heldby)) {
+			q->head = sp->next;
+			if (q->tail == sp)
+				q->tail = NULL;
+			if (releasetoo)
+				BufPoolRelease(sp);
+		} else
+			break;
+	}
+
+	sp = q->head;
+	if (sp)
+		while (sp->next) {
+			if ((sp->next->primitive == pr) && (sp->next->heldby == heldby)) {
+				if (q->tail == sp->next)
+					q->tail = sp;
+				if (releasetoo)
+					BufPoolRelease(sp->next);
+				sp->next = sp->next->next;
+			} else
+				sp = sp->next;
+		}
+	restore_flags(flags);
+}
+
+void
+Sfree(byte * ptr)
+{
+#ifdef SMALLOC_DEBUG
+	printk(KERN_DEBUG "Sfree %x\n", (unsigned int)ptr);
+#endif
+	kfree(ptr);
+}
+
+byte           *
+Smalloc(int size, int pr, char *why)
+{
+	byte           *p;
+
+	p = (byte *) kmalloc(size, pr);
+#ifdef SMALLOC_DEBUG
+	printk(KERN_DEBUG "Smalloc %s size %d res %x\n", why, size, (unsigned int)p);
+#endif
+	return (p);
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov