From 70a8c3eb8546cefe40fb0bc7991e8899b7b91075 Mon Sep 17 00:00:00 2001 From: Bastien Armand Date: Fri, 18 Apr 2014 18:10:57 +0200 Subject: [PATCH] staging: panel: fix sparse warnings in lcd_write This patch fixes two sparse warnings related to lcd_write : warning: incorrect type in argument 1 (different address spaces) warning: incorrect type in initializer (incompatible argument 2 (different address spaces)) lcd_write can be used from kernel space (in panel_lcd_print) or from user space. So we introduce the lcd_write_char function that will write a char to the device. We modify lcd_write and panel_lcd_print to use it. Finally we add __user annotation missing in lcd_write. Signed-off-by: Bastien Armand Signed-off-by: Greg Kroah-Hartman --- drivers/staging/panel/panel.c | 205 ++++++++++++++++++---------------- 1 file changed, 109 insertions(+), 96 deletions(-) diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index a53f94e7e9c3..e2e3c6bc3a6c 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -1217,111 +1217,113 @@ static inline int handle_lcd_special_code(void) return processed; } +static void lcd_write_char(char c) +{ + /* first, we'll test if we're in escape mode */ + if ((c != '\n') && lcd_escape_len >= 0) { + /* yes, let's add this char to the buffer */ + lcd_escape[lcd_escape_len++] = c; + lcd_escape[lcd_escape_len] = 0; + } else { + /* aborts any previous escape sequence */ + lcd_escape_len = -1; + + switch (c) { + case LCD_ESCAPE_CHAR: + /* start of an escape sequence */ + lcd_escape_len = 0; + lcd_escape[lcd_escape_len] = 0; + break; + case '\b': + /* go back one char and clear it */ + if (lcd_addr_x > 0) { + /* check if we're not at the + end of the line */ + if (lcd_addr_x < lcd_bwidth) + /* back one char */ + lcd_write_cmd(0x10); + lcd_addr_x--; + } + /* replace with a space */ + lcd_write_data(' '); + /* back one char again */ + lcd_write_cmd(0x10); + break; + case '\014': + /* quickly clear the display */ + lcd_clear_fast(); + break; + case '\n': + /* flush the remainder of the current line and + go to the beginning of the next line */ + for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++) + lcd_write_data(' '); + lcd_addr_x = 0; + lcd_addr_y = (lcd_addr_y + 1) % lcd_height; + lcd_gotoxy(); + break; + case '\r': + /* go to the beginning of the same line */ + lcd_addr_x = 0; + lcd_gotoxy(); + break; + case '\t': + /* print a space instead of the tab */ + lcd_print(' '); + break; + default: + /* simply print this char */ + lcd_print(c); + break; + } + } + + /* now we'll see if we're in an escape mode and if the current + escape sequence can be understood. */ + if (lcd_escape_len >= 2) { + int processed = 0; + + if (!strcmp(lcd_escape, "[2J")) { + /* clear the display */ + lcd_clear_fast(); + processed = 1; + } else if (!strcmp(lcd_escape, "[H")) { + /* cursor to home */ + lcd_addr_x = lcd_addr_y = 0; + lcd_gotoxy(); + processed = 1; + } + /* codes starting with ^[[L */ + else if ((lcd_escape_len >= 3) && + (lcd_escape[0] == '[') && + (lcd_escape[1] == 'L')) { + processed = handle_lcd_special_code(); + } + + /* LCD special escape codes */ + /* flush the escape sequence if it's been processed + or if it is getting too long. */ + if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN)) + lcd_escape_len = -1; + } /* escape codes */ +} + static ssize_t lcd_write(struct file *file, - const char *buf, size_t count, loff_t *ppos) + const char __user *buf, size_t count, loff_t *ppos) { - const char *tmp = buf; + const char __user *tmp = buf; char c; - for (; count-- > 0; (ppos ? (*ppos)++ : 0), ++tmp) { + for (; count-- > 0; (*ppos)++, tmp++) { if (!in_interrupt() && (((count + 1) & 0x1f) == 0)) /* let's be a little nice with other processes that need some CPU */ schedule(); - if (ppos == NULL && file == NULL) - /* let's not use get_user() from the kernel ! */ - c = *tmp; - else if (get_user(c, tmp)) + if (get_user(c, buf)) return -EFAULT; - /* first, we'll test if we're in escape mode */ - if ((c != '\n') && lcd_escape_len >= 0) { - /* yes, let's add this char to the buffer */ - lcd_escape[lcd_escape_len++] = c; - lcd_escape[lcd_escape_len] = 0; - } else { - /* aborts any previous escape sequence */ - lcd_escape_len = -1; - - switch (c) { - case LCD_ESCAPE_CHAR: - /* start of an escape sequence */ - lcd_escape_len = 0; - lcd_escape[lcd_escape_len] = 0; - break; - case '\b': - /* go back one char and clear it */ - if (lcd_addr_x > 0) { - /* check if we're not at the - end of the line */ - if (lcd_addr_x < lcd_bwidth) - /* back one char */ - lcd_write_cmd(0x10); - lcd_addr_x--; - } - /* replace with a space */ - lcd_write_data(' '); - /* back one char again */ - lcd_write_cmd(0x10); - break; - case '\014': - /* quickly clear the display */ - lcd_clear_fast(); - break; - case '\n': - /* flush the remainder of the current line and - go to the beginning of the next line */ - for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++) - lcd_write_data(' '); - lcd_addr_x = 0; - lcd_addr_y = (lcd_addr_y + 1) % lcd_height; - lcd_gotoxy(); - break; - case '\r': - /* go to the beginning of the same line */ - lcd_addr_x = 0; - lcd_gotoxy(); - break; - case '\t': - /* print a space instead of the tab */ - lcd_print(' '); - break; - default: - /* simply print this char */ - lcd_print(c); - break; - } - } - - /* now we'll see if we're in an escape mode and if the current - escape sequence can be understood. */ - if (lcd_escape_len >= 2) { - int processed = 0; - - if (!strcmp(lcd_escape, "[2J")) { - /* clear the display */ - lcd_clear_fast(); - processed = 1; - } else if (!strcmp(lcd_escape, "[H")) { - /* cursor to home */ - lcd_addr_x = lcd_addr_y = 0; - lcd_gotoxy(); - processed = 1; - } - /* codes starting with ^[[L */ - else if ((lcd_escape_len >= 3) && - (lcd_escape[0] == '[') && - (lcd_escape[1] == 'L')) { - processed = handle_lcd_special_code(); - } - - /* LCD special escape codes */ - /* flush the escape sequence if it's been processed - or if it is getting too long. */ - if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN)) - lcd_escape_len = -1; - } /* escape codes */ + lcd_write_char(c); } return tmp - buf; @@ -1365,8 +1367,19 @@ static struct miscdevice lcd_dev = { /* public function usable from the kernel for any purpose */ static void panel_lcd_print(const char *s) { - if (lcd_enabled && lcd_initialized) - lcd_write(NULL, s, strlen(s), NULL); + const char *tmp = s; + int count = strlen(s); + + if (lcd_enabled && lcd_initialized) { + for (; count-- > 0; tmp++) { + if (!in_interrupt() && (((count + 1) & 0x1f) == 0)) + /* let's be a little nice with other processes + that need some CPU */ + schedule(); + + lcd_write_char(*tmp); + } + } } /* initialize the LCD driver */ -- 2.30.2