linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Missing m8260_cpm_dpfree()
@ 2005-05-16 15:15 Alex Zeffertt
  2005-05-16 15:39 ` Wolfgang Denk
  2005-05-18  9:28 ` Alex Zeffertt
  0 siblings, 2 replies; 5+ messages in thread
From: Alex Zeffertt @ 2005-05-16 15:15 UTC (permalink / raw)
  To: linuxppc-embedded

Hi all,

I have a question about the MPC8260 dual port RAM allocation routines.

In arch/ppc/8260_io/commproc.c this is a  m8260_cpm_dpalloc() routine,
but the m8260_cpm_dpfree() routine is missing.  Does anybody know where
I can find this?

I am using denx's linuxppc_2_4_devel tree from 2005-03-06.

TIA,

Alex

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Missing m8260_cpm_dpfree()
  2005-05-16 15:15 Missing m8260_cpm_dpfree() Alex Zeffertt
@ 2005-05-16 15:39 ` Wolfgang Denk
  2005-05-16 16:25   ` Kumar Gala
  2005-05-18  9:28 ` Alex Zeffertt
  1 sibling, 1 reply; 5+ messages in thread
From: Wolfgang Denk @ 2005-05-16 15:39 UTC (permalink / raw)
  To: Alex Zeffertt; +Cc: linuxppc-embedded

In message <20050516161503.0081b1b0.ajz@cambridgebroadband.com> you wrote:
> 
> I have a question about the MPC8260 dual port RAM allocation routines.
> 
> In arch/ppc/8260_io/commproc.c this is a  m8260_cpm_dpalloc() routine,
> but the m8260_cpm_dpfree() routine is missing.  Does anybody know where
> I can find this?

It was never implemented.

We added this in the context of the 8xx tree, and submitted  it  here
at least twice. The patches were never accepted for the publich sourc
trees,  so  we  stopped  wasting  our  time on this. I think Pantelis
Antoniou (?) submitted similar code later, but I don't remember  what
happened to it.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Good manners are the settled  medium  of  social,  as  specie  is  of
commercial, life; returns are equally expected for both.
           - Lord Chesterfield _Letters to his Son_, 25 December 1753

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Missing m8260_cpm_dpfree()
  2005-05-16 15:39 ` Wolfgang Denk
@ 2005-05-16 16:25   ` Kumar Gala
  0 siblings, 0 replies; 5+ messages in thread
From: Kumar Gala @ 2005-05-16 16:25 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-embedded

On May 16, 2005, at 10:39 AM, Wolfgang Denk wrote:

> In message <20050516161503.0081b1b0.ajz@cambridgebroadband.com> you=20
> wrote:
>  >
> > I have a question about the MPC8260 dual port RAM allocation=20
> routines.
>  >
> > In arch/ppc/8260_io/commproc.c this is a=A0 m8260_cpm_dpalloc()=20
> routine,
>  > but the m8260_cpm_dpfree() routine is missing.=A0 Does anybody know=20=

> where
>  > I can find this?
>
> It was never implemented.
>
> We added this in the context of the 8xx tree, and submitted=A0 it=A0 =
here
>  at least twice. The patches were never accepted for the publich sourc
>  trees,=A0 so=A0 we=A0 stopped=A0 wasting=A0 our=A0 time on this. I =
think Pantelis
>  Antoniou (?) submitted similar code later, but I don't remember=A0 =
what
>  happened to it.

The 2.6 kernel has a better set of functions around managing cpm memory=20=

based on changes from Pantelis.

- kumar

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Missing m8260_cpm_dpfree()
  2005-05-16 15:15 Missing m8260_cpm_dpfree() Alex Zeffertt
  2005-05-16 15:39 ` Wolfgang Denk
@ 2005-05-18  9:28 ` Alex Zeffertt
  2005-06-02 13:56   ` Alex Zeffertt
  1 sibling, 1 reply; 5+ messages in thread
From: Alex Zeffertt @ 2005-05-18  9:28 UTC (permalink / raw)
  To: Alex Zeffertt; +Cc: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 720 bytes --]

Hi,

I'm replying to my own message.  I've got around to porting the 8xx
version of ...cpm_dpfree() to the 8260 now.  I've attached the patch
on the off chance anyone else might want it.  The patch is against the
2005-03-06 version of denx's linuxppc_2_4_devel, which is a 2.4.25
kernel.

