>From d92c991a89c7979afc46ef10f2feac0d5061d97d Mon Sep 17 00:00:00 2001
From: Ken Mills <[email protected]>
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 <[email protected]>
---
 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
From d92c991a89c7979afc46ef10f2feac0d5061d97d Mon Sep 17 00:00:00 2001
From: Ken Mills <[email protected]>
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 <[email protected]>
---
 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

_______________________________________________
Meego-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to