[PATCH 05/26] leon, gr1553b: Only align allocated memory. Verify alignment of memory.

Daniel Hellstrom daniel at gaisler.com
Mon Jun 29 11:27:52 UTC 2020


From: Arvid Bjorkengren <arvid at gaisler.com>

---
 bsps/shared/grlib/1553/gr1553bc.c |  76 ++++++++++++++++-----------
 bsps/shared/grlib/1553/gr1553bm.c |  49 ++++++++++++------
 bsps/shared/grlib/1553/gr1553rt.c | 105 ++++++++++++++++++++++++--------------
 3 files changed, 147 insertions(+), 83 deletions(-)

diff --git a/bsps/shared/grlib/1553/gr1553bc.c b/bsps/shared/grlib/1553/gr1553bc.c
index a22e2d8..f37364e 100644
--- a/bsps/shared/grlib/1553/gr1553bc.c
+++ b/bsps/shared/grlib/1553/gr1553bc.c
@@ -63,7 +63,7 @@ struct gr1553bc_priv {
  */
 #define NEXT_MINOR_MARKER 0x01
 
-/* To separate ASYNC list from SYNC list we mark them differently, but with 
+/* To separate ASYNC list from SYNC list we mark them differently, but with
  * LSB always set. This can be used to get the list the descriptor is a part
  * of.
  */
@@ -71,7 +71,7 @@ struct gr1553bc_priv {
 
 struct gr1553bc_list_cfg gr1553bc_def_cfg =
 {
-	.rt_timeout = 
+	.rt_timeout =
 		{
 			20, 20, 20, 20,
 			20, 20, 20, 20,
@@ -80,7 +80,7 @@ struct gr1553bc_list_cfg gr1553bc_def_cfg =
 			20, 20, 20, 20,
 			20, 20, 20, 20,
 			20, 20, 20, 20,
-			20, 20, 20			
+			20, 20, 20
 		},
 	.bc_timeout = 30,
 	.tropt_irq_on_err = 0,
@@ -132,7 +132,7 @@ int gr1553bc_list_config
 
 	/* RT Time Tolerances */
 	for (i=0; i<31; i++) {
-		/* 0=14us, 1=18us ... 0xf=74us 
+		/* 0=14us, 1=18us ... 0xf=74us
 		 * round upwards: 15us will be 18us
 		 */
 		timeout = ((cfg->rt_timeout[i] + 1)  - 14) / 4;
@@ -167,7 +167,7 @@ void gr1553bc_list_link_major(
 	if ( major ) {
 		major->next = next;
 		if ( next ) {
-			major->minors[major->cfg->minor_cnt-1]->next = 
+			major->minors[major->cfg->minor_cnt-1]->next =
 				next->minors[0];
 		} else {
 			major->minors[major->cfg->minor_cnt-1]->next = NULL;
@@ -195,7 +195,7 @@ int gr1553bc_list_set_major(
 		prev = list->majors[list->major_cnt-1];
 	}
 
-	/* Link to next Major if not the last one and if there is 
+	/* Link to next Major if not the last one and if there is
 	 * a next major
 	 */
 	if ( no == list->major_cnt-1 ) {
@@ -262,7 +262,7 @@ int gr1553bc_list_table_size(struct gr1553bc_list *list)
 		minor_cnt = major->cfg->minor_cnt;
 		for (j=0; j<minor_cnt; j++) {
 			/* 128-bit Alignment required by HW */
-			size += (GR1553BC_BD_ALIGN - 
+			size += (GR1553BC_BD_ALIGN -
 				(size & (GR1553BC_BD_ALIGN-1))) &
 				~(GR1553BC_BD_ALIGN-1);
 
@@ -284,6 +284,7 @@ int gr1553bc_list_table_alloc
 	int i, j, minor_cnt, size;
 	unsigned int table;
 	struct gr1553bc_priv *bcpriv = list->bc;
+	int retval = 0;
 
 	/* Free previous allocated descriptor table */
 	gr1553bc_list_table_free(list);
@@ -298,8 +299,8 @@ int gr1553bc_list_table_alloc
 		/* Address given in Hardware accessible address, we
 		 * convert it into CPU-accessible address.
 		 */
-		list->table_hw = (unsigned int)bdtab_custom & ~0x1;
-		list->_table = bdtab_custom;
+		list->_table = (void*)((unsigned int)bdtab_custom & ~0x1);
+		list->table_hw = (unsigned int)list->_table;
 		drvmgr_translate_check(
 			*bcpriv->pdev,
 			DMAMEM_TO_CPU,
@@ -310,16 +311,19 @@ int gr1553bc_list_table_alloc
 		if (bdtab_custom == NULL) {
 			/* Allocate descriptors */
 			list->_table = grlib_malloc(size + (GR1553BC_BD_ALIGN-1));
-			if ( list->_table == NULL )
-				return -1;
+			if ( list->_table == NULL ) {
+				retval = -1;
+				goto err;
+			}
+			/* 128-bit Alignment required by HW */
+			list->table_cpu =
+				(((unsigned int)list->_table + (GR1553BC_BD_ALIGN-1)) &
+				~(GR1553BC_BD_ALIGN-1));
 		} else {
 			/* Custom address, given in CPU-accessible address */
 			list->_table = bdtab_custom;
+			list->table_cpu = (unsigned int)list->_table;
 		}
-		/* 128-bit Alignment required by HW */
-		list->table_cpu =
-			(((unsigned int)list->_table + (GR1553BC_BD_ALIGN-1)) &
-			~(GR1553BC_BD_ALIGN-1));
 
 		/* We got CPU accessible descriptor table address, now we
 		 * translate that into an address that the Hardware can
@@ -338,6 +342,12 @@ int gr1553bc_list_table_alloc
 		}
 	}
 
+	/* Verify alignment */
+	if (list->table_hw & (GR1553BC_BD_ALIGN-1)) {
+		retval = -2;
+		goto err;
+	}
+
 	/* Write End-Of-List all over the descriptor table here,
 	 * For debugging/safety?
 	 */
@@ -359,8 +369,16 @@ int gr1553bc_list_table_alloc
 			table += gr1553bc_minor_table_size(major->minors[j]);
 		}
 	}
-
-	return 0;
+err:
+	if (retval) {
+		if (list->_table_custom == NULL && list->_table) {
+			free(list->_table);
+		}
+		list->table_hw = 0;
+		list->table_cpu = 0;
+		list->_table = NULL;
+	}
+	return retval;
 }
 
 void gr1553bc_list_table_free(struct gr1553bc_list *list)
@@ -399,7 +417,7 @@ int gr1553bc_list_table_build(struct gr1553bc_list *list)
 			bds = minor->bds;
 
 			/* BD[0..SLOTCNT-1] = message slots
-			 * BD[SLOTCNT+0] = END 
+			 * BD[SLOTCNT+0] = END
 			 * BD[SLOTCNT+1] = JUMP
 			 *
 			 * or if no optional time slot handling:
@@ -485,7 +503,7 @@ void gr1553bc_bd_init(
 		     ((word0 & GR1553BC_BD_TYPE) == 0) ) {
 			/* Don't touch timeslot previously allocated */
 			word0 &= ~GR1553BC_TR_TIME;
-			word0 |= GR1553BC_READ_MEM(&raw->words[0]) & 
+			word0 |= GR1553BC_READ_MEM(&raw->words[0]) &
 					GR1553BC_TR_TIME;
 		}
 		GR1553BC_WRITE_MEM(&raw->words[0], word0);
@@ -523,7 +541,7 @@ int gr1553bc_major_alloc_skel
 	maj->cfg = cfg;
 	maj->next = NULL;
 
-	/* Create links between minor frames, and from minor frames 
+	/* Create links between minor frames, and from minor frames
 	 * to configuration structure.
 	 */
 	minor = (struct gr1553bc_minor *)&maj->minors[cfg->minor_cnt];
@@ -697,7 +715,7 @@ int gr1553bc_slot_alloc2(
 			set0 = (set0 & ~GR1553BC_TR_TIME) | timefree;
 			GR1553BC_WRITE_MEM(&trbd->settings[0], set0);
 			/* Note: at the moment the minor frame can be executed faster
-			 *       than expected, we hurry up writing requested 
+			 *       than expected, we hurry up writing requested
 			 *       descriptor.
 			 */
 		}
@@ -886,7 +904,7 @@ int gr1553bc_slot_irq_prepare
 	union gr1553bc_bd *bd;
 	int slot_no, to_mid;
 
-	/* Build unconditional IRQ descriptor. The padding is used 
+	/* Build unconditional IRQ descriptor. The padding is used
 	 * for identifying the MINOR frame and function and custom data.
 	 *
 	 * The IRQ is disabled at first, a unconditional jump to next
@@ -1115,7 +1133,7 @@ int gr1553bc_slot_update
 		*stat = GR1553BC_READ_MEM(&bd->tr.status);
 		if ( status ) {
 			/* Clear status fields user selects, then
-			 * or bit31 if user wants that. The bit31 
+			 * or bit31 if user wants that. The bit31
 			 * may be used to indicate if the BC has
 			 * performed the access.
 			 */
@@ -1192,7 +1210,7 @@ int gr1553bc_mid_from_bd(
 found_mid:
 	/* Get MID of JUMP descriptor */
 	bdmid = word2 >> 8;
-	/* Subtract distance from JUMP descriptor to find MID 
+	/* Subtract distance from JUMP descriptor to find MID
 	 * of requested BD.
 	 */
 	slot_no = GR1553BC_SLOTID_FROM_ID(bdmid);
@@ -1445,7 +1463,7 @@ void gr1553bc_device_init(struct gr1553bc_priv *priv)
 	/* Stop BC if not already stopped */
 	GR1553BC_WRITE_REG(&priv->regs->bc_ctrl, GR1553BC_KEY | 0x0204);
 
-	/* Since RT can not be used at the same time as BC, we stop 
+	/* Since RT can not be used at the same time as BC, we stop
 	 * RT rx, it should already be stopped...
 	 */
 	GR1553BC_WRITE_REG(&priv->regs->rt_cfg, GR1553RT_KEY);
@@ -1463,7 +1481,7 @@ void gr1553bc_device_init(struct gr1553bc_priv *priv)
 	priv->alist = NULL;
 
 	priv->irq_log_base = (uint32_t *)
-		(((uint32_t)priv->irq_log_p + (GR1553BC_IRQLOG_SIZE-1)) & 
+		(((uint32_t)priv->irq_log_p + (GR1553BC_IRQLOG_SIZE-1)) &
 		~(GR1553BC_IRQLOG_SIZE-1));
 	/* Translate into a hardware accessible address */
 	drvmgr_translate_check(
@@ -1487,7 +1505,7 @@ void gr1553bc_device_uninit(struct gr1553bc_priv *priv)
 	/* Stop BC if not already stopped */
 	GR1553BC_WRITE_REG(&priv->regs->bc_ctrl, GR1553BC_KEY | 0x0204);
 
-	/* Since RT can not be used at the same time as BC, we stop 
+	/* Since RT can not be used at the same time as BC, we stop
 	 * RT rx, it should already be stopped...
 	 */
 	GR1553BC_WRITE_REG(&priv->regs->rt_cfg, GR1553RT_KEY);
@@ -1518,7 +1536,7 @@ void gr1553bc_isr(void *arg)
 	/* Clear handled IRQs */
 	GR1553BC_WRITE_REG(&priv->regs->irq, irq);
 
-	/* DMA error. This IRQ does not affect the IRQ log. 
+	/* DMA error. This IRQ does not affect the IRQ log.
 	 * We let standard IRQ handle handle it.
 	 */
 	if ( irq & GR1553B_IRQEN_BCDE ) {
@@ -1563,7 +1581,7 @@ void gr1553bc_isr(void *arg)
 			bd = NULL;
 		}
 
-		/* Handle Descriptor that cased IRQ 
+		/* Handle Descriptor that cased IRQ
 		 *
 		 * If someone have inserted an IRQ descriptor and tied
 		 * that to a custom function we call that function, otherwise
diff --git a/bsps/shared/grlib/1553/gr1553bm.c b/bsps/shared/grlib/1553/gr1553bm.c
index 482e574..0672c46 100644
--- a/bsps/shared/grlib/1553/gr1553bm.c
+++ b/bsps/shared/grlib/1553/gr1553bm.c
@@ -89,7 +89,7 @@ static void gr1553bm_hw_start(struct gr1553bm_priv *priv)
 
 	/* Start logging */
 	priv->regs->bm_ctrl =
-		(priv->cfg.filt_error_options & 
+		(priv->cfg.filt_error_options &
 		(GR1553B_BM_CTRL_MANL|GR1553B_BM_CTRL_UDWL|GR1553B_BM_CTRL_IMCL))
 		| GR1553B_BM_CTRL_BMEN;
 
@@ -178,6 +178,7 @@ void gr1553bm_close(void *bm)
 /* Configure the BM driver */
 int gr1553bm_config(void *bm, struct gr1553bm_config *cfg)
 {
+	int retval = 0;
 	struct gr1553bm_priv *priv = bm;
 
 	if ( priv->started )
@@ -193,12 +194,11 @@ int gr1553bm_config(void *bm, struct gr1553bm_config *cfg)
 	}
 	priv->buffer_size = cfg->buffer_size & ~0x7; /* on 8 byte bounadry */
 	if ((unsigned int)cfg->buffer_custom & 1) {
-		/* Custom Address Given in Remote address. We need
-		 * to convert it intoTranslate into Hardware a
-		 * hardware accessible address
+		/* Custom address given in remote address. We need
+		 * to convert it into a hardware accessible address
 		 */
-		priv->buffer_base_hw = (unsigned int)cfg->buffer_custom & ~1;
-		priv->buffer = cfg->buffer_custom;
+		priv->buffer = (void*)((unsigned int)cfg->buffer_custom & ~1);
+		priv->buffer_base_hw = (unsigned int)priv->buffer;
 		drvmgr_translate_check(
 			*priv->pdev,
 			DMAMEM_TO_CPU,
@@ -209,17 +209,19 @@ int gr1553bm_config(void *bm, struct gr1553bm_config *cfg)
 		if (cfg->buffer_custom == NULL) {
 			/* Allocate new buffer dynamically */
 			priv->buffer = grlib_malloc(priv->buffer_size + 8);
-			if (priv->buffer == NULL)
-				return -1;
+			if (priv->buffer == NULL) {
+				retval = -1;
+				goto err;
+			}
+			/* Align to 8 bytes */
+			priv->buffer_base = ((unsigned int)priv->buffer + (8-1)) & ~(8-1);
 		} else {
 			/* Address given in CPU accessible address, no
 			 * translation required.
 			 */
 			priv->buffer = cfg->buffer_custom;
+			priv->buffer_base = (unsigned int)priv->buffer;
 		}
-		/* Align to 16 bytes */
-		priv->buffer_base = ((unsigned int)priv->buffer + (8-1)) &
-					~(8-1);
 		/* Translate address of buffer base into address that Hardware must
 		 * use to access the buffer.
 		 */
@@ -229,13 +231,28 @@ int gr1553bm_config(void *bm, struct gr1553bm_config *cfg)
 			(void *)priv->buffer_base,
 			(void **)&priv->buffer_base_hw,
 			priv->buffer_size);
-		
+
+	}
+
+	/* Verify alignment */
+	if (priv->buffer_base_hw & (8-1)) {
+		retval = -2;
+		goto err;
 	}
 
 	/* Copy valid config */
 	priv->cfg = *cfg;
 
-	return 0;
+err:
+	if (retval) {
+		if (cfg->buffer_custom == NULL && priv->buffer) {
+			free(priv->buffer);
+		}
+		priv->buffer_base_hw = (unsigned int)NULL;
+		priv->buffer_base = (unsigned int)NULL;
+		priv->buffer = NULL;
+	}
+	return retval;
 }
 
 /* Start logging */
@@ -249,7 +266,7 @@ int gr1553bm_start(void *bm)
 		return -2;
 
 	/* Start at Time = 0 */
-	priv->regs->bm_ttag = 
+	priv->regs->bm_ttag =
 		priv->cfg.time_resolution << GR1553B_BM_TTAG_RES_BIT;
 
 	/* Configure Filters */
@@ -282,7 +299,7 @@ void gr1553bm_stop(void *bm)
 	/* Stop Hardware */
 	gr1553bm_hw_stop(priv);
 
-	/* At this point the hardware must be stopped and IRQ 
+	/* At this point the hardware must be stopped and IRQ
 	 * sources unmasked.
 	 */
 
@@ -331,7 +348,7 @@ resample:
 		hwtime2 = priv->regs->bm_ttag & GR1553B_BM_TTAG_VAL;
 		if ( hwtime > hwtime2 ) {
 			/* priv->time and hwtime may be out of sync if
-			 * IRQ updated priv->time just after bm_ttag was read 
+			 * IRQ updated priv->time just after bm_ttag was read
 			 * here, we resample if we detect inconsistancy.
 			 */
 			goto resample;
diff --git a/bsps/shared/grlib/1553/gr1553rt.c b/bsps/shared/grlib/1553/gr1553rt.c
index cea84ac..7f35138 100644
--- a/bsps/shared/grlib/1553/gr1553rt.c
+++ b/bsps/shared/grlib/1553/gr1553rt.c
@@ -159,11 +159,11 @@ static void gr1553rt_list_unreg(struct gr1553rt_list *list)
 static int gr1553rt_bdid(void *rt, struct gr1553rt_sw_bd *bd)
 {
 	struct gr1553rt_priv *priv = rt;
-	
+
 	unsigned short index;
 
 	/* Get Index of Software BD */
-	index = ((unsigned int)bd - (unsigned int)&priv->swbds[0]) / 
+	index = ((unsigned int)bd - (unsigned int)&priv->swbds[0]) /
 		sizeof(struct gr1553rt_sw_bd);
 
 	return index;
@@ -195,10 +195,9 @@ static int gr1553rt_bd_alloc(void *rt, struct gr1553rt_sw_bd **bd, int cnt)
 	}
 
 	*bd = &priv->swbds[priv->swbd_free];
+	curr = &priv->swbds[priv->swbd_free];
 	for (i=0; i<cnt; i++) {
-		if ( i == 0) {
-			curr = &priv->swbds[priv->swbd_free];
-		} else {
+		if ( i != 0) {
 			curr = &priv->swbds[curr->this_next];
 		}
 		if ( curr->this_next == 0xffff ) {
@@ -358,7 +357,7 @@ int gr1553rt_bd_init(
 	bd->next = nextbd;
 	SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
 
-	return 0;	
+	return 0;
 }
 
 int gr1553rt_bd_update(
@@ -733,7 +732,7 @@ void gr1553rt_hw_stop(struct gr1553rt_priv *priv)
 	GR1553RT_WRITE_REG(&priv->regs->rt_cfg, GR1553RT_KEY);
 
 	/* Stop BC if not already stopped: BC can not be used simultaneously
-	 * as the RT anyway 
+	 * as the RT anyway
 	 */
 	GR1553RT_WRITE_REG(&priv->regs->bc_ctrl, GR1553BC_KEY | 0x0204);
 
@@ -772,17 +771,17 @@ void gr1553rt_sw_free(struct gr1553rt_priv *priv)
 	}
 }
 
-/* Free dynamically allocated buffers, if any */
 static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
 {
 	int size;
+	int retval = 0;
 
 	/* Allocate Event log */
 	if ((unsigned int)priv->cfg.evlog_buffer & 1) {
 		/* Translate Address from HARDWARE (REMOTE) to CPU-LOCAL */
-		priv->evlog_hw_base = (unsigned int *)
+		priv->evlog_buffer = (void *)
 			((unsigned int)priv->cfg.evlog_buffer & ~0x1);
-		priv->evlog_buffer = priv->cfg.evlog_buffer;
+		priv->evlog_hw_base = (unsigned int*)priv->evlog_buffer;
 		drvmgr_translate_check(
 			*priv->pdev,
 			DMAMEM_TO_CPU,
@@ -794,16 +793,19 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
 		if (priv->cfg.evlog_buffer == NULL) {
 			priv->evlog_buffer = grlib_malloc(
 				priv->cfg.evlog_size * 2);
-			if (priv->evlog_buffer == NULL)
-				return -1;
+			if (priv->evlog_buffer == NULL) {
+				retval = -1;
+				goto err;
+			}
+			/* Align to SIZE bytes boundary */
+			priv->evlog_cpu_base = (unsigned int *)
+				(((unsigned int)priv->evlog_buffer +
+				(priv->cfg.evlog_size-1)) & ~(priv->cfg.evlog_size-1));
 		} else {
 			/* Addess already CPU-LOCAL */
 			priv->evlog_buffer = priv->cfg.evlog_buffer;
+			priv->evlog_cpu_base  = (unsigned int *)priv->evlog_buffer;
 		}
-		/* Align to SIZE bytes boundary */
-		priv->evlog_cpu_base = (unsigned int *)
-			(((unsigned int)priv->evlog_buffer +
-			(priv->cfg.evlog_size-1)) & ~(priv->cfg.evlog_size-1));
 
 		drvmgr_translate_check(
 			*priv->pdev,
@@ -813,6 +815,11 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
 			priv->cfg.evlog_size
 			);
 	}
+	/* Verify alignment */
+	if ((unsigned int)priv->evlog_hw_base & (priv->cfg.evlog_size-1)) {
+		retval = -2;
+		goto err;
+	}
 	priv->evlog_cpu_end = priv->evlog_cpu_base +
 				priv->cfg.evlog_size/sizeof(unsigned int *);
 
@@ -821,9 +828,9 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
 	size = priv->bds_cnt * sizeof(struct gr1553rt_bd);
 	if ((unsigned int)priv->cfg.bd_buffer & 1) {
 		/* Translate Address from HARDWARE (REMOTE) to CPU-LOCAL */
-		priv->bds_hw = (struct gr1553rt_bd *)
+		priv->bd_buffer = (void *)
 			((unsigned int)priv->cfg.bd_buffer & ~0x1);
-		priv->bd_buffer = priv->cfg.bd_buffer;
+		priv->bds_hw = (struct gr1553rt_bd *)priv->bd_buffer;
 		drvmgr_translate_check(
 			*priv->pdev,
 			DMAMEM_TO_CPU,
@@ -834,15 +841,18 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
 	} else {
 		if ( priv->cfg.bd_buffer == NULL ) {
 			priv->bd_buffer = grlib_malloc(size + 0xf);
-			if (priv->bd_buffer == NULL)
-				return -1;
+			if (priv->bd_buffer == NULL) {
+				retval = -1;
+				goto err;
+			}
+			/* Align to 16 bytes boundary */
+			priv->bds_cpu = (struct gr1553rt_bd *)
+				(((unsigned int)priv->bd_buffer + 0xf) & ~0xf);
 		} else {
 			/* Addess already CPU-LOCAL */
 			priv->bd_buffer	= priv->cfg.bd_buffer;
+			priv->bds_cpu = (struct gr1553rt_bd *)priv->bd_buffer;
 		}
-		/* Align to 16 bytes boundary */
-		priv->bds_cpu = (struct gr1553rt_bd *)
-				(((unsigned int)priv->bd_buffer + 0xf) & ~0xf);
 
 		/* Translate from CPU address to hardware address */
 		drvmgr_translate_check(
@@ -853,21 +863,28 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
 			size
 			);
 	}
+	/* Verify alignment */
+	if ((unsigned int)priv->bds_hw & (0xf)) {
+		retval = -2;
+		goto err;
+	}
 
 #if (RTBD_MAX == 0)
 	/* Allocate software description of */
 	priv->swbds = grlib_malloc(priv->cfg.bd_count * sizeof(*priv->swbds));
 	if ( priv->swbds == NULL ) {
-		return -1;
+		retval = -1;
+		goto err;
 	}
 #endif
 
 	/* Allocate Sub address table */
 	if ((unsigned int)priv->cfg.satab_buffer & 1) {
 		/* Translate Address from HARDWARE (REMOTE) to CPU-LOCAL */
-		priv->sas_hw = (struct gr1553rt_sa *)
+		priv->satab_buffer = (void *)
 			((unsigned int)priv->cfg.satab_buffer & ~0x1);
-		priv->satab_buffer = priv->cfg.satab_buffer;
+		priv->sas_hw = (struct gr1553rt_sa *)priv->satab_buffer;
+
 		drvmgr_translate_check(
 			*priv->pdev,
 			DMAMEM_TO_CPU,
@@ -877,16 +894,18 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
 	} else {
 		if (priv->cfg.satab_buffer == NULL) {
 			priv->satab_buffer = grlib_malloc((16 * 32) * 2);
-			if (priv->satab_buffer == NULL)
-				return -1;
+			if (priv->satab_buffer == NULL) {
+				retval = -1;
+				goto err;
+			}
+			/* Align to 512 bytes boundary */
+			priv->sas_cpu = (struct gr1553rt_sa *)
+				(((unsigned int)priv->satab_buffer + 0x1ff) & ~0x1ff);
 		} else {
 			/* Addess already CPU-LOCAL */
 			priv->satab_buffer = priv->cfg.satab_buffer;
+			priv->sas_cpu = (struct gr1553rt_sa *)priv->satab_buffer;
 		}
-		/* Align to 512 bytes boundary */
-		priv->sas_cpu = (struct gr1553rt_sa *)
-				(((unsigned int)priv->satab_buffer + 0x1ff) &
-				~0x1ff);
 
 		/* Translate Address from CPU-LOCAL to HARDWARE (REMOTE) */
 		drvmgr_translate_check(
@@ -896,8 +915,17 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
 			(void **)&priv->sas_hw,
 			16 * 32);
 	}
+	/* Verify alignment */
+	if ((unsigned int)priv->sas_hw & (0x1ff)) {
+		retval = -2;
+		goto err;
+	}
 
-	return 0;
+err:
+	if (retval) {
+		gr1553rt_sw_free(priv);
+	}
+	return retval;
 }
 
 void gr1553rt_sw_init(struct gr1553rt_priv *priv)
@@ -943,7 +971,7 @@ void gr1553rt_sw_init(struct gr1553rt_priv *priv)
 int gr1553rt_config(void *rt, struct gr1553rt_cfg *cfg)
 {
 	struct gr1553rt_priv *priv = rt;
-
+	int retval = 0;
 	if ( priv->started )
 		return -1;
 
@@ -955,9 +983,9 @@ int gr1553rt_config(void *rt, struct gr1553rt_cfg *cfg)
 	if ( cfg->rtaddress > 30 )
 		return -1;
 	if ( (cfg->evlog_size & (cfg->evlog_size-1)) != 0)
-		return -1; /* SIZE: Not aligned to a power of 2 */
+		return -2; /* SIZE: Not aligned to a power of 2 */
 	if ( ((unsigned int)priv->cfg.evlog_buffer & (cfg->evlog_size-1)) != 0 )
-		return -1; /* Buffer: Not aligned to size */
+		return -2; /* Buffer: Not aligned to size */
 #if (RTBD_MAX > 0)
 	if ( cfg->bd_count > RTBD_MAX )
 		return -1;
@@ -968,8 +996,9 @@ int gr1553rt_config(void *rt, struct gr1553rt_cfg *cfg)
 
 	/*** Adapt to new config ***/
 
-	if ( gr1553rt_sw_alloc(priv) != 0 ) 
-		return -1;
+	if ( (retval=gr1553rt_sw_alloc(priv)) != 0 ) {
+		return retval;
+	}
 
 	gr1553rt_sw_init(priv);
 
-- 
2.7.4



More information about the devel mailing list