Alex

On Mon, 16 May 2005 16:15:03 +0100
Alex Zeffertt <ajz@cambridgebroadband.com> wrote:

> Hi all,
> 
> I have a question about the MPC8260 dual port RAM allocation routines.
> 
> In arch/ppc/8260_io/commproc.c this is a  m8260_cpm_dpalloc() routine,
> but the m8260_cpm_dpfree() routine is missing.  Does anybody know
> where I can find this?
> 
> I am using denx's linuxppc_2_4_devel tree from 2005-03-06.
> 
> TIA,
> 
> Alex

[-- Attachment #2: linux-m8260_cpm_dpfree.patch --]
[-- Type: application/octet-stream, Size: 8053 bytes --]

--- linux-2.4.25.orig/include/asm-ppc/cpm_8260.h	2003-10-30 00:34:05.000000000 +0000
+++ linux-2.4.25/include/asm-ppc/cpm_8260.h	2005-05-17 12:12:05.000000000 +0100
@@ -101,6 +101,7 @@
  */
 extern	cpm8260_t	*cpmp;		/* Pointer to comm processor */
 uint		m8260_cpm_dpalloc(uint size, uint align);
+int 		m8260_cpm_dpfree(uint start_addr);
 uint		m8260_cpm_hostalloc(uint size, uint align);
 void		m8260_cpm_setbrg(uint brg, uint rate);
 void		m8260_cpm_fastbrg(uint brg, uint rate, int div16);
--- linux-2.4.25.orig/arch/ppc/kernel/ppc_ksyms.c	2004-06-09 18:00:45.000000000 +0100
+++ linux-2.4.25/arch/ppc/kernel/ppc_ksyms.c	2005-05-17 12:10:01.000000000 +0100
@@ -381,6 +381,7 @@
 #ifdef CONFIG_8260
 EXPORT_SYMBOL(cpmp);
 EXPORT_SYMBOL(m8260_cpm_dpalloc);
+EXPORT_SYMBOL(m8260_cpm_dpfree);
 EXPORT_SYMBOL(m8260_cpm_hostalloc);
 #endif /* CONFIG_8260 */
 
--- linux-2.4.25.orig/arch/ppc/8260_io/commproc.c	2003-10-30 00:32:09.000000000 +0000
+++ linux-2.4.25/arch/ppc/8260_io/commproc.c	2005-05-18 10:08:36.000000000 +0100
@@ -29,12 +29,263 @@
 #include <asm/immap_8260.h>
 #include <asm/cpm_8260.h>
 
+#define DPFREE
+
+#ifdef DPFREE
+typedef struct	cpm_dpalloc_entry_s {
+	u_short				start_addr;
+    u_short             retloc;    /* This is start_addr + alignment offset: only valid in alloc list */
+	u_short				size;
+	struct	cpm_dpalloc_entry_s *	next_entr;
+} cpm_dpalloc_entry_t;
+
+static	void	cpm_dpalloc_init(void);
+static	void	cpm_dpalloc_data_init(cpm_dpalloc_entry_t  *);
+static	int	    cpm_dpalloc_cl(cpm_dpalloc_entry_t *);
+static	int  	cpm_dpalloc_rem(cpm_dpalloc_entry_t **, cpm_dpalloc_entry_t *);
+static	void	cpm_dpalloc_ins(cpm_dpalloc_entry_t **, cpm_dpalloc_entry_t *);
+# define CPM_DPALLOC_COUNT (CPM_DATAONLY_SIZE / sizeof(cbd_t) + 1)  
+/* Dynamic lists of allocated and free DPRAM */
+static	cpm_dpalloc_entry_t  *cpm_dpalloc_free;
+static	cpm_dpalloc_entry_t  *cpm_dpalloc_alloc;
+static	cpm_dpalloc_entry_t	cpm_dpalloc_list[CPM_DPALLOC_COUNT];
+#else
 static	uint	dp_alloc_base;	/* Starting offset in DP ram */
 static	uint	dp_alloc_top;	/* Max offset + 1 */
+#endif
 static	uint	host_buffer;	/* One page of host buffer */
 static	uint	host_end;	/* end + 1 */
 cpm8260_t	*cpmp;		/* Pointer to comm processor space */
 
+#ifdef DPFREE
+/* Initialize dynamic lists
+ */
+static void cpm_dpalloc_init(void)
+{
+	int i;
+
+	cpm_dpalloc_free = cpm_dpalloc_list;
+	cpm_dpalloc_free->start_addr = CPM_DATAONLY_BASE;
+	cpm_dpalloc_free->size = CPM_DATAONLY_SIZE;
+	cpm_dpalloc_free->next_entr = NULL;
+	cpm_dpalloc_alloc = NULL;
+
+	for(i = 1; i <= CPM_DPALLOC_COUNT; i++) {
+		cpm_dpalloc_data_init (cpm_dpalloc_list + i);
+	}
+}
+
+/* Initialize element in list of DPRAM
+ */
+static void cpm_dpalloc_data_init(cpm_dpalloc_entry_t * ptr)
+{
+	ptr->retloc = ptr->start_addr = 0;
+	ptr->size = 0;
+	ptr->next_entr = NULL;
+}
+
+static int cpm_dpalloc_cl(cpm_dpalloc_entry_t * head)
+{
+	cpm_dpalloc_entry_t	* curr;
+	cpm_dpalloc_entry_t	* next;
+	int			  retloc;
+
+	curr = head;
+	retloc = -1;
+
+	if (curr) {
+		retloc = 0;
+
+		while ((next = curr->next_entr)) {
+			if (curr->start_addr + curr->size == next->start_addr) {
+				curr->size = curr->size + next->size;
+				curr->next_entr = next->next_entr;
+				cpm_dpalloc_data_init(next);
+			} else {
+				curr = next;
+			}
+		 }
+	}
+
+	return retloc;
+}
+
+/* Remove element from dynamic list of DPRAM
+ */
+static int cpm_dpalloc_rem(cpm_dpalloc_entry_t ** head, cpm_dpalloc_entry_t * ptr)
+{
+	cpm_dpalloc_entry_t	* prev;
+	cpm_dpalloc_entry_t	* curr;
+	int			  retloc;
+
+	retloc = -1;
+	for (prev = NULL , curr = *head;
+	     curr != NULL && ptr != curr;
+	     prev = curr , curr = curr->next_entr)
+		/* EMPTY */ ;
+
+	if (curr) {
+		if (prev) {
+			prev->next_entr = curr->next_entr;
+		} else {
+			*head = curr->next_entr;
+		}
+		retloc = 0;
+	}
+
+	return retloc;
+}
+
+/* Insert element in dynamic list of DPRAM
+ */
+static void cpm_dpalloc_ins(cpm_dpalloc_entry_t ** head, cpm_dpalloc_entry_t * ptr)
+{
+	cpm_dpalloc_entry_t	* prev;
+	cpm_dpalloc_entry_t	* curr;
+
+	for (prev = NULL , curr = *head;
+	     curr != NULL && ptr->start_addr >= curr->start_addr;
+	     prev = curr , curr = curr->next_entr)
+		/* EMPTY */ ;
+
+	ptr->next_entr = curr;
+
+	if (prev) {
+		prev->next_entr = ptr;
+	} else {
+		*head = ptr;
+	}
+}
+/* Allocate some memory from the dual ported ram.  We may want to
+ * enforce alignment restrictions, but right now everyone is a good
+ * citizen.
+ */
+uint m8260_cpm_dpalloc(uint size, uint align)
+{
+	cpm_dpalloc_entry_t   * new_el;
+	cpm_dpalloc_entry_t   * p;
+	cpm_dpalloc_entry_t   * p1;
+	uint			retloc;
+	u_short			max;
+	unsigned long		flags;
+	int			i;
+    uint align_mask;
+    uint off;
+
+	size = (size + 7) & ~7;
+    align_mask = align - 1;
+	max = CPM_DATAONLY_SIZE;
+	retloc = 0;
+	new_el = NULL;
+
+	if (size == 0) goto DONE;
+
+	save_flags(flags);
+	cli();
+
+	/* Find free area in DPRAM
+	*/
+	for (p = cpm_dpalloc_free; p != NULL; p = p->next_entr) {
+		if (p->size <= max) {
+            off = ((p->start_addr + align_mask) & (~align_mask)) - p->start_addr;
+            if (p->size >= size + off) {
+                new_el = p;
+                max = p->size;
+                retloc = p->start_addr + off;
+            }
+		}
+	}
+
+	if (new_el == NULL) goto DONE1;
+
+	/* Insert new element in the list of allocated DPRAM
+	*/
+	p1 = cpm_dpalloc_list;
+	p = NULL;
+	i = 0;
+	while (i < CPM_DPALLOC_COUNT) {
+		if (p1->start_addr == 0 && !p1->size && !p1->next_entr) {
+			p = p1;
+			break;
+		}
+		i ++;
+		p1 ++;
+	}
+
+	if (p == NULL) {
+		panic ("m8xx_cpm_dpalloc: INTERNAL ERROR\n");
+	}
+
+	p->start_addr = new_el->start_addr;
+	p->retloc = retloc;
+	p->size = size;
+
+    off = retloc - new_el->start_addr;
+	if (new_el->size >  (size+off)) {
+		new_el->size -= (size+off);
+		new_el->start_addr += (size+off);
+		cpm_dpalloc_ins(&cpm_dpalloc_alloc, p);
+	} else {
+		cpm_dpalloc_ins(&cpm_dpalloc_alloc, p);
+		i = cpm_dpalloc_rem(&cpm_dpalloc_free, new_el);
+
+		if ( i == -1) {
+			panic ("m8xx_cpm_dpalloc: INTERNAL ERROR\n");
+		}
+
+		cpm_dpalloc_data_init(new_el);
+	}
+
+DONE1:
+	restore_flags(flags);
+DONE:
+    if (jiffies > 10*HZ)
+        printk("%s(%u,%u) = 0x%x\n",__FUNCTION__,size,align,retloc);
+	return retloc;
+}
+
+int m8260_cpm_dpfree(uint retloc)
+{
+	cpm_dpalloc_entry_t   * r;
+	int			retval;
+	unsigned long		flags;
+
+	retval = -1;
+
+	if ((retloc < CPM_DATAONLY_BASE) ||
+	    (retloc > CPM_DATAONLY_SIZE + CPM_DATAONLY_BASE)) {
+		goto DONE;
+	}
+
+	save_flags(flags);
+	cli();
+
+	for (r = cpm_dpalloc_alloc;
+	     (r != NULL) && (r->retloc != retloc);
+	     r = r->next_entr)
+		/* EMPTY */ ;
+
+	if (r) {
+		retval = cpm_dpalloc_rem(&cpm_dpalloc_alloc, r);
+
+		if (retval == -1) {
+			panic("m8xx_cpm_dpfree: INTERNAL ERROR\n");
+		}
+		cpm_dpalloc_ins(&cpm_dpalloc_free, r);
+		retval = cpm_dpalloc_cl(cpm_dpalloc_free);
+
+		if (retval == -1) {
+			panic("m8xx_cpm_dpfree: INTERNAL ERROR\n");
+		}
+		retval = 0;
+	}
+
+	restore_flags(flags);
+DONE:
+	return retval;
+}
+#endif /* DPFREE */
+
 /* We allocate this here because it is used almost exclusively for
  * the communication processor devices.
  */
@@ -50,11 +301,14 @@
 	immr = imp = (volatile immap_t *)IMAP_ADDR;
 	commproc = &imp->im_cpm;
 
+#ifdef DPFREE
+	cpm_dpalloc_init();
+#else
 	/* Reclaim the DP memory for our use.
 	*/
 	dp_alloc_base = CPM_DATAONLY_BASE;
 	dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
-
+#endif
 	/* Set the host page for allocation.
 	*/
 	host_buffer =
@@ -68,6 +322,7 @@
 	cpmp = (cpm8260_t *)commproc;
 }
 
