From: dongkyun.yun Date: Wed, 14 Dec 2011 01:13:45 +0000 (+0900) Subject: [Title] delete unnecessary dpram sources X-Git-Tag: 2.2.1_release^2~182^2~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d7e9c17015f7ea114a7ea6e2f12dd2ddd1eb9c55;p=sdk%2Femulator%2Femulator-kernel.git [Title] delete unnecessary dpram sources [Type] // Commit Type: Feature / Bugfix / Enhancement [Module] // Module Name - (Main / Sub) [Priority] // Importance : Critical / Major / Minor [CQ#] // CQ Issue Number [Redmine#] // Redmine Isuue Number [Problem] // Problem Description [Cause] // Cause Description [Solution] // Solution Description [TestCase] // Executed the test-target (How to) --- diff --git a/arch/x86/configs/i386_emul_defconfig b/arch/x86/configs/i386_emul_defconfig index 791efb7e762c..0340ccc8cfe8 100644 --- a/arch/x86/configs/i386_emul_defconfig +++ b/arch/x86/configs/i386_emul_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.32.9 -# Mon Dec 12 12:31:35 2011 +# Wed Dec 14 10:09:11 2011 # # CONFIG_64BIT is not set CONFIG_X86_32=y @@ -1225,9 +1225,6 @@ CONFIG_NVRAM=y # CONFIG_RAW_DRIVER is not set # CONFIG_HANGCHECK_TIMER is not set # CONFIG_TCG_TPM is not set -# CONFIG_DPRAM is not set -# CONFIG_MULTIPDP is not set -# CONFIG_IPCMUX is not set # CONFIG_TELCLOCK is not set CONFIG_VDPRAM_DEVICE=y CONFIG_DEVPORT=y @@ -2105,7 +2102,7 @@ CONFIG_ANDROID_TIMED_OUTPUT=y # CONFIG_IIO is not set # -# Virtual_3D_Accelerator +# Virtual device drivers for emulator # CONFIG_HW_ACCELERATOR=y CONFIG_EMUL_LCD=y diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index d901063717ad..8965e41fb4dd 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -1097,8 +1097,6 @@ config UV_MMTIMER source "drivers/char/tpm/Kconfig" -source "drivers/char/dpram/Kconfig" - config TELCLOCK tristate "Telecom clock driver for ATCA SBC" depends on EXPERIMENTAL && X86 diff --git a/drivers/char/Makefile b/drivers/char/Makefile index dc900d5a59d3..badb3ec6af44 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -106,8 +106,6 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o obj-$(CONFIG_TCG_TPM) += tpm/ -obj-$(CONFIG_DPRAM) += dpram/ -obj-$(CONFIG_MULTIPDP) += dpram/ obj-$(CONFIG_VDPRAM_DEVICE) += vdpram.o obj-$(CONFIG_PS3_FLASH) += ps3flash.o diff --git a/drivers/char/dpram/Kconfig b/drivers/char/dpram/Kconfig deleted file mode 100755 index fbf50f8b2a35..000000000000 --- a/drivers/char/dpram/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -config DPRAM - tristate "DPRAM support" - default y - help - Please move to arch/arm/mach-pxa. It is mirage specific file - -config MULTIPDP - tristate "MULTIPDP support" - default m - help - So what? - -config IPCMUX - tristate "IPCMUX support" - default m - help - It is ipc mux driver for samsung ipc 3.0. diff --git a/drivers/char/dpram/Makefile b/drivers/char/dpram/Makefile deleted file mode 100755 index 8db3e6aab896..000000000000 --- a/drivers/char/dpram/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# -# Makefile for the ipmi drivers. -# - -dpram-config := 0 - -ifeq ($(CONFIG_MACH_MIRAGE),y) - obj-$(CONFIG_DPRAM) += dpram.o - dpram-config := 1 -endif -ifeq ($(CONFIG_MACH_OMNIA),y) - obj-$(CONFIG_DPRAM) += dpram.o - dpram-config := 1 -endif - -obj-$(CONFIG_MULTIPDP) += multipdp.o -obj-$(CONFIG_MULTIPDP) += ipcmux.o diff --git a/drivers/char/dpram/dpram.c b/drivers/char/dpram/dpram.c deleted file mode 100755 index 60e6b0e55ea1..000000000000 --- a/drivers/char/dpram/dpram.c +++ /dev/null @@ -1,1500 +0,0 @@ -/* - * DPRAM Device Driver Implementation. - * Revision History - - */ - -#define _DEBUG 0 - -#define USE_WORKQUEUE -#define ENABLE_ERROR_DEVICE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef ENABLE_ERROR_DEVICE -#include -#include -#endif - -#include -#include -#include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#ifdef CONFIG_EVENT_LOGGING -#include -#include -#include -#include -#endif - -#include "dpram.h" -#include "dprintk.h" - -#define DRIVER_ID "1.2" -#define DRIVER_NAME "DPRAM" -#define DRIVER_PROC_ENTRY "driver/dpram" -#define DRIVER_TEST_ENTRY "driver/dpram-dump" -#define DRIVER_MAJOR_NUM_ALLOC 0 - -#ifdef USE_WORKQUEUE -#define DPRAM_WORKQUEUE "DPRAM_QUEUE" -#endif - -#ifdef CONFIG_EVENT_LOGGING -#define DPRAM_ID 3 -#define DPRAM_READ 3 -#define DPRAM_WRITE 4 -#endif - -#ifdef _DEBUG -#define DPRINTK(fmt, args...) printk("[DPRAM] " fmt, ## args) -#else -#define DPRINTK(fmt, args...) do{} while(0) -#endif - -#define DFC_LOCK do{}while(0) -#define DFC_UNLOCK do{}while(0) - -#define write_to_dpram_no_lock(dest, src, size) \ - _memcpy((void *)(DPRAM_VBASE + dest), src, size) - -#define read_from_dpram_no_lock(dest, src, size) \ - _memcpy(dest, (void *)(DPRAM_VBASE + src), size) - -#define write_to_dpram(dest, src, size) \ - DFC_LOCK;\ - _memcpy((void *)(DPRAM_VBASE + dest), src, size);\ - DFC_UNLOCK - -#define read_from_dpram(dest, src, size) \ - DFC_LOCK;\ - _memcpy(dest, (void *)(DPRAM_VBASE + src), size);\ - DFC_UNLOCK - -#ifdef ENABLE_ERROR_DEVICE -#define DPRAM_ERR_MSG_LEN 65 -#define DPRAM_ERR_DEVICE "dpramerr" -#endif - -#define PHONE_ON_GPIO81 81 -#define PHONE_ACTIVE_GPIO107 107 -#define PHONE_nRESET_GPIO102 102 -#define PHONE_nINT_GPIO70 70 -#define PHONE_TEST_nINT_GPIO1 1 - -static struct tty_driver *dpram_tty_driver; - -static dpram_tasklet_data_t dpram_tasklet_data[MAX_INDEX]; - -static dpram_device_t dpram_table[MAX_INDEX] = { - { - .in_head_addr = DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, - .in_tail_addr = DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, - .in_buff_addr = DPRAM_PHONE2PDA_FORMATTED_BUFFER_ADDRESS, - .in_buff_size = DPRAM_PHONE2PDA_FORMATTED_SIZE, - - .out_head_addr = DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS, - .out_tail_addr = DPRAM_PDA2PHONE_FORMATTED_TAIL_ADDRESS, - .out_buff_addr = DPRAM_PDA2PHONE_FORMATTED_BUFFER_ADDRESS, - .out_buff_size = DPRAM_PDA2PHONE_FORMATTED_SIZE, - - .mask_req_ack = INT_MASK_REQ_ACK_F, - .mask_res_ack = INT_MASK_RES_ACK_F, - .mask_send = INT_MASK_SEND_F, - }, - { - .in_head_addr = DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS, - .in_tail_addr = DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS, - .in_buff_addr = DPRAM_PHONE2PDA_RAW_BUFFER_ADDRESS, - .in_buff_size = DPRAM_PHONE2PDA_RAW_SIZE, - - .out_head_addr = DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS, - .out_tail_addr = DPRAM_PDA2PHONE_RAW_TAIL_ADDRESS, - .out_buff_addr = DPRAM_PDA2PHONE_RAW_BUFFER_ADDRESS, - .out_buff_size = DPRAM_PDA2PHONE_RAW_SIZE, - - .mask_req_ack = INT_MASK_REQ_ACK_R, - .mask_res_ack = INT_MASK_RES_ACK_R, - .mask_send = INT_MASK_SEND_R, - }, -}; - -static struct tty_struct *dpram_tty[MAX_INDEX]; -static struct ktermios *dpram_termios[MAX_INDEX]; -static struct ktermios *dpram_termios_locked[MAX_INDEX]; - -static void res_ack_tasklet_handler(unsigned long data); - -static int debug_hexdump = 0; -static int debug_default = 0; - -module_param(debug_hexdump, int, S_IRUGO); -module_param(debug_default, int, S_IRUGO); - -#ifdef USE_WORKQUEUE -static void send_workqueue_handler(struct work_struct *dummy); -static struct workqueue_struct *dpram_workqueue; -typedef struct workqueue_data { - struct work_struct work; - unsigned long data; -} workqueue_data_t; - -static workqueue_data_t workqueue_data[MAX_INDEX]; -#else -static void send_tasklet_handler(unsigned long data); -static DECLARE_TASKLET(fmt_send_tasklet, send_tasklet_handler, 0); -static DECLARE_TASKLET(raw_send_tasklet, send_tasklet_handler, 0); -#endif - -static DECLARE_TASKLET(fmt_res_ack_tasklet, res_ack_tasklet_handler, - (unsigned long)&dpram_table[FORMATTED_INDEX]); -static DECLARE_TASKLET(raw_res_ack_tasklet, res_ack_tasklet_handler, - (unsigned long)&dpram_table[RAW_INDEX]); - -#ifdef ENABLE_ERROR_DEVICE -static unsigned int dpram_err_len; -static char dpram_err_buf[DPRAM_ERR_MSG_LEN]; - -struct class *dpram_class; - -static DECLARE_WAIT_QUEUE_HEAD(dpram_err_wait_q); -static struct fasync_struct *dpram_err_async_q; -#endif - -#define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) -void hexdump(const char *buf, int len) -{ - char str[80], octet[10]; - int ofs, i, l; - - for (ofs = 0; ofs < len; ofs += 16) { - sprintf( str, "%03d: ", ofs ); - - for (i = 0; i < 16; i++) { - if ((i + ofs) < len) - sprintf( octet, "%02x ", buf[ofs + i] ); - else - strcpy( octet, " " ); - - strcat( str, octet ); - } - strcat( str, " " ); - l = strlen( str ); - - for (i = 0; (i < 16) && ((i + ofs) < len); i++) - str[l++] = isprint( buf[ofs + i] ) ? buf[ofs + i] : '.'; - - str[l] = '\0'; - printk( "%s\n", str ); - } -} -#ifdef CONFIG_EVENT_LOGGING -static inline EVENT_HEADER *getPayloadHeader(int flag, int size) -{ - EVENT_HEADER *header; - struct timeval time_val; - - header = (EVENT_HEADER *)kmalloc(sizeof (EVENT_HEADER), GFP_ATOMIC); - do_gettimeofday(&time_val); - - header->timeVal = time_val; - header->class = (flag == DPRAM_READ ? DPRAM_READ : DPRAM_WRITE); - header->repeat_count = 0; - header->payload_length = size; - - return header; -} - -static inline void dpram_event_logging(int direction, void *src, int size) -{ - EVENT_HEADER *header; - unsigned long flags; - - header = getPayloadHeader(direction, size); - - local_irq_save(flags); - klog(header, sizeof (EVENT_HEADER), DPRAM_ID); - - if (direction == DPRAM_WRITE) { - klog(src, size, DPRAM_ID); - } - - else if (direction == DPRAM_READ) { - klog((void *)(DPRAM_VBASE + src), size, DPRAM_ID); - } - - local_irq_restore(flags); - kfree(header); -} -#endif - -static inline void byte_align(unsigned long dest, unsigned long src) -{ - u_int16_t *p_src; - volatile u_int16_t *p_dest; - - if (!(dest & (2 - 1)) && !(src & (2 - 1))) { - p_dest = (u_int16_t *)dest; - p_src = (u_int16_t *)src; - - *p_dest = (*p_dest & 0xFF00) | (*p_src & 0x00FF); - } else if ((dest & (2 - 1)) && (src & (2 - 1))) { - p_dest = (u_int16_t *)(dest - 1); - p_src = (u_int16_t *)(src - 1); - - *p_dest = (*p_dest & 0x00FF) | (*p_src & 0xFF00); - } else if (!(dest & (2 - 1)) && (src & (2 - 1))) { - p_dest = (u_int16_t *)dest; - p_src = (u_int16_t *)(src - 1); - - *p_dest = (*p_dest & 0xFF00) | ((*p_src >> 8) & 0x00FF); - } else if ((dest & (2 - 1)) && !(src & (2 - 1))) { - p_dest = (u_int16_t *)(dest - 1); - p_src = (u_int16_t *)src; - - *p_dest = (*p_dest & 0x00FF) | ((*p_src << 8) & 0xFF00); - } else { - if(debug_default) - DPRINTK("oops.~\n"); - } -} - -static inline void _memcpy(void *p_dest, const void *p_src, int size) -{ - unsigned long dest = (unsigned long)p_dest; - unsigned long src = (unsigned long)p_src; - - if (size <= 0) - return; - - if (dest & 1) { - byte_align(dest, src); - dest++, src++; - size--; - } - - if (size & 1) { - byte_align(dest + size - 1, src + size - 1); - size--; - } - - if (src & 1) { - unsigned char *s = (unsigned char *)src; - volatile u_int16_t *d = (unsigned short *)dest; - - size >>= 1; - - while (size--) { - *d++ = s[0] | (s[1] << 8); - s += 2; - } - } else { - u_int16_t *s = (u_int16_t *)src; - volatile u_int16_t *d = (unsigned short *)dest; - - size >>= 1; - - while (size--) { *d++ = *s++; } - } -} - -static inline void send_interrupt_to_phone(u_int16_t irq_mask, int blend) -{ - if (blend) { - u_int16_t tmp; - - read_from_dpram((void *)&tmp, DPRAM_PDA2PHONE_INTERRUPT_ADDRESS, - DPRAM_INTERRUPT_PORT_SIZE); - - irq_mask |= tmp; - } - - write_to_dpram(DPRAM_PDA2PHONE_INTERRUPT_ADDRESS, (void *)&irq_mask, - DPRAM_INTERRUPT_PORT_SIZE); - - if(debug_default) - DPRINTK("PDA -> Phone interrupt!\n"); -} - -static inline int dpram_write(dpram_device_t *device, const char *buf, int len) -{ - int retval, size, len_left; - - u_int16_t head, tail; - u_int16_t irq_mask = 0; - - if(debug_hexdump){ - DPRINTK("\n\n################### dpram write(%d) #####################\n", len); - hexdump(buf, len); - DPRINTK("################# dpram write(%d) End ###################\n\n", len); - } - - read_from_dpram((void *)&head, device->out_head_addr, sizeof (head)); - read_from_dpram((void *)&tail, device->out_tail_addr, sizeof (tail)); - - if (head < tail) { - retval = tail - head - 1; - size = (retval >= len) ? len : retval; - - write_to_dpram(device->out_buff_addr + head, (void *)buf, size); - retval = size; - } else if (tail == 0) { - retval = device->out_buff_size - head - 1; - size = (retval >= len) ? len : retval; - - write_to_dpram(device->out_buff_addr + head, (void *)buf, size); - retval = size; - } else { - retval = device->out_buff_size - head; - size = (retval >= len) ? len : retval; - - write_to_dpram(device->out_buff_addr + head, (void *)buf, size); - retval = size; - - len_left = len - retval; - - if (len_left > 0) { - size = ((tail - 1) >= len_left) ? len_left : tail - 1; - - write_to_dpram(device->out_buff_addr, (void *)(buf + retval), size); - retval += size; - } - } - - head = (u_int16_t)((head + retval) % device->out_buff_size); - write_to_dpram(device->out_head_addr, (void *)&head, sizeof (head)); - -#ifdef CONFIG_EVENT_LOGGING - dpram_event_logging(DPRAM_WRITE, (void *)&head, size); -#endif - - if(debug_hexdump) - DPRINTK("head: %u, tail: %u\n", head, tail); - - irq_mask = INT_MASK_VALID | device->mask_send; - - if (head < tail) - size = tail - head - 1; - else - size = (device->out_buff_size - head) + tail - 1; - - if (size < 1) - irq_mask |= device->mask_req_ack; - - send_interrupt_to_phone(irq_mask, 0); - return retval; -} - -static inline int dpram_read(dpram_device_t *device, char *buf, int len) -{ - int retval, size, len_left; - u_int16_t head, tail; - read_from_dpram((void *)&head, device->in_head_addr, sizeof (head)); - read_from_dpram((void *)&tail, device->in_tail_addr, sizeof (tail)); - - if(debug_hexdump) - printk("dpram read : len(%d), head(%d), tail(%d)\n", len, head, tail); - if (head == tail) - return 0; - - if (head > tail) { - retval = head - tail; - size = (retval >= len) ? len : retval; - -if(debug_hexdump) - printk("read form dpram : size(%d)\n", size); - read_from_dpram((void *)buf, device->in_buff_addr + tail, size); - retval = size; - } else { - retval = device->in_buff_size - tail; - size = (retval >= len) ? len : retval; - - if(debug_hexdump) - printk("1. read form dpram : size(%d)\n", size); - read_from_dpram((void *)buf, device->in_buff_addr + tail, size); - retval = size; - - len_left = len - retval; - - if (len_left > 0) { - size = (head >= len_left) ? len_left : head; - - if(debug_hexdump) - printk("2. read form dpram : size(%d)\n", size); - read_from_dpram((void *)buf + retval, device->in_buff_addr, size); - retval += size; - } - } - - tail = (u_int16_t)((tail + retval) % device->in_buff_size); - write_to_dpram(device->in_tail_addr, (void *)&tail, sizeof (tail)); - -#ifdef CONFIG_EVENT_LOGGING - dpram_event_logging(DPRAM_READ, (void *)&tail, size); -#endif - - if(debug_hexdump){ - DPRINTK("head: %u, tail: %u\n", head, tail); - printk("\n\n################### dpram read(%d) #####################\n", len); - hexdump(buf, retval); - printk("################# dpram read(%d) End ###################\n\n", len); - } - return retval; -} - -static inline void dpram_clear(void) -{ - long i; - unsigned long flags; - - u_int16_t value = 0; - - local_irq_save(flags); - - for (i = DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS; - i < DPRAM_SIZE - (DPRAM_INTERRUPT_PORT_SIZE * 2); - i += 2) - *((u_int16_t *)(DPRAM_VBASE + i)) = value; - - local_irq_restore(flags); - - read_from_dpram_no_lock((void *)&value, - DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, sizeof (value)); -} - -static inline void dpram_init_and_report(void) -{ - const u_int16_t magic_code = 0x00AA; - const u_int16_t init_start = INT_COMMAND(INT_MASK_CMD_INIT_START); - const u_int16_t init_end = INT_COMMAND(INT_MASK_CMD_INIT_END); - - u_int16_t access_enable = 0x0000; - - write_to_dpram_no_lock(DPRAM_PDA2PHONE_INTERRUPT_ADDRESS, - (void *)&init_start, DPRAM_INTERRUPT_PORT_SIZE); - - write_to_dpram_no_lock(DPRAM_ACCESS_ENABLE_ADDRESS, - (void *)&access_enable, sizeof (access_enable)); - - dpram_clear(); - - write_to_dpram_no_lock(DPRAM_MAGIC_CODE_ADDRESS, - (void *)&magic_code, sizeof (magic_code)); - { - unsigned short code = 0; - read_from_dpram_no_lock((void *)&code, DPRAM_MAGIC_CODE_ADDRESS, sizeof(code)); - if(debug_default) - printk("magic code = 0x%X\n", code); - } - - access_enable = 0x0001; - write_to_dpram_no_lock(DPRAM_ACCESS_ENABLE_ADDRESS, - (void *)&access_enable, sizeof (access_enable)); - - write_to_dpram_no_lock(DPRAM_PDA2PHONE_INTERRUPT_ADDRESS, - (void *)&init_end, DPRAM_INTERRUPT_PORT_SIZE); - - if(debug_default) - DPRINTK("DPRAM is initialized and report phone.\n"); -} - -static inline int dpram_get_read_available(dpram_device_t *device) -{ - int readable; - u_int16_t head, tail; - - read_from_dpram((void *)&head, device->in_head_addr, sizeof (head)); - read_from_dpram((void *)&tail, device->in_tail_addr, sizeof (tail)); - - readable = (head >= tail) ? (head - tail) : (device->in_buff_size - tail + head); - - if(debug_default) - DPRINTK("readable room: %u\n", readable); - return readable; -} - -static inline void dpram_drop_data(dpram_device_t *device) -{ - u_int16_t head, tail; - - read_from_dpram((void *)&head, device->in_head_addr, sizeof (head)); - read_from_dpram((void *)&tail, device->in_tail_addr, sizeof (tail)); - - if(debug_hexdump) - DPRINTK("head: %u, tail: %u\n", head, tail); - - tail = head; - - write_to_dpram(device->in_tail_addr, (void *)&tail, sizeof (tail)); -} - -static void dpram_phone_on(void) -{ - if (gpio_get_value(PHONE_ACTIVE_GPIO107) == 0) { - gpio_set_value(PHONE_nRESET_GPIO102, 1); - - gpio_set_value(PHONE_ON_GPIO81, 0); - mdelay(500); - gpio_set_value(PHONE_ON_GPIO81, 1); - mdelay(500); - gpio_set_value(PHONE_ON_GPIO81, 0); - - if(debug_default) { - printk("[dpram_phone_on]MODEM is pwr status: %d\n " - ,gpio_get_value(PHONE_ACTIVE_GPIO107)); - } - } else { - if(debug_default){ - printk("MODEM is powered on already.!\n"); - printk("try to turn off phone!\n"); - } - - gpio_set_value(PHONE_nRESET_GPIO102, 0); - - gpio_set_value(PHONE_ON_GPIO81, 1); - mdelay(500); - gpio_set_value(PHONE_ON_GPIO81, 0); - mdelay(500); - gpio_set_value(PHONE_ON_GPIO81, 1); - - if(debug_default) { - printk("[dpram_phone_on]MODEM is pwr status: %d\n " - ,gpio_get_value(PHONE_ACTIVE_GPIO107)); - } - - printk("try to turn on phone!\n"); - gpio_set_value(PHONE_nRESET_GPIO102, 1); - - gpio_set_value(PHONE_ON_GPIO81, 0); - mdelay(500); - gpio_set_value(PHONE_ON_GPIO81, 1); - mdelay(500); - gpio_set_value(PHONE_ON_GPIO81, 0); - - printk("[dpram_phone_on]MODEM is pwr status: %d\n " - ,gpio_get_value(PHONE_ACTIVE_GPIO107)); - } -} - -static void dpram_phone_off(void) -{ - const u_int16_t access_enable = 0x0000; - - write_to_dpram(DPRAM_ACCESS_ENABLE_ADDRESS, - (void *)&access_enable, sizeof (access_enable)); - - gpio_set_value(PHONE_nRESET_GPIO102, 0); - - gpio_set_value(PHONE_ON_GPIO81, 1); - mdelay(500); - gpio_set_value(PHONE_ON_GPIO81, 0); - mdelay(500); - gpio_set_value(PHONE_ON_GPIO81, 1); - - if(debug_default) { - printk("[dpram_phone_off]MODEM is pwr status: %d\n " - ,gpio_get_value(PHONE_ACTIVE_GPIO107)); - } -} - -static inline unsigned int dpram_phone_getstatus(void) -{ - unsigned int ret = 0; - - ret = !!gpio_get_value(PHONE_ACTIVE_GPIO107); - - return ret; -} - -#ifdef CONFIG_PROC_FS -static int dpram_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - int len; -#ifdef ENABLE_ERROR_DEVICE - char buf[DPRAM_ERR_MSG_LEN]; - unsigned long flags; -#endif - - u_int16_t magic, enable; - u_int16_t fmt_in_head, fmt_in_tail, fmt_out_head, fmt_out_tail; - u_int16_t raw_in_head, raw_in_tail, raw_out_head, raw_out_tail; - u_int16_t in_interrupt = 0, out_interrupt = 0; - - read_from_dpram((void *)&magic, DPRAM_MAGIC_CODE_ADDRESS, sizeof(magic)); - read_from_dpram((void *)&enable, DPRAM_ACCESS_ENABLE_ADDRESS, sizeof(enable)); - - read_from_dpram((void *)&fmt_in_head, DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, - sizeof(fmt_in_head)); - read_from_dpram((void *)&fmt_in_tail, DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, - sizeof(fmt_in_tail)); - read_from_dpram((void *)&fmt_out_head, DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS, - sizeof(fmt_out_head)); - read_from_dpram((void *)&fmt_out_tail, DPRAM_PDA2PHONE_FORMATTED_TAIL_ADDRESS, - sizeof(fmt_out_tail)); - - read_from_dpram((void *)&raw_in_head, DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS, - sizeof(raw_in_head)); - read_from_dpram((void *)&raw_in_tail, DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS, - sizeof(raw_in_tail)); - read_from_dpram((void *)&raw_out_head, DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS, - sizeof(raw_out_head)); - read_from_dpram((void *)&raw_out_tail, DPRAM_PDA2PHONE_RAW_TAIL_ADDRESS, - sizeof(raw_out_tail)); - - read_from_dpram((void *)&in_interrupt, DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, - DPRAM_INTERRUPT_PORT_SIZE); - read_from_dpram((void *)&out_interrupt, DPRAM_PDA2PHONE_INTERRUPT_ADDRESS, - DPRAM_INTERRUPT_PORT_SIZE); - -#ifdef ENABLE_ERROR_DEVICE - memset((void *)buf, '\0', DPRAM_ERR_MSG_LEN); - local_irq_save(flags); - memcpy(buf, dpram_err_buf, DPRAM_ERR_MSG_LEN - 1); - local_irq_restore(flags); -#endif - - p += sprintf(p, - "-------------------------------------\n" - "| NAME\t\t\t| VALUE\n" - "-------------------------------------\n" - "| MAGIC CODE\t\t| 0x%04x\n" - "| ENABLE CODE\t\t| 0x%04x\n" - "| PHONE->PDA FMT HEAD\t| %u\n" - "| PHONE->PDA FMT TAIL\t| %u\n" - "| PDA->PHONE FMT HEAD\t| %u\n" - "| PDA->PHONE FMT TAIL\t| %u\n" - "| PHONE->PDA RAW HEAD\t| %u\n" - "| PHONE->PDA RAW TAIL\t| %u\n" - "| PDA->PHONE RAW HEAD\t| %u\n" - "| PDA->PHONE RAW TAIL\t| %u\n" - "| PHONE->PDA INT.\t| 0x%04x\n" - "| PDA->PHONE INT.\t| 0x%04x\n" -#ifdef ENABLE_ERROR_DEVICE - "| LAST PHONE ERR MSG\t| %s\n" -#endif - "| PHONE ACTIVE\t\t| %s\n" - "-------------------------------------\n", - magic, enable, - fmt_in_head, fmt_in_tail, fmt_out_head, fmt_out_tail, - raw_in_head, raw_in_tail, raw_out_head, raw_out_tail, - in_interrupt, out_interrupt, - -#ifdef ENABLE_ERROR_DEVICE - (buf[0] != '\0' ? buf : "NONE"), -#endif - - (dpram_phone_getstatus() ? "ACTIVE" : "INACTIVE") - ); - - len = (p - page) - off; - if (len < 0) - len = 0; - - *eof = (len <= count) ? 1 : 0; - *start = page + off; - - return len; -} -static int dpram_dump_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char dump[16]; - unsigned int i=0; - if(debug_hexdump) - printk("dpram read dump========================================"); - - for(i =0 ; i < 1024 ; i++){ - memset(dump, 0x0, sizeof(dump)); - read_from_dpram((void *)dump, 16*i, sizeof(dump)); - if(debug_hexdump) - hexdump(dump, 16); - } - if(debug_hexdump) - printk("=======================================================\n"); - - *eof = 0; - *start = 0; - - return 0; -} -#endif - -static int dpram_tty_open(struct tty_struct *tty, struct file *file) -{ - dpram_device_t *device = &dpram_table[tty->index]; - -#if 0 - printk ("tty addr : %lx\n", tty); - printk ("dpram device addr : %lx\n", device); - printk ("dpram input head addr : %lx\n", device->in_head_addr); - printk ("dpram input tail addr : %lx\n", device->in_tail_addr); - printk ("dpram input buff addr : %lx\n", device->in_buff_addr); - printk ("dpram input buff size : %ld\n", device->in_buff_size); - printk ("dpram output head addr : %lx\n", device->out_head_addr); - printk ("dpram output tail addr : %lx\n", device->out_tail_addr); - printk ("dpram output buff addr : %lx\n", device->out_buff_addr); - printk ("dpram output buff size : %ld\n", device->out_buff_size); -#endif - - device->serial.tty = tty; - device->serial.open_count++; - - if (device->serial.open_count > 1) { - device->serial.open_count--; - return -EBUSY; - } - - tty->driver_data = (void *)device; - tty->low_latency = 1; - - if(debug_default) - DPRINTK("Device is opened successfully.\n"); - - tty_buffer_request_room(tty, 8192); - - return 0; -} - -static void dpram_tty_close(struct tty_struct *tty, struct file *file) -{ - dpram_device_t *device = (dpram_device_t *)tty->driver_data; - - if (device && (device == &dpram_table[tty->index])) { - down(&device->serial.sem); - - device->serial.open_count--; - device->serial.tty = NULL; - - up(&device->serial.sem); - - if(debug_default) - DPRINTK("Device is closed successfully. from pid(%d)\n", current->pid); - } else { - if(debug_default) - DPRINTK("Device is empty or different.!!\n"); - } -} - -static int dpram_tty_write(struct tty_struct *tty, - const unsigned char *buffer, int count) -{ - dpram_device_t *device = (dpram_device_t *)tty->driver_data; - - if (!device) - return 0; - - return dpram_write(device, buffer, count); -} - -static int dpram_tty_write_room(struct tty_struct *tty) -{ - int avail; - u_int16_t head, tail; - - dpram_device_t *device = (dpram_device_t *)tty->driver_data; - - if (!device) - return 0; - - read_from_dpram((void *)&head, device->out_head_addr, sizeof (head)); - read_from_dpram((void *)&tail, device->out_tail_addr, sizeof (tail)); - - avail = (head < tail) ? (tail - head - 1) : \ - (device->out_buff_size - head + tail - 1); - - return avail; -} - -static int dpram_tty_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - unsigned int val; - - if (debug_default) - DPRINTK("ioctl command: 0x%04x\n", cmd); - - switch (cmd) { - case HN_DPRAM_PHONE_ON: - printk("ioctl phome on command: 0x%04x\n", cmd); - dpram_phone_on(); - return 0; - - case HN_DPRAM_PHONE_OFF: - printk("ioctl phone off command: 0x%04x\n", cmd); - dpram_phone_off(); - return 0; - - case HN_DPRAM_PHONE_GETSTATUS: - printk("ioctl phone get status command: 0x%04x\n", cmd); - val = dpram_phone_getstatus(); - return copy_to_user((unsigned int *)arg, &val, sizeof (val)); - - default: - break; - } - - return -ENOIOCTLCMD; -} - -static int dpram_tty_chars_in_buffer(struct tty_struct *tty) -{ - int avail, written; - u_int16_t head, tail; - - dpram_device_t *device = (dpram_device_t *)tty->driver_data; - - if (!device) - return 0; - - read_from_dpram((void *)&head, device->out_head_addr, sizeof (head)); - read_from_dpram((void *)&tail, device->out_tail_addr, sizeof (tail)); - - avail = (head < tail) ? (tail - head - 1) : \ - (device->out_buff_size - head + tail - 1); - - written = device->out_buff_size - avail - 1; - - return written; -} - -#ifdef ENABLE_ERROR_DEVICE -static int dpram_err_read(struct file *filp, char *buf, size_t count, loff_t *ppos) -{ - DECLARE_WAITQUEUE(wait, current); - - unsigned long flags; - ssize_t ret; - size_t ncopy; - - add_wait_queue(&dpram_err_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - - while (1) { - local_irq_save(flags); - - if (dpram_err_len) { - ncopy = min(count, dpram_err_len); - - if (copy_to_user(buf, dpram_err_buf, ncopy)) - ret = -EFAULT; - else - ret = ncopy; - - dpram_err_len = 0; - - local_irq_restore(flags); - break; - } - - local_irq_restore(flags); - - if (filp->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - schedule(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&dpram_err_wait_q, &wait); - - return ret; -} - -static int dpram_err_fasync(int fd, struct file *filp, int mode) -{ - return fasync_helper(fd, filp, mode, &dpram_err_async_q); -} - -static unsigned int dpram_err_poll(struct file *filp, - struct poll_table_struct *wait) -{ - poll_wait(filp, &dpram_err_wait_q, wait); - return ((dpram_err_len) ? (POLLIN | POLLRDNORM) : 0); -} -#endif - -static void res_ack_tasklet_handler(unsigned long data) -{ - dpram_device_t *device = (dpram_device_t *)data; - - if (device && device->serial.tty) { - struct tty_struct *tty = device->serial.tty; - - if(debug_default) - DPRINTK("device id: %d\n", tty->index); - - tty_wakeup(tty); - } -} - -#ifdef USE_WORKQUEUE -static void send_workqueue_handler(struct work_struct *dummy) -#else -static void send_tasklet_handler(unsigned long data) -#endif -{ - workqueue_data_t *p = container_of(dummy, workqueue_data_t, work); - dpram_tasklet_data_t *tasklet_data = (dpram_tasklet_data_t *)p->data; - - dpram_device_t *device = tasklet_data->device; - u_int16_t non_cmd = tasklet_data->non_cmd; - - int ret = 0; - int readable; - - unsigned char* char_buf_ptr = NULL; - if (device && device->serial.tty) { - struct tty_struct *tty = device->serial.tty; - - while ((readable = dpram_get_read_available(device)) > 0) { - - ret=tty_prepare_flip_string(tty, &char_buf_ptr, readable); - - if (ret <= 0) { - if(debug_default) - DPRINTK("tty buffer allocation failed.\n"); - break; - } else { - ret = dpram_read(device, char_buf_ptr, ret); - if (ret < 0) { - if(debug_default) - DPRINTK("dpram_read failed.\n"); - break; - } - } - } - - tty_flip_buffer_push(tty); - } else { - if(debug_default) - DPRINTK("Drop data due to no corresponding tty.\n"); - dpram_drop_data(device); - } - if (non_cmd & device->mask_req_ack) { - if(debug_default) - DPRINTK("Send to the phone response ack.\n"); - send_interrupt_to_phone(INT_NON_COMMAND(device->mask_res_ack), 0); - } -} - -static inline void cmd_req_active_handler(void) -{ - send_interrupt_to_phone(INT_COMMAND(INT_MASK_CMD_RES_ACTIVE), 1); -} - -static inline void cmd_error_display_handler(void) -{ - char buf[DPRAM_ERR_MSG_LEN]; -#ifdef ENABLE_ERROR_DEVICE - unsigned long flags; -#endif - - memset((void *)buf, 0, sizeof (buf)); - read_from_dpram((void *)buf, DPRAM_PHONE2PDA_FORMATTED_BUFFER_ADDRESS, - sizeof (buf) - 1); - - if (debug_default) - printk("[PHONE ERROR] ->> %s\n", buf); - -#ifdef ENABLE_ERROR_DEVICE - local_irq_save(flags); - memcpy(dpram_err_buf, buf, DPRAM_ERR_MSG_LEN); - dpram_err_len = 64; - local_irq_restore(flags); - - wake_up_interruptible(&dpram_err_wait_q); - kill_fasync(&dpram_err_async_q, SIGIO, POLL_IN); -#endif -} - -static inline void cmd_phone_start_handler(void) -{ - dpram_init_and_report(); -} - -static inline void cmd_req_time_sync_handler(void) -{ - /* TODO: add your codes here.. */ -} - -static inline void cmd_phone_deep_sleep_handler(void) -{ - /* TODO: add your codes here.. */ -} - -static inline void cmd_nv_rebuilding_handler(void) -{ - /* TODO: add your codes here.. */ -} - -static inline void cmd_emer_down_handler(void) -{ - /* TODO: add your codes here.. */ -} - -static inline void command_handler(u_int16_t irq_mask) -{ - u_int16_t cmd = (irq_mask &= ~(INT_MASK_VALID | INT_MASK_COMMAND)); - - if (debug_default) - DPRINTK("command code: 0x%04x\n", cmd); - - switch (cmd) { - case INT_MASK_CMD_REQ_ACTIVE: - cmd_req_active_handler(); - break; - - case INT_MASK_CMD_ERR_DISPLAY: - cmd_error_display_handler(); - break; - - case INT_MASK_CMD_PHONE_START: -if(debug_default) - DPRINTK("phone start handler called.\n"); - cmd_phone_start_handler(); - break; - - case INT_MASK_CMD_REQ_TIME_SYNC: - cmd_req_time_sync_handler(); - break; - - case INT_MASK_CMD_PHONE_DEEP_SLEEP: - cmd_phone_deep_sleep_handler(); - break; - - case INT_MASK_CMD_NV_REBUILDING: - cmd_nv_rebuilding_handler(); - break; - - case INT_MASK_CMD_EMER_DOWN: - cmd_emer_down_handler(); - break; - - default: - if (debug_default) - DPRINTK("Unknown command..\n"); - } -} - -static inline void non_command_handler(u_int16_t irq_mask) -{ - u_int16_t fmt_head, fmt_tail; - u_int16_t raw_head, raw_tail; - - u_int16_t non_cmd = (irq_mask &= ~INT_MASK_VALID); - - if (debug_default) - DPRINTK("non-command code: 0x%04x\n", non_cmd); - - read_from_dpram_no_lock((void *)&fmt_head, DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, - sizeof (fmt_head)); - read_from_dpram_no_lock((void *)&fmt_tail, DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, - sizeof (fmt_tail)); - read_from_dpram_no_lock((void *)&raw_head, DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS, - sizeof (raw_head)); - read_from_dpram_no_lock((void *)&raw_tail, DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS, - sizeof (raw_tail)); - - if (fmt_head != fmt_tail) - non_cmd |= INT_MASK_SEND_F; - - if (raw_head != raw_tail) - non_cmd |= INT_MASK_SEND_R; - - if (non_cmd & INT_MASK_SEND_F) { - dpram_tasklet_data[FORMATTED_INDEX].device = &dpram_table[FORMATTED_INDEX]; - dpram_tasklet_data[FORMATTED_INDEX].non_cmd = non_cmd; - -#ifdef USE_WORKQUEUE - workqueue_data[FORMATTED_INDEX].data = (unsigned long)&dpram_tasklet_data[FORMATTED_INDEX]; - schedule_work(&workqueue_data[FORMATTED_INDEX].work); -#else - fmt_send_tasklet.data = (unsigned long)&dpram_tasklet_data[FORMATTED_INDEX]; - tasklet_schedule(&fmt_send_tasklet); -#endif - } - - if (non_cmd & INT_MASK_SEND_R) { - dpram_tasklet_data[RAW_INDEX].device = &dpram_table[RAW_INDEX]; - dpram_tasklet_data[RAW_INDEX].non_cmd = non_cmd; - -#ifdef USE_WORKQUEUE - workqueue_data[RAW_INDEX].data = (unsigned long)&dpram_tasklet_data[RAW_INDEX]; - schedule_work(&workqueue_data[RAW_INDEX].work); -#else - raw_send_tasklet.data = (unsigned long)&dpram_tasklet_data[RAW_INDEX]; - tasklet_schedule(&raw_send_tasklet); -#endif - } - - if (non_cmd & INT_MASK_RES_ACK_F) - tasklet_schedule(&fmt_res_ack_tasklet); - - if (non_cmd & INT_MASK_RES_ACK_R) - tasklet_schedule(&raw_res_ack_tasklet); -} - -static irqreturn_t dpram_interrupt(int irq, void *dev_id) -{ - u_int16_t irq_mask = 0; - - read_from_dpram_no_lock((void *)&irq_mask, - DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, sizeof (irq_mask)); - - if (!(irq_mask & INT_MASK_VALID)) { - if (debug_default) - DPRINTK("Invalid interrupt mask: 0x%04x\n", irq_mask); - return IRQ_NONE; - } - - if (irq_mask & INT_MASK_COMMAND) - command_handler(irq_mask); - else - non_command_handler(irq_mask); - - return IRQ_HANDLED; -} - -static irqreturn_t phone_active_interrupt(int irq, void *dev_id) -{ - if (debug_default) { - unsigned int is_phone_active = dpram_phone_getstatus(); - DPRINTK("phone is %s.\n", is_phone_active ? "active" : "inactive"); - } - - return IRQ_HANDLED; -} - -#ifdef ENABLE_ERROR_DEVICE -static struct file_operations dpram_err_ops = { - .owner = THIS_MODULE, - .read = dpram_err_read, - .fasync = dpram_err_fasync, - .poll = dpram_err_poll, - .llseek = no_llseek, - - /* TODO: add more operations */ -}; -#endif - -static const struct tty_operations dpram_tty_ops = { - .open = dpram_tty_open, - .close = dpram_tty_close, - .write = dpram_tty_write, - .write_room = dpram_tty_write_room, - .ioctl = dpram_tty_ioctl, - .chars_in_buffer = dpram_tty_chars_in_buffer, - - /* TODO: add more operations */ -}; - -#ifdef ENABLE_ERROR_DEVICE -static inline void unregister_dpram_err_device(void) -{ - unregister_chrdev(dpram_tty_driver->major, DPRAM_ERR_DEVICE); - class_destroy(dpram_class); -} - -static inline int __init register_dpram_err_device(void) -{ - struct device *dpram_err_dev_t; - int ret = register_chrdev(dpram_tty_driver->major, DPRAM_ERR_DEVICE, &dpram_err_ops); - if (ret < 0) - return ret; - - dpram_class = class_create(THIS_MODULE, "err"); - if (IS_ERR(dpram_class)) { - unregister_dpram_err_device(); - return -EFAULT; - } - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - dpram_err_dev_t = device_create(dpram_class, NULL, MKDEV(dpram_tty_driver->major, 0), NULL, DPRAM_ERR_DEVICE); -#else - dpram_err_dev_t = device_create(dpram_class, NULL, MKDEV(dpram_tty_driver->major, 0), DPRAM_ERR_DEVICE); -#endif - if (IS_ERR(dpram_err_dev_t)) { - unregister_dpram_err_device(); - return -EFAULT; - } - - return 0; -} -#endif - -static int __init register_dpram_driver(void) -{ - int retval = 0; - - dpram_tty_driver = alloc_tty_driver(MAX_INDEX); - if (!dpram_tty_driver) - return -ENOMEM; - - dpram_tty_driver->owner = THIS_MODULE; - dpram_tty_driver->magic = TTY_DRIVER_MAGIC; - dpram_tty_driver->driver_name = DRIVER_NAME; - dpram_tty_driver->name = "dpram"; - dpram_tty_driver->major = DRIVER_MAJOR_NUM_ALLOC; - dpram_tty_driver->minor_start = 1; - dpram_tty_driver->num = 2; - dpram_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - dpram_tty_driver->subtype = SERIAL_TYPE_NORMAL; - dpram_tty_driver->flags = TTY_DRIVER_REAL_RAW; - dpram_tty_driver->init_termios = tty_std_termios; - dpram_tty_driver->init_termios.c_cflag = - (B115200 | CS8 | CREAD | CLOCAL | HUPCL); - - tty_set_operations(dpram_tty_driver, &dpram_tty_ops); - dpram_tty_driver->ops = &dpram_tty_ops; - - dpram_tty_driver->ttys = dpram_tty; - dpram_tty_driver->termios = dpram_termios; - dpram_tty_driver->termios_locked = dpram_termios_locked; - - retval = tty_register_driver(dpram_tty_driver); - if (retval) { - if (debug_default) - DPRINTK("tty_register_driver error\n"); - put_tty_driver(dpram_tty_driver); - return retval; - } - - return 0; -} - -static inline void unregister_dpram_driver(void) -{ - int i; - - for (i = 0; i < MAX_INDEX; i++) - tty_unregister_device(dpram_tty_driver, i); - - tty_unregister_driver(dpram_tty_driver); -} - -static inline void __init init_devices(void) -{ - int i; - - for (i = 0; i < MAX_INDEX; i++) { - init_MUTEX(&dpram_table[i].serial.sem); - - dpram_table[i].serial.open_count = 0; - dpram_table[i].serial.tty = NULL; - } -} - -static inline void __exit kill_tasklets(void) -{ - tasklet_kill(&fmt_res_ack_tasklet); - tasklet_kill(&raw_res_ack_tasklet); - -#ifdef USE_WORKQUEUE - destroy_workqueue(dpram_workqueue); -#else - tasklet_kill(&fmt_send_tasklet); - tasklet_kill(&raw_send_tasklet); -#endif -} - -static int __init register_interrupt_handler(void) -{ - unsigned int dpram_irq, phone_active_irq; - int retval = 0; - - dpram_clear(); - - dpram_irq = IRQ_GPIO(PHONE_nINT_GPIO70); - - retval = request_irq(dpram_irq, dpram_interrupt, IRQF_DISABLED, DRIVER_NAME, NULL); - if (retval) { -if(debug_default) - DPRINTK("DPRAM interrupt handler failed.\n"); - unregister_dpram_driver(); - return -1; - } - set_irq_type(IRQ_GPIO(PHONE_nINT_GPIO70), IRQ_TYPE_EDGE_FALLING); - - phone_active_irq = IRQ_GPIO(PHONE_ACTIVE_GPIO107); - retval = request_irq(phone_active_irq, phone_active_interrupt, - IRQF_DISABLED, "Phone Active", NULL); - if (retval) { - if(debug_default) - DPRINTK("Phone active interrupt handler failed.\n"); - free_irq(dpram_irq, NULL); - unregister_dpram_driver(); - return -1; - } - set_irq_type(IRQ_GPIO(PHONE_ACTIVE_GPIO107), IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING); - - return 0; -} - -static void __init check_miss_interrupt(void) -{ - unsigned long flags; - int irq, pin_level; - - pin_level = gpio_get_value(PHONE_ACTIVE_GPIO107) && - !gpio_get_value(PHONE_nINT_GPIO70); - if (pin_level) { - irq = IRQ_GPIO(PHONE_nINT_GPIO70); - if (debug_default) - DPRINTK("Missing interrupt!\n"); - local_irq_save(flags); - dpram_interrupt(irq, NULL); - local_irq_restore(flags); - } -} - -static int __devinit dpram_probe(struct platform_device *dev) -{ - int retval; - - if(debug_default) - DPRINTK("dpram init\n"); - retval = register_dpram_driver(); - if (retval) { - if(debug_default) - DPRINTK("Failed to register dpram (tty) driver.\n"); - return -1; - } - -#ifdef ENABLE_ERROR_DEVICE - retval = register_dpram_err_device(); - if (retval) { -if(debug_default) - DPRINTK("Failed to register dpram error device.\n"); - - unregister_dpram_driver(); - return -1; - } - - memset((void *)dpram_err_buf, '\0', sizeof dpram_err_buf); -#endif - - /* SMC(Static Memory Controller) settting statements are moved to 'mirage-smemc.c' */ - - if ((retval = register_interrupt_handler()) < 0) - return -1; - - init_devices(); /// Occur Kernel Panic -#ifdef USE_WORKQUEUE - dpram_workqueue = create_singlethread_workqueue(DPRAM_WORKQUEUE); - INIT_WORK(&workqueue_data[FORMATTED_INDEX].work, send_workqueue_handler); - INIT_WORK(&workqueue_data[RAW_INDEX].work, send_workqueue_handler); -#endif - -#ifdef CONFIG_PROC_FS - create_proc_read_entry(DRIVER_PROC_ENTRY, 0, 0, dpram_read_proc, NULL); - create_proc_read_entry(DRIVER_TEST_ENTRY, 0, 0, dpram_dump_proc, NULL); -#endif - - check_miss_interrupt(); - - memset((void *)dpram_err_buf, '\0', sizeof dpram_err_buf); - - if (debug_default) - printk(DRIVER_ID "\n"); - - return 0; -} - -static void __exit dpram_exit(void) -{ - unregister_dpram_driver(); - -#ifdef ENABLE_ERROR_DEVICE - unregister_dpram_err_device(); -#endif - - free_irq(IRQ_GPIO(PHONE_nINT_GPIO70), NULL); - free_irq(IRQ_GPIO(PHONE_ACTIVE_GPIO107), NULL); - - kill_tasklets(); -} - -#ifdef CONFIG_PM -/* - * Power management hooks. Note that we won't be called from IRQ context, - * unlike the blank functions above, so we may sleep. - */ -static int dpram_suspend(struct platform_device *dev, pm_message_t state) -{ - return 0; -} - -static int dpram_resume(struct platform_device *dev) -{ - u_int16_t head, tail; - - read_from_dpram((void *)&head, DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, - sizeof(head)); - read_from_dpram((void *)&tail, DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, - sizeof(tail)); - - if (head != tail) - dpram_interrupt(0, NULL); - return 0; -} -#else -#define dpram_suspend NULL -#define dpram_resume NULL -#endif - -static struct platform_driver dpram_driver = { - .probe = dpram_probe, -#ifdef CONFIG_PM - .suspend = dpram_suspend, - .resume = dpram_resume, -#endif - .driver = { - .name = "dpram", - }, -}; - -int __devinit dpram_init(void) -{ - return platform_driver_register(&dpram_driver); -} - - -module_init(dpram_init); -module_exit(dpram_exit); - -MODULE_AUTHOR("SAMSUNG ELECTRONICS CO., LTD"); -MODULE_DESCRIPTION("DPRAM Device Driver for Linux SMART Phone"); -MODULE_LICENSE("GPL"); diff --git a/drivers/char/dpram/dpram.h b/drivers/char/dpram/dpram.h deleted file mode 100755 index 2ad595a7666c..000000000000 --- a/drivers/char/dpram/dpram.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * DPRAM Device Driver Interface. - * - * Author: Geun-Young, Kim - * Se-Heum, Eom - */ - -#ifndef __DPRAM_H__ -#define __DPRAM_H__ - -/* 16KB Size */ -#define DPRAM_SIZE 0x4000 - -/* Memory Address */ -#if defined(CONFIG_MACH_MIRAGE) -#define DPRAM_START_ADDRESS 0x0000 -#define DPRAM_MAGIC_CODE_ADDRESS (DPRAM_START_ADDRESS) -#define DPRAM_ACCESS_ENABLE_ADDRESS (DPRAM_START_ADDRESS + 0x0002) - -#define DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS (DPRAM_START_ADDRESS + 0x0004) -#define DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS) -#define DPRAM_PDA2PHONE_FORMATTED_TAIL_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS + 0x0002) -#define DPRAM_PDA2PHONE_FORMATTED_BUFFER_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS + 0x0004) -#define DPRAM_PDA2PHONE_FORMATTED_SIZE 1020 /* 0x03FC */ - -#define DPRAM_PDA2PHONE_RAW_START_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS + (DPRAM_PDA2PHONE_FORMATTED_SIZE + 4)) -#define DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS (DPRAM_PDA2PHONE_RAW_START_ADDRESS) -#define DPRAM_PDA2PHONE_RAW_TAIL_ADDRESS (DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS + 0x0002) -#define DPRAM_PDA2PHONE_RAW_BUFFER_ADDRESS (DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS + 0x0004) -#define DPRAM_PDA2PHONE_RAW_SIZE 3728 /*1BF0*/ - -#define DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS (DPRAM_PDA2PHONE_RAW_START_ADDRESS + (DPRAM_PDA2PHONE_RAW_SIZE + 4)) -#define DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS) -#define DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS + 0x0002) -#define DPRAM_PHONE2PDA_FORMATTED_BUFFER_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS + 0x0004) -#define DPRAM_PHONE2PDA_FORMATTED_SIZE 1020 /* 0x03FC */ - -#define DPRAM_PHONE2PDA_RAW_START_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS + (DPRAM_PHONE2PDA_FORMATTED_SIZE + 4)) -#define DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS (DPRAM_PHONE2PDA_RAW_START_ADDRESS) -#define DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS (DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS + 0x0002) -#define DPRAM_PHONE2PDA_RAW_BUFFER_ADDRESS (DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS + 0x0004) -#define DPRAM_PHONE2PDA_RAW_SIZE 10576 /* 1BF0 */ - -#elif defined(CONFIG_MACH_OMNIA) -#define DPRAM_START_ADDRESS 0x0000 -#define DPRAM_MAGIC_CODE_ADDRESS (DPRAM_START_ADDRESS) -#define DPRAM_ACCESS_ENABLE_ADDRESS (DPRAM_START_ADDRESS + 0x0002) - -#define DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS (DPRAM_START_ADDRESS + 0x0004) -#define DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS) -#define DPRAM_PDA2PHONE_FORMATTED_TAIL_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS + 0x0002) -#define DPRAM_PDA2PHONE_FORMATTED_BUFFER_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS + 0x0004) -#define DPRAM_PDA2PHONE_FORMATTED_SIZE 1020 /* 0x03FC */ - -#define DPRAM_PDA2PHONE_RAW_START_ADDRESS (DPRAM_START_ADDRESS + 0x0404) -#define DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS (DPRAM_PDA2PHONE_RAW_START_ADDRESS) -#define DPRAM_PDA2PHONE_RAW_TAIL_ADDRESS (DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS + 0x0002) -#define DPRAM_PDA2PHONE_RAW_BUFFER_ADDRESS (DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS + 0x0004) -#define DPRAM_PDA2PHONE_RAW_SIZE 7152 /*1BF0*/ - -#define DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS (DPRAM_START_ADDRESS + 0x1FF8) -#define DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS) -#define DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS + 0x0002) -#define DPRAM_PHONE2PDA_FORMATTED_BUFFER_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS + 0x0004) -#define DPRAM_PHONE2PDA_FORMATTED_SIZE 1020 /* 0x03FC */ - -#define DPRAM_PHONE2PDA_RAW_START_ADDRESS (DPRAM_START_ADDRESS + 0x23F8) -#define DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS (DPRAM_PHONE2PDA_RAW_START_ADDRESS) -#define DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS (DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS + 0x0002) -#define DPRAM_PHONE2PDA_RAW_BUFFER_ADDRESS (DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS + 0x0004) -#define DPRAM_PHONE2PDA_RAW_SIZE 7152 /* 1BF0 */ -#endif /* CONFIG_MACH_MIRAGE || CONFIG_MACH_OMNIA */ - -/* indicator area*/ -#define DPRAM_INDICATOR_START (DPRAM_START_ADDRESS + 0x3FEC) -#define DPRAM_INDICATOR_SIZE 16 - -//#define DPRAM_PDA2PHONE_INTERRUPT_ADDRESS (DPRAM_START_ADDRESS + 0x3FFC) -//#define DPRAM_PHONE2PDA_INTERRUPT_ADDRESS (DPRAM_START_ADDRESS + 0x3FFE) -#define DPRAM_PDA2PHONE_INTERRUPT_ADDRESS (DPRAM_START_ADDRESS + 0x3FFE) -#define DPRAM_PHONE2PDA_INTERRUPT_ADDRESS (DPRAM_START_ADDRESS + 0x3FFC) -#define DPRAM_INTERRUPT_PORT_SIZE 2 - -#ifndef DPRAM_VBASE -#define DPRAM_VBASE 0xF0000000 -#endif /* DPRAM_VBASE */ - -/* - * interrupt masks. - */ -#define INT_MASK_VALID 0x0080 -#define INT_MASK_COMMAND 0x0040 -#define INT_MASK_REQ_ACK_F 0x0020 -#define INT_MASK_REQ_ACK_R 0x0010 -#define INT_MASK_RES_ACK_F 0x0008 -#define INT_MASK_RES_ACK_R 0x0004 -#define INT_MASK_SEND_F 0x0002 -#define INT_MASK_SEND_R 0x0001 - -#define INT_MASK_CMD_INIT_START 0x0001 -#define INT_MASK_CMD_INIT_END 0x0002 -#define INT_MASK_CMD_REQ_ACTIVE 0x0003 -#define INT_MASK_CMD_RES_ACTIVE 0x0004 -#define INT_MASK_CMD_REQ_TIME_SYNC 0x0005 -#define INT_MASK_CMD_PHONE_START 0x0008 -#define INT_MASK_CMD_ERR_DISPLAY 0x0009 -#define INT_MASK_CMD_PHONE_DEEP_SLEEP 0x000A -#define INT_MASK_CMD_NV_REBUILDING 0x000B -#define INT_MASK_CMD_EMER_DOWN 0x000C - -#define INT_COMMAND(x) (INT_MASK_VALID | INT_MASK_COMMAND | x) -#define INT_NON_COMMAND(x) (INT_MASK_VALID | x) - -#define FORMATTED_INDEX 0 -#define RAW_INDEX 1 -#define MAX_INDEX 2 - -/* ioctl command definitions. */ -#define IOC_MZ_MAGIC ('h') -#define HN_DPRAM_PHONE_ON _IO(IOC_MZ_MAGIC, 0xd0) -#define HN_DPRAM_PHONE_OFF _IO(IOC_MZ_MAGIC, 0xd1) -#define HN_DPRAM_PHONE_GETSTATUS _IOR(IOC_MZ_MAGIC, 0xd2, unsigned int) - -/* - * structure definitions. - */ -typedef struct dpram_serial { - /* pointer to the tty for this device */ - struct tty_struct *tty; - - /* number of times this port has been opened */ - int open_count; - - /* locks this structure */ - struct semaphore sem; -} dpram_serial_t; - -typedef struct dpram_device { - /* DPRAM memory addresses */ - unsigned long in_head_addr; - unsigned long in_tail_addr; - unsigned long in_buff_addr; - unsigned long in_buff_size; - - unsigned long out_head_addr; - unsigned long out_tail_addr; - unsigned long out_buff_addr; - unsigned long out_buff_size; - - u_int16_t mask_req_ack; - u_int16_t mask_res_ack; - u_int16_t mask_send; - - dpram_serial_t serial; -} dpram_device_t; - -typedef struct dpram_tasklet_data { - dpram_device_t *device; - u_int16_t non_cmd; -} dpram_tasklet_data_t; - -#ifdef CONFIG_EVENT_LOGGING -typedef struct event_header { - struct timeval timeVal; - __u16 class; - __u16 repeat_count; - __s32 payload_length; -} EVENT_HEADER; -#endif - -/* TODO: add more definitions */ - -#endif /* __DPRAM_H__ */ - diff --git a/drivers/char/dpram/dprintk.h b/drivers/char/dpram/dprintk.h deleted file mode 100755 index afea67004c7e..000000000000 --- a/drivers/char/dpram/dprintk.h +++ /dev/null @@ -1,76 +0,0 @@ -/***************************************************************************** -** COPYRIGHT(C) : Samsung Electronics Co.Ltd, 2006-2011 ALL RIGHTS RESERVED -*****************************************************************************/ -#ifndef DEBUGPRINTF_H -#define DEBUGPRINTF_H - -extern unsigned long long iPrintFlag; -extern int debug_check(unsigned int flag); - -#define dprintk(x, y...) debug_check(x) ? printk("["#x"] "y) : 0 -/* flag defintion for MODULE (can be ORed) */ -#define DCM_ERR 0x0000000000000001 -#define DCM_INP 0x0000000000000002 -#define DCM_OUT 0x0000000000000004 -#define DCM_DET 0x0000000000000008 - -#define PWR_ERR 0x0000000000000010 -#define PWR_WRN 0x0000000000000020 -#define PWR_DBG 0x0000000000000040 -#define PWR_INF 0x0000000000000080 - -#define CAM_ERR 0x0000000000000100 -#define CAM_WRN 0x0000000000000200 -#define CAM_DBG 0x0000000000000400 -#define CAM_INF 0x0000000000000800 - -#define LCD_ERR 0x0000000000001000 -#define LCD_WRN 0x0000000000002000 -#define LCD_DBG 0x0000000000004000 -#define LCD_INF 0x0000000000008000 - -#define SND_ERR 0x0000000000010000 -#define SND_WRN 0x0000000000020000 -#define SND_DBG 0x0000000000040000 -#define SND_INF 0x0000000000080000 - -#define DPR_ERR 0x0000000000100000 -#define DPR_WRN 0x0000000000200000 -#define DPR_DBG 0x0000000000400000 -#define DPR_INF 0x0000000000800000 - -#define PDP_ERR 0x0000000001000000 -#define PDP_WRN 0x0000000002000000 -#define PDP_DBG 0x0000000004000000 -#define PDP_INF 0x0000000008000000 - -#define USB_ERR 0x0000000010000000 -#define USB_WRN 0x0000000020000000 -#define USB_DBG 0x0000000040000000 -#define USB_INF 0x0000000080000000 - -#define BLZ_ERR 0x0000000100000000 -#define BLZ_WRN 0x0000000200000000 -#define BLZ_DBG 0x0000000400000000 -#define BLZ_INF 0x0000000800000000 - -#define WLN_ERR 0x0000001000000000 -#define WLN_WRN 0x0000002000000000 -#define WLN_DBG 0x0000004000000000 -#define WLN_INF 0x0000008000000000 - -#define MMC_ERR 0x0000010000000000 -#define MMC_WRN 0x0000020000000000 -#define MMC_DBG 0x0000040000000000 -#define MMC_INF 0x0000080000000000 - -#define FS_ERR 0x0000100000000000 -#define FS_UFD 0x0000200000000000 -#define FS_ZFTL 0x0000400000000000 -#define FS_EXT3 0x0000800000000000 - -#define OOM_ERR 0x0001000000000000 -#define OOM_WRN 0x0002000000000000 -#define OOM_DBG 0x0004000000000000 -#define OOM_INF 0x0008000000000000 -#endif diff --git a/drivers/char/dpram/ipcmux.c b/drivers/char/dpram/ipcmux.c deleted file mode 100755 index 19f12f2eaa40..000000000000 --- a/drivers/char/dpram/ipcmux.c +++ /dev/null @@ -1,1611 +0,0 @@ -/****************************************************************************** -******************************************************************************* -* -* This is MUX/DEMUX driver for samsung IPC -* -****************************************************************************** -******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -/****************************************************************************** -******************************************************************************* -* -* DEBUG -* -****************************************************************************** -******************************************************************************/ - -//#define IPCMUX_MSGWARN -//#define IPCMUX_MSGHIGH -//#define IPCMUX_MSGLOW -//#define IPCMUX_HEXDUMP - -#define TXIPC 1 -#define TXHDLC 2 -#define RXHDLC 3 -#define RXIPC 4 - - -#ifdef IPCMUX_MSGWARN -#define MSG_WARN(X...) \ - do { \ - printk("[IPCMUX WARNING] [%s():%d]", __FUNCTION__, __LINE__); \ - printk(X); \ - } while (0) -#else -#define MSG_WARN(X...) do { } while (0) -#endif - -#ifdef IPCMUX_MSGHIGH -#define MSG_HIGH(X...) \ - do { \ - printk("[IPCMUX] [%s():%d] ", __FUNCTION__, __LINE__); \ - printk(X); \ - } while (0) -#else -#define MSG_HIGH(X...) do { } while (0) -#endif - -#ifdef IPCMUX_MSGLOW -#define MSG_LOW(X...) \ - do { \ - printk("[IPCMUX] [%s():%d] ", __FUNCTION__, __LINE__); \ - printk(X); \ - } while (0) -#else -#define MSG_LOW(X...) do { } while (0) -#endif - -#ifdef IPCMUX_HEXDUMP -int ipcmux_dump(const char *buf, int len, int direction) -{ - char str[80], octet[10]; - int ofs, i, k; - printk( "=============================================================================\n"); - - switch(direction) - { - case TXIPC: - printk( "============= [IPCMUX] APP --> MUX : %03d bytes ==============\n", len); - break; - - case TXHDLC: - printk( "============= [IPCMUX] MUX --> DPRAM : %03d bytes ==============\n", len); - break; - - case RXHDLC: - printk( "============= [IPCMUX] MUX <-- DPRAM : %03d bytes ==============\n", len); - break; - - case RXIPC: - printk( "============= [IPCMUX] APP <-- MUX : %03d bytes ==============\n", len); - break; - } - - for (ofs = 0; ofs < len; ofs += 16) - { - sprintf( str, "%03d:", ofs ); - - for (i = 0; i < 16; i++) - { - if ((i + ofs) < len) - sprintf( octet, "[%02x]", buf[ofs + i] ); - else - strcpy( octet, " " ); - strcat( str, octet ); - } - strcat( str, " " ); - k = strlen( str ); - - str[k] = '\0'; - printk( "[IPCMUX] %s\n", str ); - } - printk( "=============================================================================\n"); - - return 0; -} -#else -int ipcmux_dump(const char *buf, int len, int direction) -{ - return 0; -} -#endif - - - -/********************************************************************************************* -********************************************************************************************** -* -* Global Variables & Structures -* -********************************************************************************************** -**********************************************************************************************/ - -/*********************************************************************************************/ -/* H D L C F O R M A T */ -/*-------------------------------------------------------------------------------------------- - | Start_Flag(0x7F) | LENGTH(2) | CONTROL(1) | IPC-MESSAGE(x) | Stop_Flag(0x7E) | - --------------------------------------------------------------------------------------------*/ -/*********************************************************************************************/ - -/*********************************************************************************************/ -/* G S M I P C M E S S A G E F O R M A T */ -/*-------------------------------------------------------------------------------------------- - | LENGTH(2) | MSG_SEQ(1) | ACK_SEQ(1) | MAIN_CMD(1) | SUB_CMD(1) | CMD_TYPE(1) | PARAMETER(x) | - -------------------------------------------------------------------------------------------*/ -/*********************************************************************************************/ - - - - -#define IPC_HEADER_SIZE 7 -#define HDLC_FRAME_HEADER_SIZE 3 -#define MAX_HDLC_INFO_SIZE 1000 -#define MAX_HDLC_FRAME_SIZE (MAX_HDLC_INFO_SIZE + HDLC_FRAME_HEADER_SIZE) -#define MAX_HDLC_FRAME_SIZE_WITH_FLAGS (MAX_HDLC_FRAME_SIZE + 2) -#define START_FLAG 0x7F -#define END_FLAG 0x7E - -#define APP_DEVNAME "ipcmux" -#define DPRAM_DEVNAME "/dev/dpram0" - -/* DPRAM ioctls for DPRAM tty devices */ -#define IOC_MZ_MAGIC ('h') -#define HN_DPRAM_PHONE_ON _IO(IOC_MZ_MAGIC, 0xd0) -#define HN_DPRAM_PHONE_OFF _IO(IOC_MZ_MAGIC, 0xd1) -#define HN_DPRAM_PHONE_GETSTATUS _IOR(IOC_MZ_MAGIC, 0xd2, unsigned int) - - - - -/* Type definition for IPC Header */ -typedef struct { - unsigned short len; - unsigned char msg_seq; - unsigned char ack_seq; - unsigned char main_cmd; - unsigned char sub_cmd; - unsigned char cmd_type; -} __attribute__((packed)) ipc_hdr_t; - - -typedef enum { - IPC_GSM_PWR_CMD=0x01, /* 0x01 : Power Control Commands */ - IPC_GSM_CALL_CMD, /* 0x02 : Call Control Commands */ - IPC_GSM_DATA_CMD, /* 0x03 : Data Control Commands */ - IPC_GSM_SMS_CMD, /* 0x04 : Short Message Service Commands */ - IPC_GSM_SEC_CMD, /* 0x05 : Security - SIM control Commands */ - IPC_GSM_PB_CMD, /* 0x06 : Phonebook Control Commands */ - IPC_GSM_DISP_CMD, /* 0x07 : Display Control Commands */ - IPC_GSM_NET_CMD, /* 0x08 : Network Commands */ - IPC_GSM_SND_CMD, /* 0x09 : Sound Control Commands */ - IPC_GSM_MISC_CMD, /* 0x0A : Miscellaneous Control Commands */ - IPC_GSM_SVC_CMD, /* 0x0B : Service Mode Control Commands - Factory Test or Debug Screen Control */ - IPC_GSM_SS_CMD, /* 0x0C : Supplementary Service Control Command */ - IPC_GSM_GPRS_CMD, /* 0x0D : GPRS(AT Command to IPC) Commands */ - IPC_GSM_SAT_CMD, /* 0x0E : SIM Toolkit Commands */ - IPC_GSM_CFG_CMD, /* 0x0F : Configuration Commands */ - IPC_GSM_IMEI_CMD, /* 0x10 : IMEI Tool Commands */ - IPC_GSM_GPS_CMD, /* 0x11 : GPSl Commands */ - IPC_GSM_SAP_CMD, /* 0x12 : SIM Access Profile Commands */ - IPC_GSM_GEN_CMD=0x80, /* 0x80 : General Response Command */ - IPC_GSM_CMD_MAX -} ipc_main_cmd_t; - -typedef struct { - unsigned char m_StartMagicCode; - unsigned short m_Length; - unsigned char m_CtrlInfo; // control information id - void* m_pValue; - unsigned char m_EndMagicCode; -} HDLCFrame_t; - -// For multi HDLC frame. -typedef struct tagHDLCNode -{ - struct tagHDLCNode* m_pNext; - HDLCFrame_t m_HDLCNode; - -} HDLCNode_t; - -static HDLCFrame_t s_FrameRecvInfo = {0, }; -static HDLCNode_t* g_pHead = NULL; -static HDLCNode_t* g_pTail = NULL; - - - -typedef struct { - unsigned char id; - char ifname[16]; -} __attribute__ ((packed)) vsc_arg_t; - -typedef struct { - u_int8_t id; - u_int8_t* tx_buf; - struct tty_driver mux_tty_driver; - int open_count; - char tty_name[16]; - struct tty_struct* tty; -// struct semaphore write_lock; // if need, we will add sem. -} dev_info_t; - -//#define MAX_CHANNEL_NUMBER 3 -#define MAX_CHANNEL_NUMBER 2 -#define CHANNEL_ID_1 1 -#define CHANNEL_ID_2 2 -//#define CHANNEL_ID_3 3 - -static vsc_arg_t g_vsc_arg[MAX_CHANNEL_NUMBER]= -{ - {CHANNEL_ID_1, "ttyTEL"}, - {CHANNEL_ID_2, "ttyDNET"}, -// {CHANNEL_ID_3, "ttySIM"}, -}; - -static dev_info_t* dev_table[MAX_CHANNEL_NUMBER]; - - - - - - -static DECLARE_MUTEX(dev_lock); - -static struct task_struct *dpram_task; -static struct file *dpram_filp; -static DECLARE_COMPLETION(dpram_complete); - -extern void dpram_phone_on(void); -extern void dpram_phone_off(void); -extern unsigned int dpram_phone_getstatus(void); - -static int ipc_mux(dev_info_t *dev, const void *data, size_t len ); -static int ipc_demux(void); - - -static int vsc_read(dev_info_t *dev, unsigned char* pdata, int len); - - -/***************************************************************************** -****************************************************************************** -* -* device table functions -* -****************************************************************************** -******************************************************************************/ - -static inline dev_info_t * devtbl_get_dev_by_id(u_int8_t id) -{ - int slot; - dev_info_t *dev = NULL; - - MSG_LOW("enter \n"); - - for (slot = 0; slot < MAX_CHANNEL_NUMBER; slot++) { - if (dev_table[slot] && dev_table[slot]->id == id) { - dev = dev_table[slot]; - up(&dev_lock); - return dev; - } - } - return NULL; -} - -static inline dev_info_t * devtbl_get_dev_by_name(const char *name) -{ - int slot; - dev_info_t *dev; - - MSG_LOW("enter\n"); - - for (slot = 0; slot < MAX_CHANNEL_NUMBER; slot++) { - dev = dev_table[slot]; - if (dev && strcmp(name, dev->tty_name) == 0) { - up(&dev_lock); - return dev; - } - } - return NULL; -} - -static inline int devtbl_add_dev(dev_info_t *dev) -{ - int slot; - - MSG_LOW("enter \n"); - - if (devtbl_get_dev_by_id(dev->id)) { - return -EBUSY; - } - - for (slot = 0; slot < MAX_CHANNEL_NUMBER; slot++) { - if (dev_table[slot] == NULL) { - dev_table[slot] = dev; - up(&dev_lock); - return slot; - } - } - return -ENOSPC; -} - -static inline dev_info_t * devtbl_remove_dev_by_id(u_int8_t id) -{ - int slot; - dev_info_t *dev; - - MSG_LOW("enter \n"); - - for (slot = 0; slot < MAX_CHANNEL_NUMBER; slot++) { - if (dev_table[slot] && dev_table[slot]->id == id) { - dev = dev_table[slot]; - dev_table[slot] = NULL; - up(&dev_lock); - return dev; - } - } - return NULL; -} - -static inline dev_info_t * devtbl_remove_dev_by_slot(int slot) -{ - dev_info_t *dev; - - MSG_LOW("enter \n"); - - dev = dev_table[slot]; - dev_table[slot] = NULL; - return dev; -} - - - -/***************************************************************************** -****************************************************************************** -* -* hdlc functions -* -****************************************************************************** -******************************************************************************/ -/* === For MUX === */ -static unsigned char hdlc_get_control_infoid(void) -{ - static unsigned char s_infoid = 0; - - MSG_LOW("enter \n"); - - if (s_infoid >= 128) - s_infoid = 0; - ++s_infoid; - - return s_infoid; -} - - -/* === For DEMUX === */ -static void hdlc_clear_all_mfhdlc_nodes(void) -{ - HDLCNode_t* pnode_tmp; - HDLCNode_t* pnode = g_pHead; - - MSG_LOW("enter \n"); - - while (pnode) - { - pnode_tmp = pnode; - pnode = pnode->m_pNext; - - // free data - if (pnode_tmp->m_HDLCNode.m_pValue) - kfree(pnode_tmp->m_HDLCNode.m_pValue); - - kfree(pnode_tmp); - } - - g_pHead = g_pTail = NULL; - -} - - -static int hdlc_push_mfhdlc(HDLCFrame_t const* pframe) -{ - HDLCNode_t* pnode = NULL; - - MSG_LOW("enter \n"); - - if (!pframe){ - MSG_WARN("HDLC frame is NULL\n"); - return -1; - } - - - pnode = kmalloc(sizeof(HDLCNode_t), GFP_KERNEL); - if (pnode == NULL) { - MSG_WARN("out of memory\n"); - return -ENOMEM; - } - memset(pnode, 0, sizeof(HDLCNode_t)); - - - pnode->m_HDLCNode.m_Length = pframe->m_Length; - pnode->m_HDLCNode.m_CtrlInfo = pframe->m_CtrlInfo; - - if ((pframe->m_Length - HDLC_FRAME_HEADER_SIZE) > 0) - { - pnode->m_HDLCNode.m_pValue = kmalloc(pframe->m_Length - HDLC_FRAME_HEADER_SIZE, GFP_KERNEL); - if (pnode->m_HDLCNode.m_pValue == NULL) { - MSG_WARN("out of memory\n"); - return -ENOMEM; - } - memcpy(pnode->m_HDLCNode.m_pValue, pframe->m_pValue, pframe->m_Length - HDLC_FRAME_HEADER_SIZE); - } - - if (!g_pHead) - { - g_pHead = pnode; - } - else - { - if (g_pTail) - { - g_pTail->m_pNext = pnode; - } - } - - g_pTail = pnode; - - return 0; - -} - - - - -static HDLCFrame_t const* hdlc_get_last_mfhdlc(void) -{ - MSG_LOW("enter \n"); - - if (g_pTail) - { - return &(g_pTail->m_HDLCNode); - } - else - { - // Do nothing... - } - - return NULL; -} - - - - -/* Extract an IPC Message from Multi HDLC Frame */ -static unsigned char* hdlc_extract_ipc_from_mfhdlc(void) -{ - unsigned char* pipc_data = NULL; - unsigned char* ptr = NULL; - int ipc_size = 0; - HDLCNode_t* pnode = g_pHead; - - MSG_LOW("enter \n"); - - while (pnode) // calculate ipc length - { - ipc_size += pnode->m_HDLCNode.m_Length - HDLC_FRAME_HEADER_SIZE; - pnode = pnode->m_pNext; - } - - if (ipc_size > 0) - { - pipc_data = (unsigned char*)kmalloc(ipc_size, GFP_KERNEL); - if (pipc_data == NULL) { - MSG_WARN("out of memory\n"); - return NULL; - } - ptr = pipc_data; - pnode = g_pHead; - - while (pnode) - { - memcpy(ptr, pnode->m_HDLCNode.m_pValue, (pnode->m_HDLCNode.m_Length - HDLC_FRAME_HEADER_SIZE)); - - ptr += (pnode->m_HDLCNode.m_Length - HDLC_FRAME_HEADER_SIZE); - - pnode = pnode->m_pNext; - } - } - - hdlc_clear_all_mfhdlc_nodes(); - - return pipc_data; - -} - -static int hdlc_get_chid_from_ipc(unsigned char* pipc) -{ - int ch_id=0; - ipc_hdr_t ipc_hdr; - unsigned char ipc_rx_main_cmd; // for general response - - MSG_LOW("enter \n"); - - memcpy(&ipc_hdr, pipc, IPC_HEADER_SIZE); - - switch (ipc_hdr.main_cmd) - { - case IPC_GSM_PWR_CMD: - case IPC_GSM_CALL_CMD: - case IPC_GSM_SMS_CMD: - case IPC_GSM_DISP_CMD: - case IPC_GSM_NET_CMD: - case IPC_GSM_SND_CMD: - case IPC_GSM_MISC_CMD: - case IPC_GSM_SVC_CMD: - case IPC_GSM_SS_CMD: - case IPC_GSM_CFG_CMD: - case IPC_GSM_IMEI_CMD: - case IPC_GSM_GPS_CMD: - ch_id = CHANNEL_ID_1; - break; - - case IPC_GSM_DATA_CMD: - case IPC_GSM_GPRS_CMD: - ch_id = CHANNEL_ID_2; - break; - - case IPC_GSM_SEC_CMD: - case IPC_GSM_PB_CMD: - case IPC_GSM_SAT_CMD: - case IPC_GSM_SAP_CMD: - ch_id = CHANNEL_ID_1; - break; - - case IPC_GSM_GEN_CMD: - memcpy(&ipc_rx_main_cmd, pipc+IPC_HEADER_SIZE, 1); - switch(ipc_rx_main_cmd) - { - case IPC_GSM_PWR_CMD: - case IPC_GSM_CALL_CMD: - case IPC_GSM_SMS_CMD: - case IPC_GSM_DISP_CMD: - case IPC_GSM_NET_CMD: - case IPC_GSM_SND_CMD: - case IPC_GSM_MISC_CMD: - case IPC_GSM_SVC_CMD: - case IPC_GSM_SS_CMD: - case IPC_GSM_CFG_CMD: - case IPC_GSM_IMEI_CMD: - case IPC_GSM_GPS_CMD: - ch_id = CHANNEL_ID_1; - break; - - case IPC_GSM_DATA_CMD: - case IPC_GSM_GPRS_CMD: - ch_id = CHANNEL_ID_2; - break; - - case IPC_GSM_SEC_CMD: - case IPC_GSM_PB_CMD: - case IPC_GSM_SAT_CMD: - case IPC_GSM_SAP_CMD: - ch_id = CHANNEL_ID_1; - break; - - default: - MSG_WARN("unknown IPC RX MAIN CMD FOR GEN CMD : 0x%02x\n", ipc_rx_main_cmd); - ch_id = CHANNEL_ID_1; // unknown cmd is sent to Telephony. - break; - } - break; - - - - default: - MSG_WARN("unknown IPC MAIN CMD : 0x%02x\n", ipc_hdr.main_cmd); - ch_id = CHANNEL_ID_1; // unknown cmd is sent to Telephony. - break; - - } - - return ch_id; - -} - - - -/* Extract an IPC Packet from SFHDLC Frame or MFHDLC Frames */ -static unsigned char* hdlc_extract_ipc(HDLCFrame_t const* pframe) -{ - unsigned char *pipc; - - MSG_LOW("enter \n"); - - if (pframe->m_CtrlInfo & 0x80) - { - MSG_HIGH("This is MFHDLC frame!!\n"); - hdlc_push_mfhdlc(pframe); - return NULL; - } - else - { - HDLCFrame_t const* plast_info; - HDLCFrame_t const* plast_multi_info; - - plast_info = &s_FrameRecvInfo; - plast_multi_info = hdlc_get_last_mfhdlc(); - - /* MFHDLC */ - if (plast_multi_info && plast_info && ( (plast_multi_info->m_CtrlInfo & 0x7f) == (plast_info->m_CtrlInfo & 0x7f))) - { - MSG_HIGH("Making IPC from MF-HDLC..\n"); - - pipc = hdlc_extract_ipc_from_mfhdlc(); - return pipc; - - } - - /* SFHDLC */ - else - { - if (pframe->m_Length >= 10) - { - pipc = (unsigned char *) pframe->m_pValue; - return pipc; - } - else - { - MSG_WARN("IPC Packet is NULL\n"); - return NULL; - } - } - } - -} - - - - -/***************************************************************************** -****************************************************************************** -* -* dpram functions -* -****************************************************************************** -******************************************************************************/ - -static inline struct file *dpram_open(void) -{ - int ret = 0; - struct file *filp; - struct termios termios; - mm_segment_t oldfs; - - MSG_LOW("enter \n"); - - filp = filp_open(DPRAM_DEVNAME, O_RDWR, 0); - if (IS_ERR(filp)) { - MSG_LOW("filp_open() failed~!: %ld\n", PTR_ERR(filp)); - return NULL; - } - oldfs = get_fs(); set_fs(get_ds()); - ret = filp->f_op->unlocked_ioctl(filp, - TCGETA, (unsigned long)&termios); - set_fs(oldfs); - if (ret < 0) { - MSG_LOW("f_op->ioctl() failed: %d\n", ret); - filp_close(filp, current->files); - return NULL; - } - termios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL | B115200; - termios.c_iflag = IGNBRK | IGNPAR; - termios.c_lflag = 0; - termios.c_oflag = 0; - termios.c_cc[VMIN] = 1; - termios.c_cc[VTIME] = 1; - - oldfs = get_fs(); set_fs(get_ds()); - ret = 0; - ret = filp->f_op->unlocked_ioctl(filp, - TCSETA, (unsigned long)&termios); - set_fs(oldfs); - if (ret < 0) { - MSG_LOW("f_op->ioctl() failed: %d\n", ret); - filp_close(filp, current->files); - return NULL; - } - - return filp; -} - -static inline void dpram_close(struct file *filp) -{ - MSG_LOW("enter \n"); - - filp_close(filp, current->files); -} - -static inline int dpram_poll(struct file *filp) -{ - int ret; - unsigned int mask; - struct poll_wqueues wait_table; - mm_segment_t oldfs; - - MSG_LOW("enter \n"); - - poll_initwait(&wait_table); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - - oldfs = get_fs(); set_fs(get_ds()); - mask = filp->f_op->poll(filp, &wait_table.pt); - set_fs(oldfs); - - if (mask & POLLIN) { - ret = 0; - break; - } - - if (wait_table.error) { - MSG_LOW( "error in f_op->poll()\n"); - ret = wait_table.error; - break; - } - - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - schedule(); - } - set_current_state(TASK_RUNNING); - poll_freewait(&wait_table); - - return ret; -} - -static inline int dpram_write(struct file *filp, const void *buf, size_t count, int nonblock) -{ - int ret, n = 0; - mm_segment_t oldfs; - - MSG_LOW("enter \n"); - - ipcmux_dump(buf, count, TXHDLC); - - while (count) { - if (!dpram_filp) { - MSG_LOW( "DPRAM not available\n"); - return -ENODEV; - } - - if (nonblock) dpram_filp->f_flags |= O_NONBLOCK; - oldfs = get_fs(); set_fs(get_ds()); - ret = filp->f_op->write(filp, buf + n, count, &filp->f_pos); - set_fs(oldfs); - if (nonblock) dpram_filp->f_flags &= ~O_NONBLOCK; - if (ret < 0) { - if (ret == -EAGAIN && !nonblock) { - continue; - } - return ret; - } - n += ret; - count -= ret; - } - return n; -} - -static inline int dpram_read(struct file *filp, void *buf, size_t count) -{ - int ret, n = 0; - mm_segment_t oldfs; - - MSG_LOW("enter \n"); - - while (count) { - oldfs = get_fs(); set_fs(get_ds()); - ret = filp->f_op->read(filp, buf + n, count, &filp->f_pos); - set_fs(oldfs); - if (ret < 0) { - if (ret == -EAGAIN) continue; - MSG_LOW("f_op->read() failed: %d\n", ret); - return ret; - } - n += ret; - count -= ret; - } - return n; -} - -static int dpram_thread(void *data) -{ - int ret = 0; - struct file *filp; - - MSG_LOW("enter \n"); - - dpram_task = current; - - daemonize("dpram_thread"); - - strcpy(current->comm, "ipcmux"); - - siginitsetinv(¤t->blocked, sigmask(SIGUSR1)); - recalc_sigpending(); - - filp = dpram_open(); - if (filp == NULL) - goto out; - - dpram_filp = filp; - - complete(&dpram_complete); - - while (1) { - ret = dpram_poll(filp); - - if (ret == -ERESTARTSYS) { - if (sigismember(¤t->pending.signal, SIGUSR1)) { - MSG_LOW("got SIGUSR1 signal\n"); - sigdelset(¤t->pending.signal, SIGUSR1); - recalc_sigpending(); - ret = 0; - break; - } - } else if (ret < 0) { - MSG_WARN("dpram_poll() failed\n"); - break; - } else { - ret = ipc_demux(); - if (ret < 0) { - MSG_WARN("ipc_demux() failed\n"); - } - } - - try_to_freeze(); - } - - dpram_close(filp); - dpram_filp = NULL; -out: - dpram_task = NULL; - complete_and_exit(&dpram_complete, ret); -} - -static int vsc_open(struct tty_struct *tty, struct file *filp) -{ - dev_info_t *dev; - - MSG_LOW("enter \n"); - - down(&dev_lock); - dev = devtbl_get_dev_by_name(tty->driver->name); - if (dev == NULL) { - up(&dev_lock); - return -ENODEV; - } - if (dev->open_count > 0) { - MSG_WARN("%s has been already opened!!\n", dev->tty_name); - up(&dev_lock); - //return 0; // jspark test!!! - return -EBUSY; - } - dev->open_count = 1; - tty->driver_data = (void *)dev; - tty->low_latency = 1; - dev->tty = tty; - up(&dev_lock); - - return 0; -} - -static void vsc_close(struct tty_struct *tty, struct file *filp) -{ - dev_info_t *dev; - - MSG_LOW("enter \n"); - MSG_HIGH("ifname:[%s] \n",tty->driver->name); - - down(&dev_lock); - dev = devtbl_get_dev_by_name(tty->driver->name); - if (dev != NULL){ - dev->open_count = 0; - dev->tty = NULL; - } - up(&dev_lock); -} - - -static int vsc_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - int ret; - - dev_info_t *dev = (dev_info_t *)tty->driver_data; - - if(!dev) - return -ENODEV; - - MSG_LOW("enter \n"); - - MSG_HIGH("channel id: %u, count: %d\n",dev->id, count); - - ipcmux_dump(buf, count, TXIPC); - - ret = ipc_mux(dev, buf, count); - if (ret == 0) - { - ret = count; - } - - return ret; -} -static int vsc_read(dev_info_t *dev, unsigned char* pdata, int len) -{ - struct tty_struct *tty = dev->tty; - - int alloc_buffer_size = 0 ; - int remain_read_size = len ; - - int offset =0; - unsigned char *char_buf_ptr; - - MSG_LOW("enter \n"); - - MSG_HIGH("channel id: %u, count: %d\n",dev->id, len); - ipcmux_dump(pdata, len, RXIPC); - - do { - if (tty){ - char_buf_ptr = NULL; - alloc_buffer_size=tty_prepare_flip_string(tty, &char_buf_ptr, remain_read_size) ; - MSG_LOW("offset=%d, remain_read_size=%d, alloc_buffer_size=%d \n", offset, remain_read_size, alloc_buffer_size); - - remain_read_size -= alloc_buffer_size ; - - memcpy(char_buf_ptr, pdata+offset, alloc_buffer_size); - offset += alloc_buffer_size; - - tty_flip_buffer_push(tty); - } - else{ - MSG_WARN("no tty!!\n"); - remain_read_size=0; - } - } while (remain_read_size > 0) ; - - return 0; -} - -static int vsc_write_room(struct tty_struct *tty) -{ - MSG_LOW("enter \n"); - - return N_TTY_BUF_SIZE; -// return TTY_FLIPBUF_SIZE; -} - -static int vsc_chars_in_buffer(struct tty_struct *tty) -{ - MSG_LOW("enter \n"); - - return 0; -} - -static int vsc_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) -{ - mm_segment_t oldfs; - int ret; - - MSG_LOW("enter \n"); - - MSG_LOW("ioctl command: 0x%04x\n", cmd); - - switch (cmd) - { - case HN_DPRAM_PHONE_ON: - MSG_LOW("HN_DPRAM_PHONE_ON\n"); - - oldfs = get_fs(); set_fs(get_ds()); - ret = dpram_filp->f_op->unlocked_ioctl(dpram_filp,cmd, arg); - set_fs(oldfs); - - return ret; - - case HN_DPRAM_PHONE_OFF: - MSG_LOW("HN_DPRAM_PHONE_OFF\n"); - - oldfs = get_fs(); set_fs(get_ds()); - ret = dpram_filp->f_op->unlocked_ioctl(dpram_filp,cmd, arg); - set_fs(oldfs); - - return ret; - - - case HN_DPRAM_PHONE_GETSTATUS: - MSG_LOW("HN_DPRAM_PHONE_GETSTATUS\n"); - - oldfs = get_fs(); set_fs(get_ds()); - ret = dpram_filp->f_op->unlocked_ioctl(dpram_filp,cmd, arg); - set_fs(oldfs); - - return ret; - - default: - break; - } - - return -ENOIOCTLCMD; - -} - -static void vsc_break_ctl(struct tty_struct *tty, int break_state) -{ -} - - -static const struct tty_operations vsc_ops = -{ - .open = vsc_open, - .close = vsc_close, - .write = vsc_write, - .write_room = vsc_write_room, - .chars_in_buffer = vsc_chars_in_buffer, - .ioctl = vsc_ioctl, - .break_ctl = vsc_break_ctl, -}; - -static int vsc_register_dev(dev_info_t *dev) -{ - struct tty_driver *mux_tty_driver; - - MSG_LOW("enter \n"); - - mux_tty_driver = &dev->mux_tty_driver; - mux_tty_driver->minor_start = 0; - - mux_tty_driver->magic = TTY_DRIVER_MAGIC; - mux_tty_driver->driver_name = "ipcmux"; // unique name. (#cat /proc/tty/drivers) - mux_tty_driver->name = dev->tty_name; // node name. (# ls -al /dev/ or ls -al /sys/class/tty/) - mux_tty_driver->major = 0; // auto assinment - mux_tty_driver->num = 1; - mux_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - mux_tty_driver->subtype = SERIAL_TYPE_NORMAL; - mux_tty_driver->flags = TTY_DRIVER_REAL_RAW; - mux_tty_driver->ops = &vsc_ops; - mux_tty_driver->init_termios = tty_std_termios; // provides a set of line setting if the ports is used before it is initialized by a user - - return tty_register_driver(mux_tty_driver); - -} - -static void vsc_unregister_dev(dev_info_t *dev) -{ - struct tty_driver *mux_tty_driver = NULL; - - MSG_LOW("enter \n"); - - mux_tty_driver = &dev->mux_tty_driver; - - tty_unregister_driver(mux_tty_driver); -} - - - -static int ipc_mux(dev_info_t *dev, const void *data, size_t len) -{ - int ret; - - const unsigned char *ipc; - unsigned short ipc_len; - - unsigned char *tx_buf; - unsigned int tx_buf_len = 0; - - unsigned short hdlc_size; // hdlc_size = hdlc header size + info(ipc msg) size - unsigned char start_flag, end_flag, ctrl_info, mfhdlc_ctrl; - unsigned char endian_len[2] = {0,}; - int mfhdlc_info_current_len = 0; - int mfhdlc_info_remain_len = 0; - unsigned int offset = 0; - - MSG_LOW("enter \n"); - - tx_buf = dev->tx_buf; - ipc_len = (unsigned short)len; - - //TODO: when ipc_len isn't equal to real buf size..... - - - - - - /************************************************** - ******** Making HDLC Frame ******* - ***************************************************/ - - start_flag = START_FLAG; - end_flag = END_FLAG; - ctrl_info = 0; - hdlc_size = HDLC_FRAME_HEADER_SIZE + ipc_len; - - ctrl_info = hdlc_get_control_infoid(); - - /* SFHDLC */ - if (hdlc_size <= MAX_HDLC_FRAME_SIZE ) - { - ipc = data; - endian_len[0] = hdlc_size & 0x00ff; - endian_len[1] = (hdlc_size >> 8) & 0x00ff; - - offset = 0; - memcpy(tx_buf, &start_flag, 1); - offset = offset + 1; - memcpy(tx_buf+offset, &endian_len, 2); - offset = offset + 2; - memcpy(tx_buf+offset, &ctrl_info, 1); - offset = offset + 1; - memcpy(tx_buf+offset, ipc, ipc_len); - offset = offset + ipc_len; - memcpy(tx_buf+offset, &end_flag, 1); - offset = offset + 1; - tx_buf_len = offset; - - ret = dpram_write(dpram_filp, tx_buf, tx_buf_len, 1); - if (ret < 0) - { - MSG_HIGH("check plz.... ret:[%d]\n", ret); - return ret; - } - - - } - - /* MFHDLC */ - else - { - ipc = (unsigned char *)data; - MSG_HIGH("This is MFHDLC frame !!!!!\n"); - - mfhdlc_info_remain_len = ipc_len; - - while(mfhdlc_info_remain_len) - { - if (mfhdlc_info_remain_len > MAX_HDLC_INFO_SIZE) - { - mfhdlc_info_current_len = MAX_HDLC_INFO_SIZE; - mfhdlc_ctrl = (1 << 7) | ctrl_info; - hdlc_size = (unsigned short)MAX_HDLC_FRAME_SIZE ; - } - else - { - mfhdlc_info_current_len = mfhdlc_info_remain_len; - mfhdlc_ctrl = ctrl_info; - hdlc_size = (unsigned short)(mfhdlc_info_current_len + HDLC_FRAME_HEADER_SIZE); - } - - endian_len[0] = hdlc_size & 0x00ff; - endian_len[1] = (hdlc_size >> 8) & 0x00ff; - - - offset = 0; - memcpy(tx_buf, &start_flag, 1); - offset += 1; - memcpy(tx_buf+offset, &endian_len, 2); - offset += 2; - memcpy(tx_buf+offset, &mfhdlc_ctrl, 1); - offset += 1; - memcpy(tx_buf+offset, ipc, mfhdlc_info_current_len); - offset += mfhdlc_info_current_len; - memcpy(tx_buf+offset, &end_flag, 1); - offset += 1; - tx_buf_len = offset; - - ret = dpram_write(dpram_filp, tx_buf, tx_buf_len, 1); - if (ret < 0) - { - MSG_HIGH("check plz.... ret:[%d]\n", ret); - return ret; - } - - ipc += mfhdlc_info_current_len; - mfhdlc_info_remain_len -= mfhdlc_info_current_len; - - MSG_HIGH("writing hdlc info bytes:[%d], Remaining bytes [%d]\n", mfhdlc_info_current_len, mfhdlc_info_remain_len); - - } - - MSG_HIGH("Finished wriitng the MFHDLC to dpram\n"); - - } - - return 0; - -} - -static int ipc_demux(void) -{ - int ret; - int info_len=0; - char hdlc_len[2] = {0, }; - HDLCFrame_t frame = {0,}; - - dev_info_t *dev = NULL; - int ch_id; - unsigned char *pipc; - ipc_hdr_t ipc_hdr; - - MSG_LOW("enter \n"); - - /* STEP #1 : read start flag - 1byte && check for start flag == 0x7E */ - ret = dpram_read(dpram_filp, &(frame.m_StartMagicCode), 1); - if (ret < 0) { - MSG_WARN("dpram_read() failed: %d\n", ret); - return ret; - } - - if (frame.m_StartMagicCode != START_FLAG) - { - MSG_WARN("Invalid HDLC Frame Start flag : (0x7F != 0x%x)\n", frame.m_StartMagicCode); - return -1; - } - - - /* STEP #2 : Read the HDLC frame Len 2 Bytes . Low & High Byte */ - ret = dpram_read(dpram_filp, &(hdlc_len[0]), 1); - if (ret < 0) { - MSG_WARN("dpram_read() failed: %d\n", ret); - return ret; - } - ret = dpram_read(dpram_filp, &(hdlc_len[1]), 1); - if (ret < 0) { - MSG_WARN("dpram_read() failed: %d\n", ret); - return ret; - } - - /* copy the len to frame */ - memcpy(&(frame.m_Length), hdlc_len, 2); - if (frame.m_Length <= 0) - { - MSG_WARN("Invalid HDLC Frame Packet Length : %d\n ",frame.m_Length); - return -1; - } - - /* STEP #3: Read the Control Byte */ - ret = dpram_read(dpram_filp, &(frame.m_CtrlInfo), 1); - if (ret < 0) { - MSG_WARN("dpram_read() failed: %d\n", ret); - return ret; - } - - MSG_LOW("HDLC frame Length:[%d], control:[%02x] \n", frame.m_Length, frame.m_CtrlInfo); - - /* STEP #4: info_len = length - header len */ - info_len = frame.m_Length - HDLC_FRAME_HEADER_SIZE; - - /* STEP #5: read the data from dpram, and copy to frame data area. */ - if (info_len > 0) - { - /* allocate memory by data size */ - frame.m_pValue = kmalloc(info_len, GFP_KERNEL); - if (frame.m_pValue == NULL) { - MSG_WARN("out of memory\n"); - return -ENOMEM; - } - memset(frame.m_pValue, 0, info_len); - - /* read data from dpram */ - ret = dpram_read(dpram_filp, frame.m_pValue, info_len); - if (ret < 0) { - MSG_WARN("dpram_read() failed: %d\n", ret); - return ret; - } - - } - else - { - frame.m_pValue = NULL; - MSG_WARN("ipc len = 0 \n"); - } - - /* STEP #6: Read the End Flag 0x7E */ - ret = dpram_read(dpram_filp, &(frame.m_EndMagicCode), 1); - if (ret < 0) { - MSG_WARN("dpram_read() failed: %d\n", ret); - return ret; - } - - if (frame.m_EndMagicCode != END_FLAG) - { - MSG_WARN("Invalid HDLC Frame End Flag : (0x7E != 0x%x)\n", frame.m_EndMagicCode); - return -1; - } - - /*======== End of HDLC frame ========*/ - - /* save the last recv HDLC frame. */ - s_FrameRecvInfo.m_CtrlInfo = frame.m_CtrlInfo; - s_FrameRecvInfo.m_Length = frame.m_Length; - - - /* Make an IPC Packet now from HDLC frame */ - if (frame.m_pValue==NULL) - { - MSG_WARN("frame.m_pValue is NULL!!\n"); - return 0; - } - else - { - pipc= hdlc_extract_ipc(&frame); - - if(pipc == NULL) - return 0; // this is mfhdlc or ipc msg is NULL. - - memcpy(&ipc_hdr, pipc, IPC_HEADER_SIZE); - - ch_id =hdlc_get_chid_from_ipc(pipc); - - down(&dev_lock); - dev = devtbl_get_dev_by_id(ch_id); - if (dev == NULL) { - MSG_WARN("invalid channel id: %u\n", ch_id); - ret = -ENODEV; - goto err; - } - if (dev->tty == NULL) { - MSG_WARN("channel id(%u) has been closed. ignore data\n", ch_id); - ret = -1; - goto err; - } - - - ret = vsc_read(dev, pipc, ipc_hdr.len); - if (ret < 0) { - MSG_WARN("vsc_read() failed\n"); - goto err; - } - up(&dev_lock); - - kfree(frame.m_pValue); - - return 0; - - } - - -err: - - up(&dev_lock); - kfree(frame.m_pValue); - - return ret; -} - -static int ipcmux_activate(vsc_arg_t *vsc_arg) -{ - int ret; - dev_info_t *dev; - - MSG_LOW("vsc_arg->id:[%d], vsc_arg->ifname:[%s]\n", vsc_arg->id, vsc_arg->ifname); - - dev = kmalloc(sizeof(dev_info_t) + MAX_HDLC_FRAME_SIZE_WITH_FLAGS, GFP_KERNEL); // it has replaced alloc_tty_driver(). - if (dev == NULL) { - MSG_WARN("out of memory\n"); - return -ENOMEM; - } - memset(dev, 0, sizeof(dev_info_t)); - - dev->id = vsc_arg->id; - dev->tx_buf = (u_int8_t *)(dev + 1); - - //init_MUTEX(&dev->write_lock); - strcpy(dev->tty_name, vsc_arg->ifname); - - ret = vsc_register_dev(dev); - if (ret < 0) { // it has replaced put_tty_driver() - MSG_WARN("vsc_register_dev() failed\n"); - kfree(dev); - return ret; - } - - down(&dev_lock); - ret = devtbl_add_dev(dev); - if (ret < 0) { - MSG_WARN("devtbl_add_dev() failed\n"); - up(&dev_lock); - vsc_unregister_dev(dev); - kfree(dev); - return ret; - } - up(&dev_lock); - - MSG_LOW("%s(id: %u) serial device is created.\n", dev->mux_tty_driver.name, dev->id); - - return 0; -} - -static int ipcmux_deactivate(vsc_arg_t *vsc_arg) -{ - dev_info_t *dev = NULL; - - MSG_LOW("vsc_arg->id: %d\n", vsc_arg->id); - - down(&dev_lock); - dev = devtbl_get_dev_by_id(vsc_arg->id); - - if (dev == NULL) { - MSG_LOW("not found id: %u\n", vsc_arg->id); - up(&dev_lock); - return -EINVAL; - } - - devtbl_remove_dev_by_id(vsc_arg->id); - up(&dev_lock); - - MSG_LOW("%s(id: %u) serial device is removed\n", dev->mux_tty_driver.name, dev->id); - - vsc_unregister_dev(dev); - - kfree(dev); - - return 0; -} - -static void __exit ipcmux_cleanup(void) -{ - int slot; - dev_info_t *dev; - - MSG_LOW("enter \n"); - - - down(&dev_lock); - for (slot = 0; slot < MAX_CHANNEL_NUMBER; slot++) - { - dev = devtbl_remove_dev_by_slot(slot); - if (dev) - { - MSG_HIGH("%s(id: %u) serial device is removed\n", dev->mux_tty_driver.name, dev->id); - vsc_unregister_dev(dev); - kfree(dev); - } - } - up(&dev_lock); - -} - -static struct miscdevice ipcmux_dev = { - .minor = 133, // refer to miscdevice.h - .name = APP_DEVNAME, -}; - -static int ipcmux_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - char *p = page; - int len; - - p += sprintf(p, "ipcmux driver is created on (date : %s, time: %s)\n", __DATE__, __TIME__); - - down(&dev_lock); - for (len = 0; len < MAX_CHANNEL_NUMBER; len++) { - dev_info_t *dev = dev_table[len]; - if (!dev) continue; - - p += sprintf(p, - "name: %s\t, id: %-3u\n", - dev->tty_name, - dev->id); - } - up(&dev_lock); - - len = (p - page) - off; - if (len < 0) - len = 0; - - *eof = (len <= count) ? 1 : 0; - *start = page + off; - - return len; -} - - -static int __init ipcmux_init(void) -{ - int ret; - int i,k; - - MSG_LOW("enter \n"); - - init_completion(&dpram_complete); - ret = kernel_thread(dpram_thread, NULL, CLONE_FS | CLONE_FILES); - if (ret < 0) { - MSG_WARN("kernel_thread() failed\n"); - return ret; - } - wait_for_completion(&dpram_complete); - if (!dpram_task) { - MSG_WARN("DPRAM I/O thread error\n"); - return -EIO; - } - - for(i=0; i0) - { - for(k=0; k -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -typedef struct pdp_arg { - unsigned char id; - char ifname[16]; -} __attribute__ ((packed)) pdp_arg_t; - -#define IOC_MZ2_MAGIC (0xC1) - -#define HN_PDP_ACTIVATE _IOWR(IOC_MZ2_MAGIC, 0xe0, pdp_arg_t) -#define HN_PDP_DEACTIVATE _IOW (IOC_MZ2_MAGIC, 0xe1, pdp_arg_t) -#define HN_PDP_ADJUST _IOW (IOC_MZ2_MAGIC, 0xe2, int) - -//#include -#include - -#define MULTIPDP_ERROR -#undef USE_LOOPBACK_PING - -#ifdef USE_LOOPBACK_PING -#include -#include -#include -#endif - -#ifdef MULTIPDP_ERROR -#define EPRINTK(X...) \ - do { \ - printk("%s(): ", __FUNCTION__); \ - printk(X); \ - } while (0) -#else -#define EPRINTK(X...) do { } while (0) -#endif - -#define CONFIG_MULTIPDP_DEBUG 1 - -#if (CONFIG_MULTIPDP_DEBUG > 0) -#define DPRINTK(N, X...) \ - do { \ - if (N <= CONFIG_MULTIPDP_DEBUG) { \ - printk("%s(): ", __FUNCTION__); \ - printk(X); \ - } \ - } while (0) -#else -#define DPRINTK(N, X...) do { } while (0) -#endif - -#define MAX_PDP_CONTEXT 10 -#define MAX_PDP_DATA_LEN 1500 -#define MAX_PDP_PACKET_LEN (MAX_PDP_DATA_LEN + 4 + 2) -#define VNET_PREFIX "pdp" -#define APP_DEVNAME "multipdp" -#define DPRAM_DEVNAME "/dev/dpram1" - -#define DEV_TYPE_NET 0 -#define DEV_TYPE_SERIAL 1 - -#define DEV_FLAG_STICKY 0x1 - -#define CSD_MAJOR_NUM 0 -#define CSD_MINOR_NUM 0 - -#define DELAY_RETRY 10 - -struct pdp_hdr { - u_int16_t len; - u_int8_t id; - u_int8_t control; -} __attribute__ ((packed)); - -struct pdp_info { - u_int8_t id; - unsigned type; - unsigned flags; - u_int8_t *tx_buf; - - union { - struct { - struct net_device *net; - struct net_device_stats stats; - struct delayed_work xmit_task; - } vnet_u; - - struct { - struct tty_driver tty_driver[3]; - int refcount; - struct tty_struct *tty_table[1]; - struct ktermios *termios[1]; - struct ktermios *termios_locked[1]; - char tty_name[16]; - struct tty_struct *tty; - struct semaphore write_lock; - } vs_u; - } dev_u; -#define vn_dev dev_u.vnet_u -#define vs_dev dev_u.vs_u -}; - -static struct pdp_info *pdp_table[MAX_PDP_CONTEXT]; -static DECLARE_MUTEX(pdp_lock); - -static struct task_struct *dpram_task; -static struct file *dpram_filp; -static DECLARE_COMPLETION(dpram_complete); - -static int pdp_mux(struct pdp_info *dev, const void *data, size_t len ); -static int pdp_demux(void); -static inline struct pdp_info * pdp_get_serdev(const char *name); - -static int g_adjust = 0; - -#define PDP_BUFFER_SIZE 16 -struct pdp_buffer { - struct sk_buff *buf_arr[PDP_BUFFER_SIZE]; - int head; - int tail; -}; - -static struct pdp_buffer pdp_buf; - -static inline void vnet_buffer_init(void) -{ - pdp_buf.head = 0; - pdp_buf.tail = PDP_BUFFER_SIZE - 1; -} - -static inline int vnet_buffer_empty(void) -{ - int next_tail = pdp_buf.tail + 1; - if (next_tail == PDP_BUFFER_SIZE) - next_tail = 0; - if (next_tail == pdp_buf.head) - return 1; - return 0; -} -static inline int vnet_buffer_add(struct sk_buff *skb) -{ - if (pdp_buf.head == pdp_buf.tail) - return -1; - pdp_buf.buf_arr[pdp_buf.head] = skb; - pdp_buf.head++; - if (pdp_buf.head == PDP_BUFFER_SIZE) - pdp_buf.head = 0; - return 0; -} - -static inline struct sk_buff *vnet_buffer_extract(void) -{ - struct sk_buff *skb; - int next_tail; - if (vnet_buffer_empty()) - return NULL; - next_tail = pdp_buf.tail + 1; - if (next_tail == PDP_BUFFER_SIZE) - next_tail = 0; - - skb = pdp_buf.buf_arr[next_tail]; - return skb; -} - -static inline void vnet_buffer_move_tail(void) -{ - pdp_buf.tail++; - if (pdp_buf.tail == PDP_BUFFER_SIZE) - pdp_buf.tail = 0; -} - -static inline struct file *dpram_open(void) -{ - int ret = 0; - struct file *filp; - struct termios termios; - mm_segment_t oldfs; - - filp = filp_open(DPRAM_DEVNAME, O_RDWR, 0); - if (IS_ERR(filp)) { - DPRINTK(1, "filp_open() failed~!: %ld\n", PTR_ERR(filp)); - return NULL; - } - - oldfs = get_fs(); set_fs(get_ds()); - ret = filp->f_op->unlocked_ioctl(filp, - TCGETA, (unsigned long)&termios); - set_fs(oldfs); - if (ret < 0) { - DPRINTK(1, "f_op->ioctl() failed: %d\n", ret); - filp_close(filp, current->files); - return NULL; - } - - termios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL | B115200; - termios.c_iflag = IGNBRK | IGNPAR; - termios.c_lflag = 0; - termios.c_oflag = 0; - termios.c_cc[VMIN] = 1; - termios.c_cc[VTIME] = 1; - - oldfs = get_fs(); set_fs(get_ds()); - ret = 0; - ret = filp->f_op->unlocked_ioctl(filp, - TCSETA, (unsigned long)&termios); - set_fs(oldfs); - if (ret < 0) { - DPRINTK(1, "f_op->ioctl() failed: %d\n", ret); - filp_close(filp, current->files); - return NULL; - } - - return filp; -} - -static inline void dpram_close(struct file *filp) -{ - filp_close(filp, current->files); -} - -static inline int dpram_poll(struct file *filp) -{ - int ret; - unsigned int mask; - struct poll_wqueues wait_table; - mm_segment_t oldfs; - - poll_initwait(&wait_table); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - - oldfs = get_fs(); set_fs(get_ds()); - mask = filp->f_op->poll(filp, &wait_table.pt); - set_fs(oldfs); - - if (mask & POLLIN) { - ret = 0; - break; - } - - if (wait_table.error) { - DPRINTK(1, "error in f_op->poll()\n"); - ret = wait_table.error; - break; - } - - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - schedule(); - } - set_current_state(TASK_RUNNING); - poll_freewait(&wait_table); - - return ret; -} - -static inline int dpram_write(struct file *filp, const void *buf, size_t count, - int nonblock) -{ - int ret, n = 0; - mm_segment_t oldfs; - - while (count) { - if (!dpram_filp) { - DPRINTK(1, "DPRAM not available\n"); - return -ENODEV; - } - - if (nonblock) dpram_filp->f_flags |= O_NONBLOCK; - oldfs = get_fs(); set_fs(get_ds()); - ret = filp->f_op->write(filp, buf + n, count, &filp->f_pos); - set_fs(oldfs); - if (nonblock) dpram_filp->f_flags &= ~O_NONBLOCK; - if (ret < 0) { - if (ret == -EAGAIN && !nonblock) { - continue; - } - return ret; - } - n += ret; - count -= ret; - } - return n; -} - -static inline int dpram_read(struct file *filp, void *buf, size_t count) -{ - int ret, n = 0; - mm_segment_t oldfs; - - while (count) { - oldfs = get_fs(); set_fs(get_ds()); - ret = filp->f_op->read(filp, buf + n, count, &filp->f_pos); - set_fs(oldfs); - if (ret < 0) { - if (ret == -EAGAIN) continue; - DPRINTK(1, "f_op->read() failed: %d\n", ret); - return ret; - } - n += ret; - count -= ret; - } - return n; -} - -static inline int dpram_flush_rx(struct file *filp, size_t count) -{ - int ret, n = 0; - char *buf; - mm_segment_t oldfs; - - buf = kmalloc(count, GFP_KERNEL); - if (buf == NULL) return -ENOMEM; - - while (count) { - oldfs = get_fs(); set_fs(get_ds()); - ret = filp->f_op->read(filp, buf + n, count, &filp->f_pos); - set_fs(oldfs); - if (ret < 0) { - if (ret == -EAGAIN) continue; - DPRINTK(1, "f_op->read() failed: %d\n", ret); - kfree(buf); - return ret; - } - n += ret; - count -= ret; - } - kfree(buf); - return n; -} - - -static int dpram_thread(void *data) -{ - int ret = 0; - struct file *filp; - - dpram_task = current; - - daemonize("dpram_thread"); - - strcpy(current->comm, "multipdp"); - - siginitsetinv(¤t->blocked, sigmask(SIGUSR1)); - recalc_sigpending(); - - filp = dpram_open(); - if (filp == NULL) - goto out; - - dpram_filp = filp; - - complete(&dpram_complete); - - while (1) { - ret = dpram_poll(filp); - - if (ret == -ERESTARTSYS) { - if (sigismember(¤t->pending.signal, SIGUSR1)) { - DPRINTK(1, "got SIGUSR1 signal\n"); - sigdelset(¤t->pending.signal, SIGUSR1); - recalc_sigpending(); - ret = 0; - break; - } - } else if (ret < 0) { - EPRINTK("dpram_poll() failed\n"); - break; - } else { - ret = pdp_demux(); - if (ret < 0) { - EPRINTK("pdp_demux() failed\n"); - } - } - - try_to_freeze(); - } - - dpram_close(filp); - dpram_filp = NULL; -out: - dpram_task = NULL; - complete_and_exit(&dpram_complete, ret); -} - -static int vnet_open(struct net_device *net) -{ - struct pdp_info *dev = (struct pdp_info *)net->priv; - INIT_DELAYED_WORK(&dev->vn_dev.xmit_task, NULL); - netif_start_queue(net); - return 0; -} - -static int vnet_stop(struct net_device *net) -{ - netif_stop_queue(net); - flush_scheduled_work(); - return 0; -} - -static void vnet_defer_xmit(struct work_struct *data) -{ - int ret; - struct sk_buff *skb = NULL; - struct net_device *net = NULL; - struct pdp_info *dev = NULL; - - if (vnet_buffer_empty()) - goto out; - - while (!vnet_buffer_empty()) { - skb = (struct sk_buff *)vnet_buffer_extract(); - if (!skb) - goto out; - net = (struct net_device *)skb->dev; - dev = (struct pdp_info *)net->priv; - - ret = pdp_mux(dev, skb->data, skb->len); - if (ret < 0) - goto out; - else { - vnet_buffer_move_tail(); - net->trans_start = jiffies; - dev->vn_dev.stats.tx_bytes += skb->len; - dev->vn_dev.stats.tx_packets++; - dev_kfree_skb_any(skb); - } - netif_wake_queue(net); - } - -out: - if (!vnet_buffer_empty()) { - PREPARE_DELAYED_WORK(&dev->vn_dev.xmit_task, vnet_defer_xmit); - schedule_delayed_work(&dev->vn_dev.xmit_task, DELAY_RETRY); - } -} - -static int vnet_start_xmit(struct sk_buff *skb, struct net_device *net) -{ - struct pdp_info *dev = (struct pdp_info *)net->priv; - int ret; -#ifdef USE_LOOPBACK_PING - struct sk_buff *skb2; - struct icmphdr *icmph; - struct iphdr *iph; -#endif - - DPRINTK(3, "id: %d, skb->len: %d\n", dev->id, skb->len); - -#ifdef USE_LOOPBACK_PING - dev->vn_dev.stats.tx_bytes += skb->len; - dev->vn_dev.stats.tx_packets++; - - skb2 = alloc_skb(skb->len, GFP_ATOMIC); - if (skb2 == NULL) { - DPRINTK(1, "alloc_skb() failed\n"); - dev_kfree_skb_any(skb); - return -ENOMEM; - } - - memcpy(skb2->data, skb->data, skb->len); - skb_put(skb2, skb->len); - dev_kfree_skb_any(skb); - - icmph = (struct icmphdr *)(skb2->data + sizeof(struct iphdr)); - iph = (struct iphdr *)skb2->data; - - icmph->type = __constant_htons(ICMP_ECHOREPLY); - - ret = iph->daddr; - iph->daddr = iph->saddr; - iph->saddr = ret; - iph->check = 0; - iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); - - skb2->dev = net; - skb2->protocol = __constant_htons(ETH_P_IP); - - netif_rx(skb2); - - dev->vn_dev.stats.rx_packets++; - dev->vn_dev.stats.rx_bytes += skb->len; -#else - ret = vnet_buffer_add(skb); - if (ret < 0) { - dev->vn_dev.stats.tx_dropped++; - dev_kfree_skb_any(skb); - } - PREPARE_WORK(&dev->vn_dev.xmit_task.work, vnet_defer_xmit); - schedule_work(&dev->vn_dev.xmit_task.work); - if (!ret) - netif_stop_queue(net); -#endif - - return 0; -} - -static int vnet_recv(struct pdp_info *dev, size_t len) -{ - struct sk_buff *skb; - int ret; - - if (!netif_running(dev->vn_dev.net)) { - DPRINTK(1, "%s(id: %u) is not running\n", - dev->vn_dev.net->name, dev->id); - return -ENODEV; - } - - skb = alloc_skb(len, GFP_ATOMIC); - if (skb == NULL) { - DPRINTK(1, "alloc_skb() failed\n"); - return -ENOMEM; - } - - ret = dpram_read(dpram_filp, skb->data, len); - if (ret < 0) { - DPRINTK(1, "dpram_read() failed: %d\n", ret); - dev_kfree_skb_any(skb); - return ret; - } - - skb_put(skb, ret); - - skb->dev = dev->vn_dev.net; - skb->protocol = __constant_htons(ETH_P_IP); - - netif_rx(skb); - - dev->vn_dev.stats.rx_packets++; - dev->vn_dev.stats.rx_bytes += skb->len; - return 0; -} - -static struct net_device_stats *vnet_get_stats(struct net_device *net) -{ - struct pdp_info *dev = (struct pdp_info *)net->priv; - return &dev->vn_dev.stats; -} - -static void vnet_tx_timeout(struct net_device *net) -{ - struct pdp_info *dev = (struct pdp_info *)net->priv; - DPRINTK(3, "enter"); - net->trans_start = jiffies; - dev->vn_dev.stats.tx_errors++; - netif_wake_queue(net); -} - -static struct net_device *vnet_add_dev(void *priv) -{ - int ret; - struct net_device *net; - - net = kmalloc(sizeof(*net), GFP_KERNEL); - if (net == NULL) { - DPRINTK(1, "out of memory\n"); - return NULL; - } - memset(net, 0, sizeof(*net)); - - strcpy(net->name, VNET_PREFIX "%d"); - net->open = vnet_open; - net->stop = vnet_stop; - net->hard_start_xmit = vnet_start_xmit; - net->get_stats = vnet_get_stats; - net->tx_timeout = vnet_tx_timeout; - net->type = ARPHRD_PPP; - net->hard_header_len = 0; - net->mtu = MAX_PDP_DATA_LEN; - net->addr_len = 0; - net->tx_queue_len = 1000; - net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; - net->watchdog_timeo = 5 * HZ; - net->priv = priv; - - ret = register_netdev(net); - if (ret != 0) { - DPRINTK(1, "register_netdevice failed: %d\n", ret); - kfree(net); - return NULL; - } - - return net; -} - -static void vnet_del_dev(struct net_device *net) -{ - unregister_netdev(net); - kfree(net); -} - -static int vs_open(struct tty_struct *tty, struct file *filp) -{ - struct pdp_info *dev; - - DPRINTK(3, "enter\n"); - - down(&pdp_lock); - dev = pdp_get_serdev(tty->driver->name); - if (dev == NULL) { - up(&pdp_lock); - return -ENODEV; - } - tty->driver_data = (void *)dev; - tty->low_latency = 1; - dev->vs_dev.tty = tty; - up(&pdp_lock); - - return 0; -} - -static void vs_close(struct tty_struct *tty, struct file *filp) -{ - struct pdp_info *dev; - - DPRINTK(3, "enter\n"); - - down(&pdp_lock); - dev = pdp_get_serdev(tty->driver->name); - if (dev != NULL) - dev->vs_dev.tty = NULL; - up(&pdp_lock); -} - - -static int vs_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - int ret; - - - struct pdp_info *dev = (struct pdp_info *)tty->driver_data; - - DPRINTK(3, "id: %u, count: %d\n",dev->id, count); - - ret = pdp_mux(dev, buf, count); - if (ret == 0) { - ret = count; - } - - return ret; -} - -static int vs_write_room(struct tty_struct *tty) -{ - return N_TTY_BUF_SIZE; -// return TTY_FLIPBUF_SIZE; -} - -static int vs_chars_in_buffer(struct tty_struct *tty) -{ - return 0; -} - -static int vs_read(struct pdp_info *dev, size_t len) -{ - struct tty_struct *tty = dev->vs_dev.tty; - - int remain_buffer_size = 0 ; - int alloc_buffer_size = 0 ; - - int remain_read_size = len ; - - int ret = 0; - - unsigned char *char_buf_ptr; - - do { - char_buf_ptr = NULL; - alloc_buffer_size=tty_prepare_flip_string(tty, &char_buf_ptr, remain_read_size) ; - remain_read_size -= alloc_buffer_size ; - - remain_buffer_size = alloc_buffer_size ; - do { - ret = dpram_read(dpram_filp, char_buf_ptr, remain_buffer_size); - remain_buffer_size -= ret ; - char_buf_ptr += ret ; - if (ret < 0) { - DPRINTK(1, "dpram_read() failed: %d\n", ret); - return ret; - } - } while ( remain_buffer_size > 0 ); - - tty_flip_buffer_push(tty); - - } while (remain_read_size > 0) ; - - return 0; -} - -static int vs_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - -static void vs_break_ctl(struct tty_struct *tty, int break_state) -{ -} - -static const struct tty_operations vs_ops = -{ - .open = vs_open, - .close = vs_close, - .write = vs_write, - .write_room = vs_write_room, - .chars_in_buffer = vs_chars_in_buffer, - .ioctl = vs_ioctl, - .break_ctl = vs_break_ctl, -}; - -static int vs_add_dev(struct pdp_info *dev) -{ - struct tty_driver *tty_driver; - - switch (dev->id) { - case 1: - tty_driver = &dev->vs_dev.tty_driver[0]; - tty_driver->minor_start = CSD_MINOR_NUM; - break; - - case 25: - tty_driver = &dev->vs_dev.tty_driver[1]; - tty_driver->minor_start = 1; - break; - - case 5: - tty_driver = &dev->vs_dev.tty_driver[2]; - tty_driver->minor_start = 2; - break; - - default: - tty_driver = NULL; - } - - if (!tty_driver) { - printk("tty driver is NULL!\n"); - return -1; - } - - tty_driver->magic = TTY_DRIVER_MAGIC; - tty_driver->driver_name = "multipdp"; - tty_driver->name = dev->vs_dev.tty_name; - tty_driver->major = CSD_MAJOR_NUM; - tty_driver->num = 1; - tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - tty_driver->subtype = SERIAL_TYPE_NORMAL; - tty_driver->flags = TTY_DRIVER_REAL_RAW; - tty_driver->refcount = dev->vs_dev.refcount; - tty_driver->ttys = dev->vs_dev.tty_table; - tty_driver->termios = dev->vs_dev.termios; - tty_driver->termios_locked = dev->vs_dev.termios_locked; - tty_driver->ops = &vs_ops; - tty_driver->init_termios = tty_std_termios; - - return tty_register_driver(tty_driver); -} - -static void vs_del_dev(struct pdp_info *dev) -{ - struct tty_driver *tty_driver = NULL; - - switch (dev->id) { - case 1: - tty_driver = &dev->vs_dev.tty_driver[0]; - break; - - case 25: - tty_driver = &dev->vs_dev.tty_driver[1]; - break; - - case 5: - tty_driver = &dev->vs_dev.tty_driver[2]; - break; - } - - tty_unregister_driver(tty_driver); -} - -static inline struct pdp_info * pdp_get_dev(u_int8_t id) -{ - int slot; - - for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { - if (pdp_table[slot] && pdp_table[slot]->id == id) { - return pdp_table[slot]; - } - } - return NULL; -} - -static inline struct pdp_info * pdp_get_serdev(const char *name) -{ - int slot; - struct pdp_info *dev; - - for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { - dev = pdp_table[slot]; - if (dev && dev->type == DEV_TYPE_SERIAL && - strcmp(name, dev->vs_dev.tty_name) == 0) { - return dev; - } - } - return NULL; -} - -static inline int pdp_add_dev(struct pdp_info *dev) -{ - int slot; - - if (pdp_get_dev(dev->id)) { - return -EBUSY; - } - - for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { - if (pdp_table[slot] == NULL) { - pdp_table[slot] = dev; - return slot; - } - } - return -ENOSPC; -} - -static inline struct pdp_info * pdp_remove_dev(u_int8_t id) -{ - int slot; - struct pdp_info *dev; - - for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { - if (pdp_table[slot] && pdp_table[slot]->id == id) { - dev = pdp_table[slot]; - pdp_table[slot] = NULL; - return dev; - } - } - return NULL; -} - -static inline struct pdp_info * pdp_remove_slot(int slot) -{ - struct pdp_info *dev; - - dev = pdp_table[slot]; - pdp_table[slot] = NULL; - return dev; -} - -static int pdp_mux(struct pdp_info *dev, const void *data, size_t len ) -{ - int ret; - size_t nbytes; - u_int8_t *tx_buf; - struct pdp_hdr *hdr; - const u_int8_t *buf; - - tx_buf = dev->tx_buf; - hdr = (struct pdp_hdr *)(tx_buf + 1); - buf = data; - - hdr->id = dev->id; - - hdr->control = 0; - - while (len) { - if (len > MAX_PDP_DATA_LEN) { - nbytes = MAX_PDP_DATA_LEN; - } else { - nbytes = len; - } - hdr->len = nbytes + sizeof(struct pdp_hdr); - - tx_buf[0] = 0x7f; - - memcpy(tx_buf + 1 + sizeof(struct pdp_hdr), buf, nbytes); - - tx_buf[1 + hdr->len] = 0x7e; - - DPRINTK(2, "hdr->id: %d, hdr->len: %d\n", hdr->id, hdr->len); - - ret = dpram_write(dpram_filp, tx_buf, hdr->len + 2, 1); - if (ret < 0) { - return ret; - } - buf += nbytes; - len -= nbytes; - } - - return 0; -} - -static int pdp_demux(void) -{ - int ret; - u_int8_t ch; - size_t len; - struct pdp_info *dev = NULL; - struct pdp_hdr hdr; - - ret = dpram_read(dpram_filp, &ch, sizeof(ch)); - if (ret < 0) { - DPRINTK(1, "dpram_read() failed: %d\n", ret); - return ret; - } - if (ch != 0x7f) { - DPRINTK(1, "invalid start byte: 0x%02x\n", ch); - return -1; - } - - ret = dpram_read(dpram_filp, &hdr, sizeof(hdr)); - if (ret < 0) { - DPRINTK(1, "dpram_read() failed: %d\n", ret); - return ret; - } - - DPRINTK(2, "hdr->id: %d, hdr->len: %d\n", hdr.id, hdr.len); - - len = hdr.len - sizeof(struct pdp_hdr); - - down(&pdp_lock); - dev = pdp_get_dev(hdr.id); - if (dev == NULL) { - DPRINTK(1, "invalid id: %u\n", hdr.id); - ret = -ENODEV; - goto err; - } - - if (dev->type == DEV_TYPE_SERIAL && dev->vs_dev.tty == NULL) { - DPRINTK(1, "closed serial id: %u. ignore data\n", hdr.id); - ret = 0; // just ignore it. - goto err; - } - - if (dev->type == DEV_TYPE_NET) { - ret = vnet_recv(dev, len); - if (ret < 0) { - DPRINTK(1, "vnet_recv() failed\n"); - goto err; - } - } else if (dev->type == DEV_TYPE_SERIAL) { - ret = vs_read(dev, len); - if (ret < 0) { - DPRINTK(1, "vs_read() failed\n"); - goto err; - } - } - up(&pdp_lock); - - ret = dpram_read(dpram_filp, &ch, sizeof(ch)); - if (ret < 0) { - DPRINTK(1, "dpram_read() failed: %d\n", ret); - return ret; - } - if (ch != 0x7e) { - DPRINTK(1, "invalid stop byte: 0x%02x\n", ch); - return -1; - } - return 0; - -err: - up(&pdp_lock); - dpram_flush_rx(dpram_filp, len + 1); - - return ret; -} - -static int pdp_activate(pdp_arg_t *pdp_arg, unsigned type, unsigned flags) -{ - int ret; - struct pdp_info *dev; - struct net_device *net; - - DPRINTK(2, "id: %d\n", pdp_arg->id); - - dev = kmalloc(sizeof(struct pdp_info) + MAX_PDP_PACKET_LEN, GFP_KERNEL); - if (dev == NULL) { - DPRINTK(1, "out of memory\n"); - return -ENOMEM; - } - memset(dev, 0, sizeof(struct pdp_info)); - - if (type == DEV_TYPE_NET) { - dev->id = pdp_arg->id + g_adjust; - } - - else { - dev->id = pdp_arg->id; - } - - dev->type = type; - dev->flags = flags; - dev->tx_buf = (u_int8_t *)(dev + 1); - - if (type == DEV_TYPE_NET) { - net = vnet_add_dev((void *)dev); - if (net == NULL) { - kfree(dev); - return -ENOMEM; - } - - dev->vn_dev.net = net; - strcpy(pdp_arg->ifname, net->name); - - down(&pdp_lock); - ret = pdp_add_dev(dev); - if (ret < 0) { - DPRINTK(1, "pdp_add_dev() failed\n"); - up(&pdp_lock); - vnet_del_dev(dev->vn_dev.net); - kfree(dev); - return ret; - } - up(&pdp_lock); - - DPRINTK(1, "%s(id: %u) network device created\n", - net->name, dev->id); - } else if (type == DEV_TYPE_SERIAL) { - init_MUTEX(&dev->vs_dev.write_lock); - strcpy(dev->vs_dev.tty_name, pdp_arg->ifname); - - ret = vs_add_dev(dev); - if (ret < 0) { - kfree(dev); - return ret; - } - - down(&pdp_lock); - ret = pdp_add_dev(dev); - if (ret < 0) { - DPRINTK(1, "pdp_add_dev() failed\n"); - up(&pdp_lock); - vs_del_dev(dev); - kfree(dev); - return ret; - } - up(&pdp_lock); - - if (dev->id == 1) { - DPRINTK(1, "%s(id: %u) serial device is created.\n", - dev->vs_dev.tty_driver[0].name, dev->id); - } - - else if (dev->id == 25) { - DPRINTK(1, "%s(id: %u) serial device is created.\n", - dev->vs_dev.tty_driver[1].name, dev->id); - } - - else if (dev->id == 5) { - DPRINTK(1, "%s(id: %u) serial device is created.\n", - dev->vs_dev.tty_driver[2].name, dev->id); - } - } - - return 0; -} - -static int pdp_deactivate(pdp_arg_t *pdp_arg, int force) -{ - struct pdp_info *dev = NULL; - - DPRINTK(1, "id: %d\n", pdp_arg->id); - - down(&pdp_lock); - - if (pdp_arg->id == 1) { - DPRINTK(1, "Channel ID is 1, we will remove the network device (pdp) of channel ID: %d.\n", - pdp_arg->id + g_adjust); - } - - else { - DPRINTK(1, "Channel ID: %d\n", pdp_arg->id); - } - - pdp_arg->id = pdp_arg->id + g_adjust; - DPRINTK(1, "ID is adjusted, new ID: %d\n", pdp_arg->id); - - dev = pdp_get_dev(pdp_arg->id); - - if (dev == NULL) { - DPRINTK(1, "not found id: %u\n", pdp_arg->id); - up(&pdp_lock); - return -EINVAL; - } - if (!force && dev->flags & DEV_FLAG_STICKY) { - DPRINTK(1, "sticky id: %u\n", pdp_arg->id); - up(&pdp_lock); - return -EACCES; - } - - pdp_remove_dev(pdp_arg->id); - up(&pdp_lock); - - if (dev->type == DEV_TYPE_NET) { - DPRINTK(1, "%s(id: %u) network device removed\n", - dev->vn_dev.net->name, dev->id); - vnet_del_dev(dev->vn_dev.net); - } else if (dev->type == DEV_TYPE_SERIAL) { - if (dev->id == 1) { - DPRINTK(1, "%s(id: %u) serial device removed\n", - dev->vs_dev.tty_driver[0].name, dev->id); - } - - else if (dev->id == 25) { - DPRINTK(1, "%s(id: %u) serial device removed\n", - dev->vs_dev.tty_driver[1].name, dev->id); - } - - else if (dev->id == 5) { - DPRINTK(1, "%s(id: %u) serial device removed\n", - dev->vs_dev.tty_driver[2].name, dev->id); - } - - vs_del_dev(dev); - } - - kfree(dev); - - return 0; -} - -static void __exit pdp_cleanup(void) -{ - int slot; - struct pdp_info *dev; - - down(&pdp_lock); - for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { - dev = pdp_remove_slot(slot); - if (dev) { - if (dev->type == DEV_TYPE_NET) { - DPRINTK(1, "%s(id: %u) network device removed\n", - dev->vn_dev.net->name, dev->id); - vnet_del_dev(dev->vn_dev.net); - } else if (dev->type == DEV_TYPE_SERIAL) { - if (dev->id == 1) { - DPRINTK(1, "%s(id: %u) serial device removed\n", - dev->vs_dev.tty_driver[0].name, dev->id); - } - - else if (dev->id == 25) { - DPRINTK(1, "%s(id: %u) serial device removed\n", - dev->vs_dev.tty_driver[1].name, dev->id); - } - - else if (dev->id == 5) { - DPRINTK(1, "%s(id: %u) serial device removed\n", - dev->vs_dev.tty_driver[2].name, dev->id); - } - - vs_del_dev(dev); - } - - kfree(dev); - } - } - up(&pdp_lock); -} - -static int pdp_adjust(const int adjust) -{ - g_adjust = adjust; - printk("adjusting value: %d\n", adjust); - return 0; -} - -static int multipdp_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int ret, adjust; - pdp_arg_t pdp_arg; - - switch (cmd) { - case HN_PDP_ACTIVATE: - if (copy_from_user(&pdp_arg, (void *)arg, sizeof(pdp_arg))) - return -EFAULT; - ret = pdp_activate(&pdp_arg, DEV_TYPE_NET, 0); - if (ret < 0) { - return ret; - } - return copy_to_user((void *)arg, &pdp_arg, sizeof(pdp_arg)); - - case HN_PDP_DEACTIVATE: - printk("1\n"); - if (copy_from_user(&pdp_arg, (void *)arg, sizeof(pdp_arg))) - return -EFAULT; - return pdp_deactivate(&pdp_arg, 0); - - case HN_PDP_ADJUST: - if (copy_from_user(&adjust, (void *)arg, sizeof (int))) - return -EFAULT; - - return pdp_adjust(adjust); - } - - return -EINVAL; -} - -static struct file_operations multipdp_fops = { - .owner = THIS_MODULE, - .ioctl = multipdp_ioctl, - .llseek = no_llseek, -}; - -static struct miscdevice multipdp_dev = { - .minor = 132, - .name = APP_DEVNAME, - .fops = &multipdp_fops, -}; - -#ifdef CONFIG_PROC_FS -static int multipdp_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - - char *p = page; - int len; - - down(&pdp_lock); - - p += sprintf(p, "modified multipdp driver on 20070205\n"); - for (len = 0; len < MAX_PDP_CONTEXT; len++) { - struct pdp_info *dev = pdp_table[len]; - if (!dev) continue; - - p += sprintf(p, - "name: %s\t, id: %-3u, type: %-7s, flags: 0x%04x\n", - dev->type == DEV_TYPE_NET ? - dev->vn_dev.net->name : dev->vs_dev.tty_name, - dev->id, - dev->type == DEV_TYPE_NET ? "network" : "serial", - dev->flags); - } - up(&pdp_lock); - - len = (p - page) - off; - if (len < 0) - len = 0; - - *eof = (len <= count) ? 1 : 0; - *start = page + off; - - return len; -} -#endif - -static int __init multipdp_init(void) -{ - int ret; - pdp_arg_t pdp_arg = { .id = 1, .ifname = "ttyCSD", }; - pdp_arg_t router_arg = { .id = 25, .ifname = "ttyROUTER", }; - pdp_arg_t gps_arg = { .id = 5, .ifname = "ttyGPS", }; - - vnet_buffer_init(); - - init_completion(&dpram_complete); - ret = kernel_thread(dpram_thread, NULL, CLONE_FS | CLONE_FILES); - if (ret < 0) { - EPRINTK("kernel_thread() failed\n"); - return ret; - } - wait_for_completion(&dpram_complete); - if (!dpram_task) { - EPRINTK("DPRAM I/O thread error\n"); - return -EIO; - } - - ret = pdp_activate(&pdp_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); - if (ret < 0) { - EPRINTK("failed to create a serial device for CSD\n"); - goto err0; - } - - ret = pdp_activate(&router_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); - if (ret < 0) { - EPRINTK("failed to create a serial device for ROUTER\n"); - goto err1; - } - - ret = pdp_activate(&gps_arg, DEV_TYPE_SERIAL, DEV_FLAG_STICKY); - if (ret < 0) { - EPRINTK("failed to create a serial device for ROUTER\n"); - goto err1; - } - - ret = misc_register(&multipdp_dev); - if (ret < 0) { - EPRINTK("misc_register() failed\n"); - goto err1; - } - -#ifdef CONFIG_PROC_FS - create_proc_read_entry(APP_DEVNAME, 0, NULL, - multipdp_proc_read, NULL); -#endif - - printk(KERN_INFO - "$Id: multipdp.c,v 1.1 2008/03/17 12:31:17 kdsoo Exp $\n"); - return 0; - -err1: - pdp_deactivate(&pdp_arg, 1); - -err0: - if (dpram_task) { - send_sig(SIGUSR1, dpram_task, 1); - wait_for_completion(&dpram_complete); - } - return ret; -} - -static void __exit multipdp_exit(void) -{ -#ifdef CONFIG_PROC_FS - remove_proc_entry(APP_DEVNAME, NULL); -#endif - - misc_deregister(&multipdp_dev); - - pdp_cleanup(); - - if (dpram_task) { - send_sig(SIGUSR1, dpram_task, 1); - wait_for_completion(&dpram_complete); - } -} - -module_init(multipdp_init); -module_exit(multipdp_exit); - -MODULE_AUTHOR("SAMSUNG ELECTRONICS CO., LTD"); -MODULE_DESCRIPTION("Multiple PDP Muxer / Demuxer"); -MODULE_LICENSE("GPL");