[Meego-kernel] [PATCH 2/2] Modified pti_write_to aperture to be endian independent.

Mills, Ken K ken.k.mills at intel.com
Tue Oct 19 18:42:21 PDT 2010


>From d92c991a89c7979afc46ef10f2feac0d5061d97d Mon Sep 17 00:00:00 2001
From: Ken Mills <ken.k.mills at intel.com>
Date: Tue, 19 Oct 2010 18:21:38 -0700
Subject: [PATCH 2/2] Modified pti_write_to aperture to be endian independent. Also allow user
 space log messages to exceed 8192 bytes.

Signed-off-by: Ken Mills <ken.k.mills at intel.com>
---
 drivers/misc/pti.c |   99 +++++++++++++++++++++++----------------------------
 1 files changed, 45 insertions(+), 54 deletions(-)

diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index 696a59d..f314110 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -50,6 +50,7 @@
 #define CONSOLE_ID	73   /* console master ID address */
 #define OS_BASE_ID	74   /* base OS master ID address */
 #define APP_BASE_ID	80   /* base App master ID address */
+#define USER_COPY_SIZE	8192 /* 8Kb buffer to copy data from user space */
 #define CONTROL_FRAME_LEN	32 /* PTI control frame maximum size */
 
 struct pti_tty {
@@ -102,10 +103,7 @@ static unsigned int pti_control_channel;
 static void pti_write_to_aperture(struct masterchannel *mc, u8 *buf, int len)
 {
 	int dwordcnt, final, i;
-	union {
-		u32 val;
-		u8 c[4];
-	} ptiword;
+	u32 ptiword;
 	u8 *p;
 	u32 __iomem *aperture;
 
@@ -125,44 +123,27 @@ static void pti_write_to_aperture(struct masterchannel *mc, u8 *buf, int len)
 		dwordcnt--;
 	}
 
-	/*
-	   FIXME: This algorithm builds the dword from the input buffer.
-	   This algorithm does work correctly with the PTI HW
-	   and Fido debugging HW.  However, this got flagged in upstream
-	   review not conforming to proper endian practices.
-	   u32 ptiword = cpu_to_le32(*(u32 *)p);
-	   was tried but was incorrect endianess.  Then the Fido
-	   HW used to test this code broke.  The goal is to submit
-	   something known to work and then fix this when it can be tested.
-	*/
 	for (i = 0; i < dwordcnt; i++) {
-		ptiword.c[3] = *p++;
-		ptiword.c[2] = *p++;
-		ptiword.c[1] = *p++;
-		ptiword.c[0] = *p++;
+		ptiword = be32_to_cpu(*(u32 *)p);
+		p += 4;
 		pr_debug("%s(%d): PTI aperture: master(%d), channel(%d)\n",
 			__func__, __LINE__, mc->master, mc->channel);
 		pr_debug("%s(%d): PTI double word: %#x\n\n",
-			__func__, __LINE__, ptiword.val);
-		iowrite32(ptiword.val, aperture);
+			__func__, __LINE__, ptiword);
+		iowrite32(ptiword, aperture);
 	}
 
 	aperture += DTS;		/* adding DTS signals that is EOM */
-	ptiword.val = 0;
-	/*
-	   FIXME: This has the same issue as stated in other FIXME.
-	   u32 ptiword |= *p++ << (8 * i); was tried and had the
-	   same character-swapping endianess problem.
-	 */
+
+	ptiword = 0;
 	for (i = 0; i < final; i++)
-		ptiword.c[3-i] = *p++;
+		ptiword |= *p++ << (24-(8*i));
 
 	pr_debug("%s(%d): PTI aperture: master(%d), channel(%d)\n",
 		__func__, __LINE__, mc->master, mc->channel);
 	pr_debug("%s(%d): Final PTI double word: %#x\n\n",
-		__func__, __LINE__, ptiword.val);
-	iowrite32(ptiword.val, aperture);
-
+		__func__, __LINE__, ptiword);
+	iowrite32(ptiword, aperture);
 	return;
 }
 
@@ -223,6 +204,7 @@ static void pti_write_full_frame_to_aperture(struct masterchannel *mc,
 	pti_write_to_aperture(mc, (u8 *)buf, len);
 }
 