+#ifndef DPFREE
 /* Allocate some memory from the dual ported ram.
  * To help protocols with object alignment restrictions, we do that
  * if they ask.
@@ -95,6 +350,12 @@
 
 	return(retloc);
 }
+int m8260_cpm_dpfree(uint start_addr)
+{
+    printk(KERN_ERR "%s() not implemented\n", __FUNCTION__);
+    return -1;
+}
+#endif /*ifndef DPFREE*/
 
 /* We also own one page of host buffer space for the allocation of
  * UART "fifos" and the like.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Missing m8260_cpm_dpfree()
  2005-05-18  9:28 ` Alex Zeffertt
@ 2005-06-02 13:56   ` Alex Zeffertt
  0 siblings, 0 replies; 5+ messages in thread
From: Alex Zeffertt @ 2005-06-02 13:56 UTC (permalink / raw)
  To: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 1022 bytes --]

Hi,

A while ago I posted a patch which added the m8260_cpm_dpfree()
function.  I've just noticed a bug in this which is fixed in the
attached patch.

Alex

On Wed, 18 May 2005 10:28:14 +0100
Alex Zeffertt <ajz@cambridgebroadband.com> wrote:

> Hi,
> 
> I'm replying to my own message.  I've got around to porting the 8xx
> version of ...cpm_dpfree() to the 8260 now.  I've attached the patch
> on the off chance anyone else might want it.  The patch is against the
> 2005-03-06 version of denx's linuxppc_2_4_devel, which is a 2.4.25
> kernel.
> 
> Alex
> 
> On Mon, 16 May 2005 16:15:03 +0100
> Alex Zeffertt <ajz@cambridgebroadband.com> wrote:
> 
> > Hi all,
> > 
> > I have a question about the MPC8260 dual port RAM allocation
> > routines.
> > 
> > In arch/ppc/8260_io/commproc.c this is a  m8260_cpm_dpalloc()
> > routine, but the m8260_cpm_dpfree() routine is missing.  Does
> > anybody know where I can find this?
> > 
> > I am using denx's linuxppc_2_4_devel tree from 2005-03-06.
> > 
> > TIA,
> > 
> > Alex
> 

[-- Attachment #2: linux-m8260_cpm_dpfree.patch-2 --]
[-- Type: application/octet-stream, Size: 7423 bytes --]

--- linux-2.4.25.orig/arch/ppc/8260_io/commproc.c	2003-10-30 00:32:09.000000000 +0000
+++ linux-2.4.25/arch/ppc/8260_io/commproc.c	2005-06-02 14:47:16.000000000 +0100
@@ -29,12 +29,264 @@
 #include <asm/immap_8260.h>
 #include <asm/cpm_8260.h>
 
+#define DPFREE
+
+#ifdef DPFREE
+typedef struct	cpm_dpalloc_entry_s {
+	u_short				start_addr;
+    u_short             retloc;    /* This is start_addr + alignment offset: only valid in alloc list */
+	u_short				size;
+	struct	cpm_dpalloc_entry_s *	next_entr;
+} cpm_dpalloc_entry_t;
+
+static	void	cpm_dpalloc_init(void);
+static	void	cpm_dpalloc_data_init(cpm_dpalloc_entry_t  *);
+static	int	    cpm_dpalloc_cl(cpm_dpalloc_entry_t *);
+static	int  	cpm_dpalloc_rem(cpm_dpalloc_entry_t **, cpm_dpalloc_entry_t *);
+static	void	cpm_dpalloc_ins(cpm_dpalloc_entry_t **, cpm_dpalloc_entry_t *);
+# define CPM_DPALLOC_COUNT (CPM_DATAONLY_SIZE / sizeof(cbd_t) + 1)  
+/* Dynamic lists of allocated and free DPRAM */
+static	cpm_dpalloc_entry_t  *cpm_dpalloc_free;
+static	cpm_dpalloc_entry_t  *cpm_dpalloc_alloc;
+static	cpm_dpalloc_entry_t	cpm_dpalloc_list[CPM_DPALLOC_COUNT];
+#else
 static	uint	dp_alloc_base;	/* Starting offset in DP ram */
 static	uint	dp_alloc_top;	/* Max offset + 1 */
