>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