+
 /**
  * getID(): Allocate a master and channel ID.
  *
@@ -323,6 +305,9 @@ EXPORT_SYMBOL(mipi_request_masterchannel);
 void mipi_release_masterchannel(struct masterchannel *mc)
 {
 	u8 master, channel, i;
+
+	mutex_lock(&alloclock);
+
 	if (mc) {
 		master = mc->master;
 		channel = mc->channel;
@@ -338,6 +323,8 @@ void mipi_release_masterchannel(struct masterchannel *mc)
 
 		kfree(mc);
 	}
+
+	mutex_unlock(&alloclock);
 }
 EXPORT_SYMBOL(mipi_release_masterchannel);
 
@@ -406,8 +393,6 @@ static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
 	struct masterchannel *mc;
 	int ret = 0;
 
-	pr_debug("%s %s(%d): Called.\n", __FILE__,  __func__, __LINE__);
-
 	/*
 	   we actually want to allocate a new channel per open, per
 	   system arch.  HW gives more than plenty channels for a single
@@ -418,6 +403,8 @@ static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
 	ret = tty_port_open(&drv_data->port, tty, filp);
 	pti_tty_data = tty->driver_data;
 	mc = mipi_request_masterchannel(0);
+	if (mc == 0)
+		return -EBUSY;
 	pti_tty_data->mc = mc;
 
 	return ret;
@@ -456,7 +443,6 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
 {
 	int idx = tty->index;
 	struct pti_tty *pti_tty_data;
-
 	int ret = tty_init_termios(tty);
 
 	if (ret == 0) {
@@ -566,40 +552,45 @@ int pti_char_release(struct inode *inode, struct file *filp)
  * @param data: trace data to be written.
  * @param len:  # of byte to write.
  * @param ppose: Not used in this function implementation.
- * @return int : # of bytes written, or error.  -EMSGSIZE is
- *               returned if length is beyond 8k.
+ * @return int : # of bytes written, or error.
  */
 ssize_t pti_char_write(struct file *filp, const char *data, size_t len,
 		loff_t *ppose)
 {
-	int retval;
-
 	struct masterchannel *mc;
 	void *kbuf;
+	const char *tmp = data;
 
-	/*
-	   adding a limit on the size of the buffer, since this
-	   is a value that can be passed in by a user and we want to
-	   minimize the chance of crashing alloc.  Returning
-	   EMSGSIZE actually seems to be the best error code
-	   for a user to figure out what happened.
-	*/
-	if (len > 8192)
-		return -EMSGSIZE;
+	size_t size = USER_COPY_SIZE, n = 0;
 
 	mc = filp->private_data;
 
-	kbuf = kmalloc(len, GFP_KERNEL);
-	if (kbuf == NULL)
+	kbuf = kmalloc(size, GFP_KERNEL);
+	if (kbuf == NULL)  {
+		pr_err("%s(%d): buf allocation failed\n",
+			__func__, __LINE__);
 		return 0;
-	retval = copy_from_user(kbuf, data, len);
-	if (retval) {
-		kfree(kbuf);
-		return -EFAULT;
 	}
 
-	pr_debug("%s(%d): buf: %s, len: %d\n", __func__, __LINE__, data, len);
-	pti_write_to_aperture(mc, kbuf, len);
+	do {
+		if (len - n > USER_COPY_SIZE)
+			size = USER_COPY_SIZE;
+		else
+			size = len - n;
+
+		if (copy_from_user(kbuf, tmp, size)) {
+			kfree(kbuf);
+			return n ? n : -EFAULT;
+		}
+
+		pr_debug("%s(%d): writing %u bytes\n", __func__, __LINE__,
+							size);
+		pti_write_to_aperture(mc, kbuf, size);
+		n  += size;
+		tmp += size;
+
+	} while (len > n);
+
 	kfree(kbuf);
 	kbuf = 0;
 
-- 
1.7.0.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Modified-pti_write_to-aperture-to-be-endian-independ.patch
Type: text/x-patch
Size: 6255 bytes
Desc: 0002-Modified-pti_write_to-aperture-to-be-endian-independ.patch
URL: <http://lists.meego.com/pipermail/meego-kernel/attachments/20101019/59a83055/attachment.bin>


More information about the Meego-kernel mailing list