+#endif
 static	uint	host_buffer;	/* One page of host buffer */
 static	uint	host_end;	/* end + 1 */
 cpm8260_t	*cpmp;		/* Pointer to comm processor space */
 
+#ifdef DPFREE
+/* Initialize dynamic lists
+ */
+static void cpm_dpalloc_init(void)
+{
+	int i;
+
+	cpm_dpalloc_free = cpm_dpalloc_list;
+	cpm_dpalloc_free->start_addr = CPM_DATAONLY_BASE;
+	cpm_dpalloc_free->size = CPM_DATAONLY_SIZE;
+	cpm_dpalloc_free->next_entr = NULL;
+	cpm_dpalloc_alloc = NULL;
+
+	for(i = 1; i <= CPM_DPALLOC_COUNT; i++) {
+		cpm_dpalloc_data_init (cpm_dpalloc_list + i);
+	}
+}
+
+/* Initialize element in list of DPRAM
+ */
+static void cpm_dpalloc_data_init(cpm_dpalloc_entry_t * ptr)
+{
+	ptr->retloc = ptr->start_addr = 0;
+	ptr->size = 0;
+	ptr->next_entr = NULL;
+}
+
+static int cpm_dpalloc_cl(cpm_dpalloc_entry_t * head)
+{
+	cpm_dpalloc_entry_t	* curr;
+	cpm_dpalloc_entry_t	* next;
+	int			  retloc;
+
+	curr = head;
+	retloc = -1;
+
+	if (curr) {
+		retloc = 0;
+
+		while ((next = curr->next_entr)) {
+			if (curr->start_addr + curr->size == next->start_addr) {
+				curr->size = curr->size + next->size;
+				curr->next_entr = next->next_entr;
+				cpm_dpalloc_data_init(next);
+			} else {
+				curr = next;
+			}
+		 }
+	}
+
+	return retloc;
+}
+
+/* Remove element from dynamic list of DPRAM
+ */
+static int cpm_dpalloc_rem(cpm_dpalloc_entry_t ** head, cpm_dpalloc_entry_t * ptr)
+{
+	cpm_dpalloc_entry_t	* prev;
+	cpm_dpalloc_entry_t	* curr;
+	int			  retloc;
+
+	retloc = -1;
+	for (prev = NULL , curr = *head;
+	     curr != NULL && ptr != curr;
+	     prev = curr , curr = curr->next_entr)
+		/* EMPTY */ ;
+
+	if (curr) {
+		if (prev) {
+			prev->next_entr = curr->next_entr;
+		} else {
+			*head = curr->next_entr;
+		}
+		retloc = 0;
+	}
+
+	return retloc;
+}
+
+/* Insert element in dynamic list of DPRAM
+ */
+static void cpm_dpalloc_ins(cpm_dpalloc_entry_t ** head, cpm_dpalloc_entry_t * ptr)
+{
+	cpm_dpalloc_entry_t	* prev;
+	cpm_dpalloc_entry_t	* curr;
+
+	for (prev = NULL , curr = *head;
+	     curr != NULL && ptr->start_addr >= curr->start_addr;
+	     prev = curr , curr = curr->next_entr)
+		/* EMPTY */ ;
+
+	ptr->next_entr = curr;
+
+	if (prev) {
+		prev->next_entr = ptr;
+	} else {
+		*head = ptr;
+	}
+}
+/* Allocate some memory from the dual ported ram.  We may want to
+ * enforce alignment restrictions, but right now everyone is a good
+ * citizen.
+ */
+uint m8260_cpm_dpalloc(uint size, uint align)
+{
+    cpm_dpalloc_entry_t   * new_el;
+    cpm_dpalloc_entry_t   * p;
+    cpm_dpalloc_entry_t   * p1;
+    uint			retloc;
+    u_short			max;
+    unsigned long		flags;
+    int			i;
+    uint align_mask;
+    uint off;
+
+    size = (size + 7) & ~7;
+    align_mask = align - 1;
+    max = CPM_DATAONLY_SIZE;
+    retloc = 0;
+    new_el = NULL;
+
+    if (size == 0) goto DONE;
+
+    save_flags(flags);
+    cli();
+
+    /* Find free area in DPRAM
+     */
+    for (p = cpm_dpalloc_free; p != NULL; p = p->next_entr) {
+        if (p->size <= max) {
+            off = ((p->start_addr + align_mask) & (~align_mask)) - p->start_addr;
+            if (p->size >= size + off) {
+                new_el = p;
+                max = p->size;
+                retloc = p->start_addr + off;
+            }
+        }
+    }
+
+    if (new_el == NULL) goto DONE1;
+
+    /* Insert new element in the list of allocated DPRAM
+     */
+    p1 = cpm_dpalloc_list;
+    p = NULL;
+    i = 0;
+    while (i < CPM_DPALLOC_COUNT) {
+        if (p1->start_addr == 0 && !p1->size && !p1->next_entr) {
+            p = p1;
+            break;
+        }
+        i ++;
+        p1 ++;
+    }
+
+    if (p == NULL) {
+        panic ("m8xx_cpm_dpalloc: INTERNAL ERROR\n");
+    }
+
+    off = retloc - new_el->start_addr;
+
+    p->start_addr = new_el->start_addr;
+    p->retloc = retloc;
+    p->size = size + off;
+
+    if (new_el->size >  (size+off)) {
+        new_el->size -= (size+off);
+        new_el->start_addr += (size+off);
+        cpm_dpalloc_ins(&cpm_dpalloc_alloc, p);
+    } else {
+        cpm_dpalloc_ins(&cpm_dpalloc_alloc, p);
+        i = cpm_dpalloc_rem(&cpm_dpalloc_free, new_el);
+
+        if ( i == -1) {
+            panic ("m8xx_cpm_dpalloc: INTERNAL ERROR\n");
+        }
+
+        cpm_dpalloc_data_init(new_el);
+    }
+
+ DONE1:
+    restore_flags(flags);
+ DONE:
+    return retloc;
+}
+
+int m8260_cpm_dpfree(uint retloc)
+{
+	cpm_dpalloc_entry_t   * r;
+	int			retval;
+	unsigned long		flags;
+
+	retval = -1;
+
+	if ((retloc < CPM_DATAONLY_BASE) ||
+	    (retloc > CPM_DATAONLY_SIZE + CPM_DATAONLY_BASE)) {
+		goto DONE;
+	}
+
+	save_flags(flags);
+	cli();
+
+	for (r = cpm_dpalloc_alloc;
+	     (r != NULL) && (r->retloc != retloc);
+	     r = r->next_entr)
+		/* EMPTY */ ;
+
+	if (r) {
+		retval = cpm_dpalloc_rem(&cpm_dpalloc_alloc, r);
+
+		if (retval == -1) {
+			panic("m8xx_cpm_dpfree: INTERNAL ERROR\n");
+		}
+		cpm_dpalloc_ins(&cpm_dpalloc_free, r);
+		retval = cpm_dpalloc_cl(cpm_dpalloc_free);
+
+		if (retval == -1) {
+			panic("m8xx_cpm_dpfree: INTERNAL ERROR\n");
+		}
+		retval = 0;
+	} else {
+	  printk(KERN_ERR "m8xx_cpm_dpfree: address not found in alloc list\n");
+	}
+
+	restore_flags(flags);
+DONE:
+	return retval;
+}
+#endif /* DPFREE */
+
 /* We allocate this here because it is used almost exclusively for
  * the communication processor devices.
  */
