[Cbe-oss-dev] [PATCH 3/3] libspe2: Clean up proxy DMA and add error checks

Kazunori Asayama asayama at sm.sony.co.jp
Mon Jun 25 23:48:02 EST 2007


This patch modifies proxy DMA implementation in libspe2 as following:

  - share the same code between 'get' and 'put'
  - make scope of variables smaller
  - add missing error checks

Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>

---
 spebase/dma.c |  201 +++++++++++++++++++++++++++-------------------------------
 1 file changed, 97 insertions(+), 104 deletions(-)

Index: b/spebase/dma.c
===================================================================
--- a/spebase/dma.c	2007-06-22 21:48:00.000000000 +0900
+++ b/spebase/dma.c	2007-06-25 10:32:40.000000000 +0900
@@ -32,107 +32,93 @@
 static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status);
 static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status);
 
-static int spe_do_mfc_put(spe_context_ptr_t spectx, unsigned src, void *dst,
-			  unsigned size, unsigned tag, unsigned class,
-			  enum mfc_cmd cmd)
+static int issue_mfc_command(spe_context_ptr_t spectx, unsigned lsa, void *ea,
+			     unsigned size, unsigned tag, unsigned tid, unsigned rid,
+			     enum mfc_cmd cmd)
 {
-	struct mfc_command_parameter_area parm = {
-		.lsa   = src,
-		.ea    = (unsigned long) dst,
-		.size  = size,
-		.tag   = tag,
-		.class = class,
-		.cmd   = cmd,
-	};
-	int ret, fd;
-	unsigned int eah, eal;
-	volatile struct spe_mfc_command_area *cmd_area = 
-                spectx->base_private->mfc_mmap_base;
+	int ret;
 
-	DEBUG_PRINTF("queuing DMA %x %lx %x %x %x %x\n", parm.lsa,
-		parm.ea, parm.size, parm.tag, parm.class, parm.cmd);
+	DEBUG_PRINTF("queuing DMA %x %lx %x %x %x %x %x\n", lsa,
+		(unsigned long)ea, size, tag, tid, rid, (unsigned)cmd);
+
+	/* tag 16-31 are reserved by kernel */
+	if (tag > 0x0f || tid > 0xff || rid > 0xff) {
+		errno = EINVAL;
+		return -1;
+	}
 
 	if (spectx->base_private->flags & SPE_MAP_PS) {
+		volatile struct spe_mfc_command_area *cmd_area =
+			spectx->base_private->mfc_mmap_base;
+		unsigned int eal = (uintptr_t) ea & 0xFFFFFFFF;
+		unsigned int eah = (unsigned long long)(uintptr_t) ea >> 32;
 		_base_spe_context_lock(spectx, FD_MFC);
-		eal = (uintptr_t) dst & 0xFFFFFFFF;
-		eah = (unsigned long long)(uintptr_t) dst >> 32;
 		while ((cmd_area->MFC_QStatus & 0x0000FFFF) == 0) ;
 		do {
-			cmd_area->MFC_LSA         = src;
+			cmd_area->MFC_LSA         = lsa;
 			cmd_area->MFC_EAH         = eah;
 			cmd_area->MFC_EAL         = eal;
 			cmd_area->MFC_Size_Tag    = (size << 16) | tag;
-                        cmd_area->MFC_ClassID_CMD = (class << 16) | cmd;
+			cmd_area->MFC_ClassID_CMD = (tid << 24) | (rid << 16) | cmd;
 
 			ret = cmd_area->MFC_CMDStatus & 0x00000003;
 		} while (ret); // at least one of the two bits is set
 		_base_spe_context_unlock(spectx, FD_MFC);
-		return ret;
+		return 0;
 	}
-
-	fd = open_if_closed(spectx, FD_MFC, 0);
-	if (fd != -1) {
-		ret = write(fd, &parm, sizeof (parm));
-		if ((ret < 0) && (errno != EIO)) {
-			perror("spe_do_mfc_put: internal error");
+	else {
+		int fd;
+		fd = open_if_closed(spectx, FD_MFC, 0);
+		if (fd != -1) {
+			struct mfc_command_parameter_area parm = {
+				.lsa   = lsa,
+				.ea    = (unsigned long) ea,
+				.size  = size,
+				.tag   = tag,
+				.class = (tid << 8) | rid,
+				.cmd   = cmd,
+			};
+			ret = write(fd, &parm, sizeof (parm));
+			if ((ret < 0) && (errno != EIO)) {
+				perror("spe_do_mfc_put: internal error");
+			}
+			return ret < 0 ? -1 : 0;
 		}
-		return ret < 0 ? -1 : 0;
 	}
-	/* the kernel does not support DMA, so just copy directly */
-	memcpy(dst, spectx->base_private->mem_mmap_base + src, size);
-	return 0;
+	/* the kernel does not support DMA */
+	return 1;
 }
 
-static int spe_do_mfc_get(spe_context_ptr_t spectx, unsigned int dst, void *src,
-			  unsigned int size, unsigned int tag, unsigned int class,
+static int spe_do_mfc_put(spe_context_ptr_t spectx, unsigned src, void *dst,
+			  unsigned size, unsigned tag, unsigned tid, unsigned rid,
 			  enum mfc_cmd cmd)
 {
-	struct mfc_command_parameter_area parm = {
-		.lsa   = dst,
-		.ea    = (unsigned long) src,
-		.size  = size,
-		.tag   = tag,
-		.class = class,
-		.cmd   = cmd,
-	};
-	int ret, fd;
-	unsigned int eah, eal;
-	volatile struct spe_mfc_command_area *cmd_area = 
-                spectx->base_private->mfc_mmap_base;
-
-	DEBUG_PRINTF("queuing DMA %x %x %x %x %x %x\n", parm.lsa,
-	                                           parm.ea, parm.size, parm.tag, parm.class, parm.cmd);
-	
-
-        if (spectx->base_private->flags & SPE_MAP_PS) {
-		_base_spe_context_lock(spectx, FD_MFC);
-		eal = (uintptr_t) src & 0xFFFFFFFF;
-		eah = (unsigned long long)(uintptr_t) src >> 32;
-                while ((cmd_area->MFC_QStatus & 0x0000FFFF) == 0) ;
-                do {
-                        cmd_area->MFC_LSA         = dst;
-                        cmd_area->MFC_EAH         = eah;
-                        cmd_area->MFC_EAL         = eal;
-                        cmd_area->MFC_Size_Tag    = (size << 16) | tag;
-                        cmd_area->MFC_ClassID_CMD = (class << 16) | cmd;
-                        ret = cmd_area->MFC_CMDStatus & 0x00000003;
-                } while (ret); // at least one of the two bits is set
-		_base_spe_context_unlock(spectx, FD_MFC);
-                return ret;
-        }
-
-	fd = open_if_closed(spectx, FD_MFC, 0);
-	if (fd != -1) {
-		ret = write(fd, &parm, sizeof (parm));
-		if ((ret < 0) && (errno != EIO)) {
-			perror("spe_do_mfc_get: internal error");
-		}
-		return ret < 0 ? -1 : 0;
+	int ret;
+	ret = issue_mfc_command(spectx, src, dst, size, tag, tid, rid, cmd);
+	if (ret <= 0) {
+		return ret;
 	}
+	else {
+		/* the kernel does not support DMA, so just copy directly */
+		memcpy(dst, spectx->base_private->mem_mmap_base + src, size);
+		return 0;
+	}
+}
 
-	/* the kernel does not support DMA, so just copy directly */
-	memcpy(spectx->base_private->mem_mmap_base + dst, src, size);
-	return 0;
+static int spe_do_mfc_get(spe_context_ptr_t spectx, unsigned int dst, void *src,
+			  unsigned int size, unsigned int tag, unsigned tid, unsigned rid,
+			  enum mfc_cmd cmd)
+{
+	int ret;
+	ret = issue_mfc_command(spectx, dst, src, size, tag, tid, rid, cmd);
+	if (ret <= 0) {
+		return ret;
+	}
+	else {
+		/* the kernel does not support DMA, so just copy directly */
+		memcpy(spectx->base_private->mem_mmap_base + dst, src, size);
+		return 0;
+	}
 }
 
 int _base_spe_mfcio_put(spe_context_ptr_t spectx, 
@@ -143,7 +129,7 @@ int _base_spe_mfcio_put(spe_context_ptr_
                         unsigned int tid, 
                         unsigned int rid)
 {
-	return spe_do_mfc_put(spectx, ls, ea, size, tag & 0xf, tid << 8 | rid, MFC_CMD_PUT);
+	return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUT);
 }
 
 int _base_spe_mfcio_putb(spe_context_ptr_t spectx, 
@@ -154,9 +140,7 @@ int _base_spe_mfcio_putb(spe_context_ptr
                         unsigned int tid, 
                         unsigned int rid)
 {
-	return spe_do_mfc_put(spectx, ls, ea, size, tag & 0xf,
-		tid << 8 | rid, MFC_CMD_PUTB);
-	
+	return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUTB);
 }
 
 int _base_spe_mfcio_putf(spe_context_ptr_t spectx, 
@@ -167,9 +151,7 @@ int _base_spe_mfcio_putf(spe_context_ptr
                         unsigned int tid, 
                         unsigned int rid)
 {
-	return spe_do_mfc_put(spectx, ls, ea, size, tag & 0xf,
-			tid << 8 | rid, MFC_CMD_PUTF);
-	
+	return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUTF);
 }
 
 
@@ -181,8 +163,7 @@ int _base_spe_mfcio_get(spe_context_ptr_
                         unsigned int tid, 
                         unsigned int rid)
 {
-	return spe_do_mfc_get(spectx, ls, ea, size, tag & 0xf,
-				tid << 8 | rid, MFC_CMD_GET);
+	return spe_do_mfc_get(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_GET);
 }
 
 int _base_spe_mfcio_getb(spe_context_ptr_t spectx, 
@@ -193,8 +174,7 @@ int _base_spe_mfcio_getb(spe_context_ptr
                         unsigned int tid, 
                         unsigned int rid)
 {
-	return spe_do_mfc_get(spectx, ls, ea, size, tag & 0xf,
-				tid << 8 | rid, MFC_CMD_GETB);
+	return spe_do_mfc_get(spectx, ls, ea, size, tag, rid, rid, MFC_CMD_GETB);
 }
 
 int _base_spe_mfcio_getf(spe_context_ptr_t spectx, 
@@ -205,8 +185,7 @@ int _base_spe_mfcio_getf(spe_context_ptr
                         unsigned int tid, 
                         unsigned int rid)
 {
-	return spe_do_mfc_get(spectx, ls, ea, size, tag & 0xf,
-				tid << 8 | rid, MFC_CMD_GETF);
+	return spe_do_mfc_get(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_GETF);
 }
 
 static int spe_mfcio_tag_status_read_all(spe_context_ptr_t spectx, 
@@ -218,6 +197,9 @@ static int spe_mfcio_tag_status_read_all
 		return spe_read_tag_status_block(spectx, mask, tag_status);
 	} else {
 		fd = open_if_closed(spectx, FD_MFC, 0);
+		if (fd == -1) {
+			return -1;
+		}
 
 		if (fsync(fd) != 0) {
 			return -1;
@@ -225,7 +207,6 @@ static int spe_mfcio_tag_status_read_all
 
 		return spe_read_tag_status_block(spectx, mask, tag_status);
 	}
-	return -1;
 }
 
 static int spe_mfcio_tag_status_read_any(spe_context_ptr_t spectx,
@@ -247,21 +228,24 @@ static int spe_mfcio_tag_status_read_imm
  */
 static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status)
 {
-	int fd;
-	volatile struct spe_mfc_command_area *cmd_area = 
-                spectx->base_private->mfc_mmap_base;
-
 	if (spectx->base_private->flags & SPE_MAP_PS) {
+		volatile struct spe_mfc_command_area *cmd_area =
+			spectx->base_private->mfc_mmap_base;
+
 		_base_spe_context_lock(spectx, FD_MFC);
 		cmd_area->Prxy_QueryMask = mask;
 		__asm__ ("eieio");
-		*tag_status = 0;
-		while  (*tag_status ^ mask) 
-			*tag_status =  cmd_area->Prxy_TagStatus;
+		do {
+			*tag_status = cmd_area->Prxy_TagStatus;
+		} while (*tag_status ^ mask);
 		_base_spe_context_unlock(spectx, FD_MFC);
 		return 0;
 	} else {
+		int fd;
 		fd = open_if_closed(spectx, FD_MFC, 0);
+		if (fd == -1) {
+			return -1;
+		}
 		
 		if (read(fd,tag_status,4) == 4) {
 			return 0;
@@ -272,14 +256,12 @@ static int spe_read_tag_status_block(spe
 
 static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status)
 {
-	struct pollfd poll_fd;
-	
-	int fd;
 	unsigned int ret;
-	volatile struct spe_mfc_command_area *cmd_area = 
-                spectx->base_private->mfc_mmap_base;
 
 	if (spectx->base_private->flags & SPE_MAP_PS) {
+		volatile struct spe_mfc_command_area *cmd_area =
+			spectx->base_private->mfc_mmap_base;
+
 		_base_spe_context_lock(spectx, FD_MFC);
 		cmd_area->Prxy_QueryMask = mask;
 		__asm__ ("eieio");
@@ -287,7 +269,13 @@ static int spe_read_tag_status_noblock(s
 		_base_spe_context_unlock(spectx, FD_MFC);
 		return 0;
 	} else {
+		struct pollfd poll_fd;
+		int fd;
+
 		fd = open_if_closed(spectx, FD_MFC, 0);
+		if (fd == -1) {
+			return -1;
+		}
 		
 		poll_fd.fd = fd;
 		poll_fd.events = POLLIN;
@@ -316,6 +304,11 @@ int _base_spe_mfcio_tag_status_read(spe_
 			mask = 0;
 	}
 
+	if (!tag_status) {
+		errno = EINVAL;
+		return -1;
+	}
+
 	switch (behavior) {
 	case SPE_TAG_ALL:
 		return spe_mfcio_tag_status_read_all(spectx, mask, tag_status);



More information about the cbe-oss-dev mailing list