@@ -50,11 +302,14 @@
 	immr = imp = (volatile immap_t *)IMAP_ADDR;
 	commproc = &imp->im_cpm;
 
+#ifdef DPFREE
+	cpm_dpalloc_init();
+#else
 	/* Reclaim the DP memory for our use.
 	*/
 	dp_alloc_base = CPM_DATAONLY_BASE;
 	dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
-
+#endif
 	/* Set the host page for allocation.
 	*/
 	host_buffer =
@@ -68,6 +323,7 @@
 	cpmp = (cpm8260_t *)commproc;
 }
 
+#ifndef DPFREE
 /* Allocate some memory from the dual ported ram.
  * To help protocols with object alignment restrictions, we do that
  * if they ask.
@@ -95,6 +351,12 @@
 
 	return(retloc);
 }
+int m8260_cpm_dpfree(uint start_addr)
+{
+    printk(KERN_ERR "%s() not implemented\n", __FUNCTION__);
+    return -1;
+}
+#endif /*ifndef DPFREE*/
 
 /* We also own one page of host buffer space for the allocation of
  * UART "fifos" and the like.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-06-02 13:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-16 15:15 Missing m8260_cpm_dpfree() Alex Zeffertt
2005-05-16 15:39 ` Wolfgang Denk
2005-05-16 16:25   ` Kumar Gala
2005-05-18  9:28 ` Alex Zeffertt
2005-06-02 13:56   ` Alex Zeffertt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).