From 16bc7e9079f825b709bc2a2c9be410768236ba9a Mon Sep 17 00:00:00 2001 From: sirmordred Date: Sun, 21 Jun 2015 12:16:27 +0300 Subject: [PATCH] drivers: dpram: Updated dpram driver * From kylesseopen 4.0 ICS release (with 3.0 kernel) --- drivers/dpram/Kconfig | 6 - drivers/dpram/dpram.c | 949 +++++++++++++----------- drivers/dpram/dpram.h | 101 ++- drivers/dpram/multipdp.c | 1466 ++++++++++++++++++++------------------ 4 files changed, 1387 insertions(+), 1135 deletions(-) diff --git a/drivers/dpram/Kconfig b/drivers/dpram/Kconfig index 6eaa9faf0bf..fdc3989c427 100644 --- a/drivers/dpram/Kconfig +++ b/drivers/dpram/Kconfig @@ -11,12 +11,6 @@ config DPRAM ---help--- Include this for using smem as dpram for communication between modem and appl. -config ENABLE_TTY_CIQ - bool "Enabling dpram TTY CIQ Driver" - default n - ---help--- - Include this for using whitelist. - config DPRAM_WHITELIST bool "Using dpram to send whitelist port infos" default y diff --git a/drivers/dpram/dpram.c b/drivers/dpram/dpram.c index a72a2e841bf..93d415eb755 100644 --- a/drivers/dpram/dpram.c +++ b/drivers/dpram/dpram.c @@ -19,13 +19,17 @@ #include #include #include -#include #include #include #include #include +#include + +#ifdef _ENABLE_ERROR_DEVICE #include #include +#endif /* _ENABLE_ERROR_DEVICE */ + #include #include #include @@ -34,6 +38,7 @@ #include #include #include +#include #include "dpram.h" #include "../../arch/arm/mach-msm/smd_private.h" @@ -42,9 +47,10 @@ #define DRIVER_NAME "DPRAM" #define DRIVER_MAJOR_NUM 255 -#undef _DEBUG +#define _DEBUG #ifdef _DEBUG -#define dprintk(s, args...) printk("[DPRAM] %s:%d - " s, __func__, __LINE__, ##args) +#define dprintk(s, args...) \ + printk(KERN_INFO "%s:%d - " s, __func__, __LINE__, ##args) #else #define dprintk(s, args...) #endif /* _DEBUG */ @@ -55,11 +61,25 @@ #define READ_FROM_DPRAM(dest, src, size) \ _memcpy(dest, (void *)(SmemBase + src), size) +#ifdef _ENABLE_ERROR_DEVICE #define DPRAM_ERR_MSG_LEN 65 #define DPRAM_ERR_DEVICE "dpramerr" +#endif /* _ENABLE_ERROR_DEVICE */ -#define MSM_TRIG_A2M_DPRAM_INT (writel(1 << 4, MSM_APCS_GCC_BASE + 0x8)) +#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) +struct smem_info { + unsigned int silent_reset; + unsigned int ram_dump_level; +}; + +struct smem_info *smem_flag; +int silent_value; +int default_dump_enable_flag; +int dump_enable_flag; +EXPORT_SYMBOL(dump_enable_flag); + +static int fmt_error_check; static volatile unsigned char *SmemBase; static int DpramInited = 0; @@ -117,6 +137,7 @@ static DECLARE_TASKLET(fmt_res_ack_tasklet, res_ack_tasklet_handler, 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]; @@ -124,13 +145,13 @@ struct class *dpram_class; static DECLARE_WAIT_QUEUE_HEAD(dpram_err_wait_q); static struct fasync_struct *dpram_err_async_q; +#endif /* _ENABLE_ERROR_DEVICE */ static DEFINE_SEMAPHORE(write_mutex); struct wake_lock imei_wake_lock; struct wake_lock dpram_wake_lock; struct wake_lock silent_wake_lock; -extern struct class *sec_class; /* tty related functions. */ static inline void byte_align(unsigned long dest, unsigned long src) @@ -141,22 +162,18 @@ static inline void byte_align(unsigned long dest, unsigned long src) if (!(dest % 2) && !(src % 2)) { p_dest = (u16 *)dest; p_src = (u16 *)src; - *p_dest = (*p_dest & 0xFF00) | (*p_src & 0x00FF); } else if ((dest % 2) && (src % 2)) { p_dest = (u16 *)(dest - 1); p_src = (u16 *)(src - 1); - *p_dest = (*p_dest & 0x00FF) | (*p_src & 0xFF00); } else if (!(dest % 2) && (src % 2)) { p_dest = (u16 *)dest; p_src = (u16 *)(src - 1); - *p_dest = (*p_dest & 0xFF00) | ((*p_src >> 8) & 0x00FF); } else if ((dest % 2) && !(src % 2)) { p_dest = (u16 *)(dest - 1); p_src = (u16 *)src; - *p_dest = (*p_dest & 0x00FF) | ((*p_src << 8) & 0xFF00); } else { dprintk("oops.~\n"); @@ -168,9 +185,8 @@ 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) { + if (size <= 0) return; - } if (dest & 1) { byte_align(dest, src); @@ -199,7 +215,8 @@ static inline void _memcpy(void *p_dest, const void *p_src, int size) size >>= 1; - while (size--) { *d++ = *s++; } + while (size--) + *d++ = *s++; } } @@ -208,9 +225,8 @@ static inline int _memcmp(u8 *dest, u8 *src, int size) int i = 0; while (i++ < size) { - if (*(dest + i) != *(src + i)) { + if (*(dest + i) != *(src + i)) return 1; - } } return 0; @@ -248,12 +264,10 @@ static void send_interrupt_to_phone(u16 irq_mask) { WRITE_TO_DPRAM(DPRAM_PDA2PHONE_INTERRUPT_ADDRESS, &irq_mask, DPRAM_INTERRUPT_PORT_SIZE); - MSM_TRIG_A2M_DPRAM_INT; - dprintk("PDA -> Phone interrupt!\n"); + writel(1, MSM_A2M_INT(3)); } #ifdef NO_TTY_DPRAM - #define yisprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) void yhexdump(const char *buf, int len) { @@ -261,121 +275,109 @@ void yhexdump(const char *buf, int len) int ofs, i, l; for (ofs = 0; ofs < len; ofs += 16) { - sprintf( str, "%03d: ", ofs ); + sprintf(str, sizeof(str), "%03d: ", ofs); for (i = 0; i < 16; i++) { if ((i + ofs) < len) - sprintf( octet, "%02x ", buf[ofs + i] ); + sprintf(octet, sizeof(octet), + "%02x ", buf[ofs + i]); else - strcpy( octet, " " ); + strncpy(octet, " ", 3); - strcat( str, octet ); + strncat(str, octet, sizeof(octet)); } - strcat( str, " " ); - l = strlen( str ); + + strncat(str, " ", 2); + l = strnlen(str, sizeof(str)); for (i = 0; (i < 16) && ((i + ofs) < len); i++) - str[l++] = yisprint( buf[ofs + i] ) ? buf[ofs + i] : '.'; + str[l++] = yisprint(buf[ofs + i]) ? buf[ofs + i] : '.'; str[l] = '\0'; - printk( "%s\n", str ); + dprintk("%s\n", str); } } -EXPORT_SYMBOL(yhexdump); - -char multipdp_rbuf[128 * 1024]; +char multipdp_rbuf[128*1024]; static int dpram_write(dpram_device_t *device, const unsigned char *buf, int len); static int (*multipdp_rx_noti_func)(char *, int); static inline int dpram_tty_insert_data(dpram_device_t *device, const u8 *psrc, u16 size); int multipdp_buf_copy(int index, char *dpram, int size) { - - if( index < 0 || index > sizeof(multipdp_rbuf) || (index + size) > sizeof(multipdp_rbuf)) + if (index < 0 || index > sizeof(multipdp_rbuf)-1 || + (index + size) > sizeof(multipdp_rbuf)) return -1; - dprintk("multipdp_buf_copy:index=%d size=%d\n", index, size); - memcpy( (void *)&multipdp_rbuf[index], (void *)dpram, size); - return( size); - + memcpy((void *)&multipdp_rbuf[index], (void *)dpram, size); + return size; } EXPORT_SYMBOL(multipdp_buf_copy); -int multipdp_rx_noti_regi( int (*rx_cfunc)(char *, int)) +void multipdp_rx_noti_regi(int (*rx_cfunc)(char *, int)) { multipdp_rx_noti_func = rx_cfunc; - return 0; } -EXPORT_SYMBOL(multipdp_rx_noti_regi); int multipdp_rx_datalen; -int multipdp_rx_data(dpram_device_t *device, int len) +int multipdp_rx_data(dpram_device_t *device, int len) { static int inuse_flag = 0; - int ret = 0; if( len == 0 ) return 0; if( inuse_flag ) - printk("***** inuse_flag = %d\n", inuse_flag); + dprintk("***** inuse_flag = %d\n", inuse_flag); inuse_flag ++; - if( multipdp_rx_noti_func) { - dprintk("multipdp_rx_data Before(noti_func) : len=%d\n",len); + if (multipdp_rx_noti_func) { multipdp_rx_datalen = len; - ret = multipdp_rx_noti_func(multipdp_rbuf, len); - dprintk("multipdp_rx_data After(noti_func) : ret=%d\n",ret); } - inuse_flag --; - - return(ret); + inuse_flag--; + return ret; } -int multipdp_dump(void) +int multipdp_dump(void) { yhexdump(multipdp_rbuf, multipdp_rx_datalen); return 0; } -EXPORT_SYMBOL(multipdp_dump); int multipdp_write(const unsigned char *buf, int len) { int i, ret; - // FORMATTED_INDEX : dpram0, RAW_INDEX : dpram1 + /* FORMATTED_INDEX : dpram0, RAW_INDEX : dpram1 */ dpram_device_t *device = &dpram_table[RAW_INDEX]; #ifdef NO_TTY_TX_RETRY - for(i =0; i<10; i++) - { + for (i = 0; i < 10; i++) { ret = dpram_write(device, buf, len); - if( ret > 0 ) { + + if (ret > 0) break; - } - printk(KERN_DEBUG "dpram_write() failed: %d, i(%d)\n", ret, i); - } - if ( i>=10) { - printk(KERN_DEBUG "dpram_write() failed: %d\n", ret); + + dprintk("dpram_write() failed: %d, i(%d)\n", ret, i); } - + + if (i >= 10) + dprintk("dpram_write() failed: %d\n", ret); + return ret; #endif } -EXPORT_SYMBOL(multipdp_write); #endif +extern struct class *sec_class; struct device *dpram_dev; - -#define POWER_DOWN_TIME ( 30 * HZ ) struct device *pm_dev; +struct timer_list power_down_timer; void power_down_registertimer(struct timer_list* ptimer, unsigned long timeover ); void power_down_timeout(unsigned long arg); -struct timer_list power_down_timer; bool power_down; static ssize_t show_info(struct device *d, @@ -383,7 +385,6 @@ static ssize_t show_info(struct device *d, { char *p = buf; - u16 magic, enable; u16 fmt_in_head, fmt_in_tail, fmt_out_head, fmt_out_tail; u16 raw_in_head, raw_in_tail, raw_out_head, raw_out_tail; @@ -468,7 +469,6 @@ static ssize_t store_whitelist(struct device *d, dpram_write(&dpram_table[0], buf, count); break; default: - break; } @@ -478,54 +478,48 @@ static ssize_t store_whitelist(struct device *d, static DEVICE_ATTR(whitelist, S_IRUGO|S_IWUSR, NULL, store_whitelist); #endif - +/* hsil */ static ssize_t store_power_down(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { char *after; - unsigned long value = simple_strtoul(buf, &after, 10); + unsigned long value = simple_strtoul(buf, &after, 10); if (value == 1) { - printk("[dpram] %s(%d)\n", __func__, __LINE__); - power_down_registertimer(&power_down_timer, POWER_DOWN_TIME); - } - + dprintk("[HSIL]\n"); + power_down_registertimer(&power_down_timer, POWER_DOWN_TIME); + } return count; } static DEVICE_ATTR(power_down, S_IRUGO|S_IWUSR, NULL, store_power_down); - static int dpram_write(dpram_device_t *device, const unsigned char *buf, int len) { int retval = 0; int size = 0; - u16 head, tail; u16 irq_mask = 0; - down(&write_mutex); READ_FROM_DPRAM_VERIFY(&head, device->out_head_addr, sizeof(head)); READ_FROM_DPRAM_VERIFY(&tail, device->out_tail_addr, sizeof(tail)); - - // +++++++++ head ---------- tail ++++++++++ // - if (head < tail) { + if (head < tail) { /* +++++++++ head ---------- tail ++++++++++ */ size = tail - head - 1; size = (len > size) ? size : len; WRITE_TO_DPRAM(device->out_buff_addr + head, buf, size); retval = size; - } else if (tail == 0) { + } else if (tail == 0) { /* tail +++++++++++++++ head --------------- */ size = device->out_buff_size - head - 1; size = (len > size) ? size : len; WRITE_TO_DPRAM(device->out_buff_addr + head, buf, size); retval = size; - } else { + } else { /* ------ tail +++++++++++ head ------------ */ size = device->out_buff_size - head; size = (len > size) ? size : len; @@ -559,17 +553,15 @@ static int dpram_write(dpram_device_t *device, return retval; } -#define CLUSTER_SEGMENT 1550 - static inline int dpram_tty_insert_data(dpram_device_t *device, const u8 *psrc, u16 size) { - +#define CLUSTER_SEGMENT 1550 u16 copied_size = 0; int retval = 0; - // ... ..... multipdp. .... raw data. .... - - if (size > CLUSTER_SEGMENT){ + + /* ... ..... multipdp. .... raw data. .... */ + if (size > CLUSTER_SEGMENT) { while (size) { copied_size = (size > CLUSTER_SEGMENT) ? CLUSTER_SEGMENT : size; tty_insert_flip_string(device->serial.tty, psrc + retval, copied_size); @@ -577,20 +569,17 @@ int dpram_tty_insert_data(dpram_device_t *device, const u8 *psrc, u16 size) size = size - copied_size; retval += copied_size; } - return retval; } - return tty_insert_flip_string(device->serial.tty, psrc, size); } static int dpram_read(dpram_device_t *device, const u16 non_cmd) { - int retval = 0; + int retval = 0, tmp_retval = 0; int size = 0; - u16 head, tail; - + #ifdef NO_TTY_DPRAM struct tty_struct *tty = device->serial.tty; #endif @@ -601,44 +590,124 @@ static int dpram_read(dpram_device_t *device, const u16 non_cmd) if (head != tail) { u16 up_tail = 0; - // ------- tail ++++++++++++ head -------- // + /* ------- tail ++++++++++++ head -------- */ if (head > tail) { size = head - tail; #ifdef NO_TTY_DPRAM - if( tty->index != 1) { //index : 0=dpram0, 1=dpram1 - retval = dpram_tty_insert_data(device, (unsigned char *)(SmemBase + (device->in_buff_addr + tail)), size); - } else { //2: dpram1 - retval = multipdp_buf_copy( 0, (unsigned char *)(SmemBase + (device->in_buff_addr + tail)), size); + /* index : dpram0 = 0, dpram1 = 1*/ + if (tty->index == 0) { + retval = dpram_tty_insert_data(device, + (unsigned char *) + (SmemBase + + (device->in_buff_addr + tail)), + size); + if (retval != size) { + if (fmt_error_check == 0) { + fmt_error_check = 1; + pr_err("[c1] %d fmt size mismatch %d(%d)\n", + fmt_error_check, + retval, size); + } + } else { + fmt_error_check = 0; + } + } else if (tty->index == 1) { /* 2: dpram1 */ + retval = multipdp_buf_copy(0, + (unsigned char *) + (SmemBase + + (device->in_buff_addr + tail)), + size); + if (retval != size) + pr_err("[c1] raw size mismatch %d(%d)\n", + retval, size); + } else { + pr_err("[error][c1] Invalid tty index [%u]\n", + tty->index); } #endif - if (retval != size) - dprintk("Size Mismatch : Real Size = %d, Returned Size = %d\n", size, retval); - } else { + } else { /* +++++++ head ------------ tail ++++++++ */ int tmp_size = 0; - // Total Size. + /* Total Size. */ size = device->in_buff_size - tail + head; - // 1. tail -> buffer end. + /* 1. tail -> buffer end. */ tmp_size = device->in_buff_size - tail; #ifdef NO_TTY_DPRAM - if( tty->index != 1) { //index : 0=dpram0, 1=dpram1 - retval = dpram_tty_insert_data(device, (unsigned char *)(SmemBase + (device->in_buff_addr + tail)), tmp_size); + /* index : dpram0 = 0, dpram1 = 1*/ + if (tty->index == 0) { + retval = dpram_tty_insert_data(device, + (unsigned char *) + (SmemBase + + (device->in_buff_addr + tail)), + tmp_size); + + if (retval != tmp_size) { + if (fmt_error_check == 0) { + fmt_error_check = 1; + pr_err("[c2] %d fmt size mismatch %d(%d)\n", + fmt_error_check, + retval, tmp_size); + } } else { - retval = multipdp_buf_copy( 0, (unsigned char *)(SmemBase + (device->in_buff_addr + tail)), tmp_size); + fmt_error_check = 0; } + } else if (tty->index == 1) { + retval = multipdp_buf_copy(0, + (unsigned char *) + (SmemBase + + (device->in_buff_addr + tail)), + tmp_size); + if (retval != tmp_size) + pr_err("[c2] raw size mismatch %d(%d)\n", + retval, tmp_size); + } else { + pr_err("[Error][c2] Invalid tty index [%u]\n", + tty->index); + } #endif - - // 2. buffer start -> head. + /* 2. buffer start -> head.*/ if (size > tmp_size) { #ifdef NO_TTY_DPRAM - if( tty->index != 1) { //index : 0=dpram0, 1=dpram1 - dpram_tty_insert_data(device, (unsigned char *)(SmemBase + device->in_buff_addr), size - tmp_size); - } else { - multipdp_buf_copy( tmp_size, (unsigned char *)(SmemBase + device->in_buff_addr), size - tmp_size); - } + /* index : dpram0 = 0, dpram1 = 1 */ + if (tty->index == 0) { + tmp_retval = dpram_tty_insert_data( + device, + (unsigned char *) + (SmemBase + + device->in_buff_addr), + size-tmp_size); + retval += tmp_retval; + + if (tmp_retval != (size-tmp_size)) { + if (fmt_error_check == 0) { + fmt_error_check = 1; + pr_err("[c3] %d fmt size mismatch %d(%d)\n", + fmt_error_check, + tmp_retval, + size-tmp_size); + } + } else { + fmt_error_check = 0; + } + } else if (tty->index == 1) { + tmp_retval = multipdp_buf_copy(tmp_size, + (unsigned char *) + (SmemBase + + device->in_buff_addr), + size-tmp_size); + retval += tmp_retval; + if (tmp_retval != (size-tmp_size)) + pr_err("[c3] raw size mismatch %d(%d)\n", + tmp_retval, + size-tmp_size); + } else { + pr_err("[Error][c3] Invalid tty index [%u]\n", + tty->index); + } +#else + retval += (size-tmp_size); #endif - retval += (size - tmp_size); } } @@ -651,7 +720,7 @@ static int dpram_read(dpram_device_t *device, const u16 non_cmd) send_interrupt_to_phone(INT_NON_COMMAND(device->mask_res_ack)); #ifdef NO_TTY_DPRAM - if( tty->index == 1) + if (tty->index == 1) multipdp_rx_data(device, retval); #endif @@ -669,12 +738,12 @@ static void dpram_clear(void) /* @LDK@ clear DPRAM except interrupt area */ local_irq_save(flags); - for (i=DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS; iin_head_addr, sizeof(head)); READ_FROM_DPRAM_VERIFY(&tail, device->in_tail_addr, sizeof(tail)); - dprintk("%s : head = 0x%x\n", __func__, head); - dprintk("%s : tail = 0x%x\n", __func__, tail); + dprintk("head = 0x%x\n", head); + dprintk("tail = 0x%x\n", tail); return head - tail; } @@ -739,6 +807,7 @@ static void dpram_phone_on(void) static void dpram_phone_off(void) { + /* Do something */ } static int dpram_phone_getstatus(void) @@ -782,11 +851,26 @@ static void dpram_mem_rw(struct _mem_param *param) } } +static void dpram_extra_mem_rw(struct _param_em *param) +{ + /* @LDK@ write */ + if (param->rw) { + /* we don't have KBL so let's protect it ourself. */ + /* use kernel up to 2.6.38, if you use this line */ + down(&write_mutex); + WRITE_TO_DPRAM(param->offset, param->addr, param->size); + /* use kernel up to 2.6.38, if you use this line */ + up(&write_mutex); + } else { /* @LDK@ read */ + READ_FROM_DPRAM(param->addr, param->offset, param->size); + } +} + static void dpram_ramdump(void) { - printk("[DPRAM] RAMDUMP MODE START!\n"); + dprintk("[DPRAM] RAMDUMP MODE START!\n"); writel(0xCCCC, MSM_SHARED_RAM_BASE + 0x30); - printk("[DPRAM] call msm_proc_comm_reset_modem_now func\n"); + dprintk("[DPRAM] call msm_proc_comm_reset_modem_now func\n"); msm_proc_comm_reset_modem_now(); } @@ -797,30 +881,52 @@ static void print_smem(void) u16 raw_in_head, raw_in_tail, raw_out_head, raw_out_tail; u16 in_interrupt = 0, out_interrupt = 0; u8 raw_out_buf; - struct file *filp; - int writelen; - mm_segment_t old_fs; - static char buf[1024*32]; - int count, chr_count; - 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 *)&raw_out_buf, DPRAM_PDA2PHONE_RAW_BUFFER_ADDRESS, sizeof(raw_out_buf)); - 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); + 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 *)&raw_out_buf, + DPRAM_PDA2PHONE_RAW_BUFFER_ADDRESS, + sizeof(raw_out_buf)); + 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); + dprintk("\n"); - printk("#####################################\n"); - printk("######### DPRAM DUMP DATA (0604) #########\n"); - printk("#####################################\n"); - printk("-------------------------------------\n" + dprintk("#####################################\n"); + dprintk("######### DPRAM DUMP DATA (0604) #########\n"); + dprintk("#####################################\n"); + dprintk("-------------------------------------\n" "| NAME\t\t\t| VALUE\n" "-------------------------------------\n" "| MAGIC CODE\t\t| 0x%04x\n" @@ -842,26 +948,10 @@ static void print_smem(void) raw_in_head, raw_in_tail, raw_out_head, raw_out_tail, raw_out_buf, in_interrupt, out_interrupt ); - - count = 1024 * 8; - chr_count = 0; - old_fs = get_fs(); - set_fs(KERNEL_DS); - - filp = filp_open("/sdcard/dpram_dump",O_CREAT|O_WRONLY,0666); - if(!filp) { - printk("Can't creat /sdcard/dpram_dump file\n"); - } else { - memcpy((void *)buf, (void *)SmemBase, DPRAM_SIZE/*1024*32*/); - writelen = filp->f_op->write(filp,(void *)buf,DPRAM_SIZE/*1024*32*/,&filp->f_pos); - } - set_fs(old_fs); - } void request_phone_power_off_reset(int flag); - /* dpram tty file operations. */ static int dpram_tty_open(struct tty_struct *tty, struct file *file) { @@ -876,16 +966,16 @@ static int dpram_tty_open(struct tty_struct *tty, struct file *file) return -EBUSY; } - if (tty->index == 1) // dpram1 - { + /* dpram1 */ + if (tty->index == 1) { struct termios termios; mm_segment_t oldfs; oldfs = get_fs(); set_fs(get_ds()); - /* use kernel up to 2.6.38, if you use this line */ - if (file->f_op->unlocked_ioctl) - file->f_op->unlocked_ioctl(file, TCGETA, (unsigned long)&termios); + /* use kernel up to 2.6.38, if you use this line */ + if (file->f_op->unlocked_ioctl) + file->f_op->unlocked_ioctl(file, TCGETA, (unsigned long)&termios); set_fs(oldfs); @@ -897,11 +987,10 @@ static int dpram_tty_open(struct tty_struct *tty, struct file *file) termios.c_cc[VTIME] = 1; oldfs = get_fs(); set_fs(get_ds()); - - /* use kernel up to 2.6.38, if you use this line */ - if (file->f_op->unlocked_ioctl) - file->f_op->unlocked_ioctl(file, TCSETA, (unsigned long)&termios); - + + /* use kernel up to 2.6.38, if you use this line */ + if (file->f_op->unlocked_ioctl) + file->f_op->unlocked_ioctl(file, TCSETA, (unsigned long)&termios); set_fs(oldfs); } @@ -928,9 +1017,8 @@ static int dpram_tty_write(struct tty_struct *tty, { dpram_device_t *device = (dpram_device_t *)tty->driver_data; - if (!device) { + if (!device) return 0; - } return dpram_write(device, buffer, count); } @@ -961,66 +1049,68 @@ static int dpram_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned int val; switch (cmd) { - case HN_DPRAM_PHONE_ON: - if (DpramInited) { - dprintk("Doubled Phone On Cmd : do nothing\n"); - return 0; - } - dprintk("[Version 3] HN_DPRAM_PHONE_ON\n"); - dpram_phone_on(); - DpramInited = 1; - return 0; - - case HN_DPRAM_PHONE_OFF: - dprintk("HN_DPRAM_PHONE_OFF\n"); - dpram_phone_off(); - return 0; - - case HN_DPRAM_PHONE_GETSTATUS: - dprintk("HN_DPRAM_PHONE_GETSTATUS\n"); - val = dpram_phone_getstatus(); - return copy_to_user((unsigned int *)arg, &val, sizeof(val)); - - case HN_DPRAM_PHONE_RESET: - dprintk("[RAM DUMP]HN_DPRAM_PHONE_RESET\n"); - dpram_phone_reset(); + case HN_DPRAM_PHONE_ON: + if (DpramInited) { + dprintk("Doubled Phone On Cmd : do nothing\n"); return 0; - - case HN_DPRAM_MEM_RW: + } + dprintk("[Version 3] HN_DPRAM_PHONE_ON\n"); + dpram_phone_on(); + DpramInited = 1; + return 0; + case HN_DPRAM_PHONE_OFF: + dprintk("HN_DPRAM_PHONE_OFF\n"); + dpram_phone_off(); + return 0; + case HN_DPRAM_PHONE_GETSTATUS: + dprintk("HN_DPRAM_PHONE_GETSTATUS\n"); + val = dpram_phone_getstatus(); + return copy_to_user((unsigned int *)arg, &val, sizeof(val)); + case HN_DPRAM_PHONE_RESET: + dprintk("[RAM DUMP]HN_DPRAM_PHONE_RESET\n"); + dpram_phone_reset(); + return 0; + case HN_DPRAM_MEM_RW: { struct _mem_param param; - dprintk("HN_DPRAM_MEM_RW\n"); - val = copy_from_user((void *)¶m, (void *)arg, sizeof(param)); + val = copy_from_user((void *)¶m, (void *)arg, + sizeof(param)); dpram_mem_rw(¶m); - if (!param.dir) { - return copy_to_user((unsigned long *)arg, ¶m, sizeof(param)); - } - + if (!param.dir) + return copy_to_user((unsigned long *)arg, + ¶m, sizeof(param)); return 0; } - - case HN_DPRAM_DUMP: - print_smem(); - return 0; - - case HN_DPRAM_WAKELOCK: - wake_lock(&imei_wake_lock); - return 0; - - case HN_DPRAM_WAKEUNLOCK: - wake_unlock(&imei_wake_lock); - return 0; - - case HN_DPRAM_RAMDUMP: - dpram_ramdump(); + case HN_DPRAM_EXTRA_MEM_RW: + { + struct _param_em param; + dprintk("HN_DPRAM_EXTRA_MEM_RW\n"); + val = copy_from_user((void *)¶m, (void *)arg, + sizeof(param)); + dpram_extra_mem_rw(¶m); + + if (!param.rw) /* Read */ + return copy_to_user((unsigned long *)arg, + ¶m, sizeof(param)); return 0; - default: - dprintk("default\n"); - break; + } + case HN_DPRAM_DUMP: + print_smem(); + return 0; + case HN_DPRAM_WAKELOCK: + wake_lock(&imei_wake_lock); + return 0; + case HN_DPRAM_WAKEUNLOCK: + wake_unlock(&imei_wake_lock); + return 0; + case HN_DPRAM_RAMDUMP: + dpram_ramdump(); + return 0; + default: + break; } - return -ENOIOCTLCMD; } @@ -1062,14 +1152,12 @@ static int dpram_err_read(struct file *filp, char *buf, size_t count, loff_t *pp if (dpram_err_len) { ncopy = min(count, dpram_err_len); - if (copy_to_user(buf, dpram_err_buf, ncopy)) { + if (copy_to_user(buf, dpram_err_buf, ncopy)) ret = -EFAULT; - } else { + else ret = ncopy; - } dpram_err_len = 0; - local_irq_restore(flags); break; } @@ -1117,9 +1205,8 @@ static void res_ack_tasklet_handler(unsigned long data) struct tty_struct *tty = device->serial.tty; if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc->ops->write_wakeup) { + tty->ldisc->ops->write_wakeup) (tty->ldisc->ops->write_wakeup)(tty); - } wake_up_interruptible(&tty->write_wait); } @@ -1138,14 +1225,21 @@ static void send_tasklet_handler(unsigned long data) struct tty_struct *tty = device->serial.tty; ret = dpram_read(device, non_cmd); if (ret == -EAGAIN) { - if (non_cmd & INT_MASK_SEND_F) tasklet_schedule(&fmt_send_tasklet); - if (non_cmd & INT_MASK_SEND_R) tasklet_schedule(&raw_send_tasklet); + if (non_cmd & INT_MASK_SEND_F) + tasklet_schedule(&fmt_send_tasklet); + if (non_cmd & INT_MASK_SEND_R) + tasklet_schedule(&raw_send_tasklet); return ; } #ifdef NO_TTY_DPRAM - if( tty->index != 1) //index : 0=dpram0, 1=dpram1 + /* index: 0 = dpram0, 1 = dpram1 */ + if (tty->index != 1) { +#endif + tty->low_latency = 0; + tty_flip_buffer_push(tty); +#ifdef NO_TTY_DPRAM + } #endif - tty_flip_buffer_push(tty); } else { dpram_drop_data(device); } @@ -1164,8 +1258,8 @@ static void cmd_error_display_handler(void) unsigned long flags; #endif /* _ENABLE_ERROR_DEVICE */ - //for silent reset - printk("[DPRAM] %s : silent reset,\n", __func__); + /* for silent reset */ + dprintk("[DPRAM] : silent reset,\n"); wake_lock(&silent_wake_lock); memset((void *)buf, 0, sizeof (buf)); buf[0] = '1'; @@ -1192,20 +1286,46 @@ static void cmd_phone_start_handler(void) dpram_init_and_report(); } +static void cmd_req_time_sync_handler(void) +{ + /* TODO: add your codes here.. */ +} + +static void cmd_phone_deep_sleep_handler(void) +{ + /* TODO: add your codes here.. */ +} + +static void cmd_nv_rebuilding_handler(void) +{ + /* TODO: add your codes here.. */ +} + +static void cmd_emer_down_handler(void) +{ + /* TODO: add your codes here.. */ +} + static void cmd_chg_detect_noti(void) { + u16 value; u16 irq_clear = 0x0000; - READ_FROM_DPRAM(&value, DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, sizeof(value)); - if(value == 0x40C0) { - WRITE_TO_DPRAM(DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, &irq_clear, DPRAM_INTERRUPT_PORT_SIZE); - printk("[DPRAM:%s] chg_detect irq: 0x%x cleared.\n", __func__, value); + READ_FROM_DPRAM(&value, + DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, + sizeof(value)); + if (value == 0x40C0) { + WRITE_TO_DPRAM(DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, + &irq_clear, + DPRAM_INTERRUPT_PORT_SIZE); + dprintk("[DPRAM] chg_detect irq: 0x%x cleared.\n", value); } else { - READ_FROM_DPRAM(&value, DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, sizeof(value)); - printk("[DPRAM:%s] changed irq: 0x%x detected.\n", __func__, value); + READ_FROM_DPRAM(&value, + DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, + sizeof(value)); + dprintk("[DPRAM] changed irq: 0x%x detected.\n", value); } - } static void cmd_chg_state_changed(void) @@ -1213,40 +1333,53 @@ static void cmd_chg_state_changed(void) u16 value; u16 irq_clear = 0x0000; - READ_FROM_DPRAM(&value, DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, sizeof(value)); - if(value == 0x50C0) { - WRITE_TO_DPRAM(DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, &irq_clear, DPRAM_INTERRUPT_PORT_SIZE); - printk("[DPRAM:%s] chg_state irq: 0x%x cleared.\n", __func__, value); + READ_FROM_DPRAM(&value, + DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, + sizeof(value)); + if (value == 0x50C0) { + WRITE_TO_DPRAM(DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, + &irq_clear, + DPRAM_INTERRUPT_PORT_SIZE); + dprintk("[DPRAM] chg_state irq: 0x%x cleared.\n", value); } else { - READ_FROM_DPRAM(&value, DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, sizeof(value)); - printk("[DPRAM:%s] changed irq: 0x%x detected.\n", __func__, value); + READ_FROM_DPRAM(&value, + DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, + sizeof(value)); + dprintk("[DPRAM] changed irq: 0x%x detected.\n", value); } - } static void command_handler(u16 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: - cmd_phone_start_handler(); - break; - case INT_MASK_CMD_CHG_DETECT_NOTI: - cmd_chg_detect_noti(); - break; - - case INT_MASK_CMD_CHG_STATE_CHANGED: - cmd_chg_state_changed(); - break; - - default: - dprintk("Unknown command..\n"); + 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: + 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; + case INT_MASK_CMD_CHG_DETECT_NOTI: + cmd_chg_detect_noti(); + break; + case INT_MASK_CMD_CHG_STATE_CHANGED: + cmd_chg_state_changed(); + break; + default: + dprintk("Unknown command..\n"); } } @@ -1255,15 +1388,23 @@ static void non_command_handler(u16 non_cmd) u16 head, tail; /* @LDK@ formatted check. */ - READ_FROM_DPRAM_VERIFY(&head, DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, sizeof(head)); - READ_FROM_DPRAM_VERIFY(&tail, DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, sizeof(tail)); + READ_FROM_DPRAM_VERIFY(&head, + DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, + sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, + DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, + sizeof(tail)); if (head != tail) non_cmd |= INT_MASK_SEND_F; /* @LDK@ raw check. */ - READ_FROM_DPRAM_VERIFY(&head, DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS, sizeof(head)); - READ_FROM_DPRAM_VERIFY(&tail, DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS, sizeof(tail)); + READ_FROM_DPRAM_VERIFY(&head, + DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS, + sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, + DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS, + sizeof(tail)); if (head != tail) non_cmd |= INT_MASK_SEND_R; @@ -1271,19 +1412,26 @@ static void non_command_handler(u16 non_cmd) /* @LDK@ +++ scheduling.. +++ */ if (non_cmd & INT_MASK_SEND_F) { wake_lock_timeout(&dpram_wake_lock, HZ/2); - dpram_tasklet_data[FORMATTED_INDEX].device = &dpram_table[FORMATTED_INDEX]; - dpram_tasklet_data[FORMATTED_INDEX].non_cmd = non_cmd; + + dpram_tasklet_data[FORMATTED_INDEX].device = + &dpram_table[FORMATTED_INDEX]; + dpram_tasklet_data[FORMATTED_INDEX].non_cmd = + non_cmd; - fmt_send_tasklet.data = (unsigned long)&dpram_tasklet_data[FORMATTED_INDEX]; + fmt_send_tasklet.data = + (unsigned long)&dpram_tasklet_data[FORMATTED_INDEX]; tasklet_schedule(&fmt_send_tasklet); } if (non_cmd & INT_MASK_SEND_R) { wake_lock_timeout(&dpram_wake_lock, 6*HZ); - dpram_tasklet_data[RAW_INDEX].device = &dpram_table[RAW_INDEX]; - dpram_tasklet_data[RAW_INDEX].non_cmd = non_cmd; + dpram_tasklet_data[RAW_INDEX].device = + &dpram_table[RAW_INDEX]; + dpram_tasklet_data[RAW_INDEX].non_cmd = + non_cmd; - raw_send_tasklet.data = (unsigned long)&dpram_tasklet_data[RAW_INDEX]; + raw_send_tasklet.data = + (unsigned long)&dpram_tasklet_data[RAW_INDEX]; /* @LDK@ raw buffer op. -> soft irq level. */ tasklet_hi_schedule(&raw_send_tasklet); } @@ -1299,13 +1447,17 @@ static void non_command_handler(u16 non_cmd) } } +static inline +void check_int_pin_level(void) +{ +} + /* @LDK@ interrupt handlers. */ static irqreturn_t dpram_interrupt(int irq, void *dev_id) { u16 irq_mask = 0; - - dprintk("%s : interrupt handler\n", __func__); - + + /* wake_lock_timeout(&dpram_wake_lock, HZ/2); */ READ_FROM_DPRAM(&irq_mask, DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, sizeof(irq_mask)); /* valid bit verification. @LDK@ */ @@ -1322,9 +1474,8 @@ static irqreturn_t dpram_interrupt(int irq, void *dev_id) } else { irq_mask &= ~INT_MASK_VALID; non_command_handler(irq_mask); - //wake_lock_timeout(&dpram_wake_lock, 6*HZ); + /* wake_lock_timeout(&dpram_wake_lock, 6*HZ); */ } - return IRQ_HANDLED; } @@ -1337,6 +1488,7 @@ static struct file_operations dpram_err_ops = { .poll = dpram_err_poll, .llseek = no_llseek, + /* TODO: add more operations */ }; #endif /* _ENABLE_ERROR_DEVICE */ @@ -1349,6 +1501,7 @@ static struct tty_operations dpram_tty_ops = { .ioctl = dpram_tty_ioctl, .chars_in_buffer = dpram_tty_chars_in_buffer, + /* TODO: add more operations */ }; #ifdef _ENABLE_ERROR_DEVICE @@ -1364,9 +1517,8 @@ static int register_dpram_err_device(void) struct device *dpram_err_dev_t; int ret = register_chrdev(DRIVER_MAJOR_NUM, DPRAM_ERR_DEVICE, &dpram_err_ops); - if ( ret < 0 ) { + if (ret < 0) return ret; - } dpram_class = class_create(THIS_MODULE, "err"); @@ -1395,9 +1547,8 @@ static int register_dpram_driver(void) /* @LDK@ allocate tty driver */ dpram_tty_driver = alloc_tty_driver(MAX_INDEX); - if (!dpram_tty_driver) { + if (!dpram_tty_driver) return -ENOMEM; - } /* @LDK@ initialize tty driver */ dpram_tty_driver->owner = THIS_MODULE; @@ -1461,22 +1612,19 @@ static int register_interrupt_handler(void) { int retval = 0; - /* @LDK@ interrupt area read - pin level will be driven high. */ dprintk("Dpram clear start\n"); dpram_clear(); - - /* @LDK@ Phone active INT. */ /* @LDK@ dpram interrupt */ - retval = request_irq(INT_A9_M2A_4, dpram_interrupt, IRQF_TRIGGER_RISING, DRIVER_NAME, NULL); + retval = request_irq(INT_A9_M2A_3, dpram_interrupt, IRQF_TRIGGER_RISING, DRIVER_NAME, NULL); if (retval) { dprintk("DPRAM interrupt handler failed.\n"); unregister_dpram_driver(); return -1; } - dprintk("INT_A9_M2A_4 interrupt handler success\n"); + dprintk("INT_A9_M2A_3 interrupt handler success\n"); return 0; } @@ -1487,28 +1635,30 @@ static void check_miss_interrupt(void) u16 head, tail; u16 value; - dprintk("%s\n", __func__); + dprintk("\n"); READ_FROM_DPRAM_VERIFY(&head, DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, sizeof(head)); READ_FROM_DPRAM_VERIFY(&tail, DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, sizeof(tail)); - dprintk("%s : head = 0x%x\n", __func__, head); - dprintk("%s : tail = 0x%x\n", __func__, tail); + dprintk("head = 0x%x\n", head); + dprintk("tail = 0x%x\n", tail); if (head != tail) { dprintk("there is a missed interrupt. try to read it!\n"); - printk("[DPRAM:%s] there is a missed interrupt. try to read it!\n", __func__); + dprintk("[DPRAM] there is a missed interrupt." + "try to read it!\n"); local_irq_save(flags); - dpram_interrupt(INT_A9_M2A_4, NULL); + dpram_interrupt(INT_A9_M2A_3, NULL); local_irq_restore(flags); } READ_FROM_DPRAM(&value, DPRAM_PHONE2PDA_INTERRUPT_ADDRESS, sizeof(value)); if(value == 0x40C0 || value == 0x50C0) { - printk("[DPRAM:%s] there is a missed battery interrupt. try to read it!\n", __func__); + dprintk("[DPRAM] there is a missed battery interrupt." + "try to read it!\n"); local_irq_save(flags); - dpram_interrupt(INT_A9_M2A_4, NULL); + dpram_interrupt(INT_A9_M2A_3, NULL); local_irq_restore(flags); } } @@ -1531,18 +1681,29 @@ enum { void request_phone_power_off_reset(int flag) { - unsigned char fmt_cmd_reset[12] = {0x7F, 0x0A, 0x00, 0x5C, 0x07, 0x00, 0x5C, 0x00, 0x01, 0x03, 0x05, 0x7E}; - unsigned char fmt_cmd_powoff[12] = {0x7F, 0x0A, 0x00, 0x5D, 0x07, 0x00, 0x5D, 0x00, 0x01, 0x02, 0x01, 0x7E}; + unsigned char fmt_cmd_reset[12] = { + 0x7F, 0x0A, 0x00, 0x5C, 0x07, 0x00, + 0x5C, 0x00, 0x01, 0x03, 0x05, 0x7E}; + unsigned char fmt_cmd_powoff[12] = { + 0x7F, 0x0A, 0x00, 0x5D, 0x07, 0x00, + 0x5D, 0x00, 0x01, 0x02, 0x01, 0x7E}; switch(flag) { - case RESET : - printk("Dpram Reset's called\n"); - dpram_write(&dpram_table[0], fmt_cmd_reset, sizeof(fmt_cmd_reset)); - break; - case POWEROFF : - printk("Dpram Poweroff's called\n"); - dpram_write(&dpram_table[0], fmt_cmd_powoff, sizeof(fmt_cmd_powoff)); - break; + case RESET: + dprintk("Dpram Reset's called\n"); + dpram_write(&dpram_table[0], + fmt_cmd_reset, + sizeof(fmt_cmd_reset)); + break; + case POWEROFF: + dprintk("Dpram Poweroff's called\n"); + dpram_write(&dpram_table[0], + fmt_cmd_powoff, + sizeof(fmt_cmd_powoff)); + break; + default: + dprintk("Invalid flag\n"); + break; } } @@ -1552,9 +1713,13 @@ static int __devinit dpram_probe(struct platform_device *dev) /* allocate smem dpram area */ dprintk("SMEM_DPRAM allocation\n"); - SmemBase = (volatile unsigned char *)(smem_alloc(SMEM_ID_VENDOR0, DPRAM_SIZE)); + + SmemBase = (unsigned char *) + (smem_alloc(SMEM_ID_VENDOR0, 0x4000*2)); + if (!SmemBase) { - dprintk("smem_alloc failed : SmemBase = 0x%x\n", (unsigned int)SmemBase); + dprintk("smem_alloc failed : SmemBase = 0x%x\n", + (unsigned int)SmemBase); return -1; } dprintk("SmemBase = 0x%x\n", (unsigned int)SmemBase); @@ -1583,9 +1748,9 @@ static int __devinit dpram_probe(struct platform_device *dev) /* @LDK@ register interrupt handler */ dprintk("Register interrupt handler\n"); - if ((retval = register_interrupt_handler()) < 0) { + retval = register_interrupt_handler(); + if (retval < 0) return -1; - } /* @LDK@ initialize device table */ init_devices(); @@ -1618,20 +1783,12 @@ static struct platform_driver platform_dpram_driver = { }, }; -struct smem_info { - unsigned int info; -}; - -struct smem_info *smem_flag; -int silent_value = 0; -int dump_enable_flag = 0; - -EXPORT_SYMBOL(dump_enable_flag); - -void power_down_registertimer(struct timer_list* ptimer, unsigned long timeover ) +/* hsil */ +void power_down_registertimer(struct timer_list *ptimer, + unsigned long timeover) { - printk("%s\n",__func__); - init_timer(ptimer); + dprintk("into\n"); + init_timer(ptimer); ptimer->expires = get_jiffies_64() + timeover; ptimer->data = (long) NULL; ptimer->function = power_down_timeout; @@ -1640,10 +1797,13 @@ void power_down_registertimer(struct timer_list* ptimer, unsigned long timeover void power_down_timeout(unsigned long arg) { - printk("%s\n",__func__); - - power_down = true; - pm_power_off(); + dprintk("into\n"); + if (!smem_flag) { + pr_err("smem_flag is NULL!"); + return; + } + smem_flag->silent_reset = 0xAEAEAEAE; + msm_proc_comm_reset_modem_now(); } static int silent_read_proc_debug(char *page, char **start, off_t offset, @@ -1658,14 +1818,12 @@ static int silent_write_proc_debug(struct file *file, const char *buffer, { char *buf; - if (count < 1) { + if (count < 1) return -EINVAL; - } buf = kmalloc(count, GFP_KERNEL); - if (!buf) { + if (!buf) return -ENOMEM; - } if (copy_from_user(buf, buffer, count)) { kfree(buf); @@ -1674,10 +1832,10 @@ static int silent_write_proc_debug(struct file *file, const char *buffer, if (buf[0] == '0') { silent_value = 0; - printk("Set silent : %d\n", silent_value); + dprintk("Set silent : %d\n", silent_value); } else if (buf[0] == '1') { silent_value = 1; - printk("Set silent : %d\n", silent_value); + dprintk("Set silent : %d\n", silent_value); } else { kfree(buf); return -EINVAL; @@ -1699,140 +1857,104 @@ static int dump_write_proc_debug(struct file *file, const char *buffer, { char *buf; - if (count < 1) { + if (count < 1) return -EINVAL; - } buf = kmalloc(count, GFP_KERNEL); - if (!buf) { + if (!buf) return -ENOMEM; - } if (copy_from_user(buf, buffer, count)) { kfree(buf); return -EFAULT; } - if (buf[0] == '0') { // low (no RAM dump) - dump_enable_flag = 0; - smem_flag->info = 0xAEAEAEAE; - } else if (buf[0] == '1') { // middle (kernel fault) + if (buf[0] == '0') { /* low (no RAM dump) */ + dump_enable_flag = 0; + if (smem_flag) + smem_flag->silent_reset = 0xAEAEAEAE; + } else if (buf[0] == '1') { /* middle (kernel fault) */ dump_enable_flag = 1; - smem_flag->info = 0xA9A9A9A9; - } else if (buf[0] == '2') { // high (user fault) + if (smem_flag) + smem_flag->silent_reset = 0xA9A9A9A9; + } else if (buf[0] == '2') { /* high (user fault) */ dump_enable_flag = 2; - smem_flag->info = 0xA9A9A9A9; + if (smem_flag) + smem_flag->silent_reset = 0xA9A9A9A9; } else { kfree(buf); return -EINVAL; } - printk("dump_enable_flag : %d, smem_flag : 0x%08x\n", dump_enable_flag, smem_flag->info); - - kfree(buf); - return count; -} - -static int nosim_proc_read(char *page, char **start, off_t offset, - int count, int *eof, void *data) -{ - return 0; -} - -static int nosim_proc_write(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - char *buf; - - if (count < 1 || count > 6) - return -EINVAL; + smem_flag->ram_dump_level = dump_enable_flag; - buf = kmalloc(count, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - if (copy_from_user(buf, buffer, count)) { - kfree(buf); - return -EFAULT; - } - - if (!strncmp(buf,"PANIC",5)) - BUG(); + if (!smem_flag) + pr_err("smem_flag is NULL!"); + else + dprintk("dump_enable_flag : %d, smem_flag : 0x%08x\n", + dump_enable_flag, smem_flag->silent_reset); kfree(buf); return count; } -#ifdef AUTO_POWER_ON_OFF_FLAG /* init & cleanup. */ -#define RESET_ALL 0xab800200 -#define RESET_ALL_VAL 0x1 -#endif static int __init dpram_init(void) { int ret; struct proc_dir_entry *ent; + fmt_error_check = 0; -#ifdef AUTO_POWER_ON_OFF_FLAG - void __iomem *reset_base; - - reset_base = ioremap(RESET_ALL, PAGE_SIZE); - - writel(RESET_ALL_VAL, reset_base); - - while(1); -#endif ret = platform_driver_register(&platform_dpram_driver); - if (ret) { + if (ret) goto error_return; - } wake_lock_init(&imei_wake_lock, WAKE_LOCK_SUSPEND, "IEMI"); wake_lock_init(&dpram_wake_lock, WAKE_LOCK_SUSPEND, "DPRAM"); wake_lock_init(&silent_wake_lock, WAKE_LOCK_SUSPEND, "SILENT_RESET"); platform_device_register_simple("dpram", -1, NULL, 0); - // For silent ram dump mode - + /* For silent ram dump mode */ ent = create_proc_entry("silent", S_IRWXUGO, NULL); ent->read_proc = silent_read_proc_debug; ent->write_proc = silent_write_proc_debug; - smem_flag = (struct smem_info *) smem_alloc(SMEM_ID_VENDOR2, sizeof(struct smem_info)); - if(smem_flag->info == 0xAEAEAEAE) + smem_flag = (struct smem_info *)smem_alloc(SMEM_ID_VENDOR1, + sizeof(struct smem_info)); + if (smem_flag && smem_flag->silent_reset == 0xAEAEAEAE) silent_value = 1; ent = create_proc_entry("dump_enable", S_IRWXUGO, NULL); ent->read_proc = dump_read_proc_debug; ent->write_proc = dump_write_proc_debug; - smem_flag->info = 0xAEAEAEAE; - printk("[Silent Value] : %d\n", silent_value); + if (smem_flag) { + smem_flag->silent_reset = 0; + dprintk("smem_flag = 0x%X\n", smem_flag); + /* Save smem flag address , do NOT change it */ + writel_relaxed((void *)(smem_flag) - MSM_SHARED_RAM_BASE, + MSM_SHARED_RAM_BASE + 0xFFA00); + } - ent = create_proc_entry("nosim_handler", S_IRWXUGO, NULL); - ent->read_proc = nosim_proc_read; - ent->write_proc = nosim_proc_write; + printk("[Silent Value] : %d\n", silent_value); - if(IS_ERR(sec_class)) - pr_err("Failed to create class(sec)!\n"); - dpram_dev = device_create(sec_class, NULL, 0, NULL, "dpram"); - if(IS_ERR(dpram_dev)) + if (IS_ERR(dpram_dev)) pr_err("Failed to create device(dpram)!\n"); - - if(device_create_file(dpram_dev, &dev_attr_info) < 0) + if (device_create_file(dpram_dev, &dev_attr_info) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_info.attr.name); #ifdef CONFIG_DPRAM_WHITELIST - if(device_create_file(dpram_dev, &dev_attr_whitelist) < 0) + if (device_create_file(dpram_dev, &dev_attr_whitelist) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_whitelist.attr.name); #endif + /* hsil */ pm_dev = device_create(sec_class, NULL, 0, NULL, "pm"); - if(IS_ERR(pm_dev)) + if (IS_ERR(pm_dev)) pr_err("Failed to create device(pm)!\n"); - if(device_create_file(pm_dev, &dev_attr_info) < 0) + if (device_create_file(pm_dev, &dev_attr_info) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_info.attr.name); - if(device_create_file(pm_dev, &dev_attr_power_down) < 0) + if (device_create_file(pm_dev, &dev_attr_power_down) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_power_down.attr.name); -error_return: +error_return: return ret; } @@ -1841,6 +1963,7 @@ static void __exit dpram_exit(void) wake_lock_destroy(&dpram_wake_lock); wake_lock_destroy(&imei_wake_lock); wake_lock_destroy(&silent_wake_lock); + platform_driver_unregister(&platform_dpram_driver); } diff --git a/drivers/dpram/dpram.h b/drivers/dpram/dpram.h index 6960dc3787f..56cf644e705 100644 --- a/drivers/dpram/dpram.h +++ b/drivers/dpram/dpram.h @@ -15,7 +15,6 @@ #ifndef __DPRAM_H__ #define __DPRAM_H__ -//#define DPRAM_16MB #if defined(CONFIG_MACH_ANCORA_TMO) || defined(CONFIG_MACH_APACHE) #define DPRAM_64K #else @@ -23,41 +22,43 @@ #endif #ifdef DPRAM_16MB /* if dpram size is 16MB */ -#define DPRAM_SIZE 0x4000 +#define DPRAM_SIZE 0x4000 -#define DPRAM_START_ADDRESS 0x0000 -#define DPRAM_MAGIC_CODE_ADDRESS (DPRAM_START_ADDRESS) -#define DPRAM_ACCESS_ENABLE_ADDRESS (DPRAM_START_ADDRESS + 0x0002) +#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_HEAD_ADDRESS (DPRAM_START_ADDRESS + 0x0004) -#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_FORMATTED_HEAD_ADDRESS (DPRAM_START_ADDRESS + 0x0004) +#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_HEAD_ADDRESS (DPRAM_START_ADDRESS + 0x0404) -#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_PDA2PHONE_RAW_HEAD_ADDRESS (DPRAM_START_ADDRESS + 0x0404) +#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_HEAD_ADDRESS (DPRAM_START_ADDRESS + 0x1FF8) -#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_FORMATTED_HEAD_ADDRESS (DPRAM_START_ADDRESS + 0x1FF8) +#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_HEAD_ADDRESS (DPRAM_START_ADDRESS + 0x23F8) -#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 */ +#define DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS (DPRAM_START_ADDRESS + 0x23F8) +#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 */ /* indicator area*/ -#define DPRAM_INDICATOR_START (DPRAM_START_ADDRESS + 0x3FEC) -#define DPRAM_INDICATOR_SIZE 16 +#define DPRAM_INDICATOR_START (DPRAM_START_ADDRESS + 0x3FEC) +#define DPRAM_INDICATOR_SIZE 16 -#define DPRAM_PDA2PHONE_INTERRUPT_ADDRESS (DPRAM_START_ADDRESS + 0x3FFE) -#define DPRAM_PHONE2PDA_INTERRUPT_ADDRESS (DPRAM_START_ADDRESS + 0x3FFC) -#define DPRAM_INTERRUPT_PORT_SIZE 2 +#define DPRAM_PDA2PHONE_INTERRUPT_ADDRESS (DPRAM_START_ADDRESS + 0x3FFE) +#define DPRAM_PHONE2PDA_INTERRUPT_ADDRESS (DPRAM_START_ADDRESS + 0x3FFC) +#define DPRAM_INTERRUPT_PORT_SIZE 2 #endif + + #ifdef DPRAM_32MB #define DPRAM_SIZE 0x8000 @@ -134,10 +135,16 @@ #endif /* DPRAM_32MB*/ + +#define POWER_DOWN_TIME (30 * HZ) + #ifndef DPRAM_VBASE #define DPRAM_VBASE 0xF0000000 #endif /* DPRAM_VBASE */ + + + /* * interrupt masks. */ @@ -160,7 +167,7 @@ #define INT_MASK_CMD_PHONE_DEEP_SLEEP 0x000A #define INT_MASK_CMD_NV_REBUILDING 0x000B #define INT_MASK_CMD_EMER_DOWN 0x000C -// hsil + #define INT_MASK_CMD_PHONE_RESET 0x000F #define INT_MASK_CMD_CHG_DETECT_NOTI 0x4000 #define INT_MASK_CMD_CHG_STATE_CHANGED 0x5000 @@ -177,25 +184,25 @@ #define INT_MASK_CP_INFINEON 0x0200 #define INT_MASK_CP_BROADCOM 0x0300 -#define INT_COMMAND(x) (INT_MASK_VALID | INT_MASK_COMMAND | x) -#define INT_NON_COMMAND(x) (INT_MASK_VALID | x) +#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 +#define FORMATTED_INDEX 0 +#define RAW_INDEX 1 +#define MAX_INDEX 2 /* ioctl command definitions. */ -#define IOC_SEC_MAGIC (0xf0) +#define IOC_SEC_MAGIC (0xf0) #define HN_DPRAM_PHONE_ON _IO(IOC_SEC_MAGIC, 0xc0) #define HN_DPRAM_PHONE_OFF _IO(IOC_SEC_MAGIC, 0xc1) #define HN_DPRAM_PHONE_GETSTATUS _IOR(IOC_SEC_MAGIC, 0xc2, unsigned int) -#define HN_DPRAM_MEM_RW _IO(IOC_SEC_MAGIC, 0xc3) +#define HN_DPRAM_MEM_RW _IO(IOC_SEC_MAGIC, 0xc3) #define HN_DPRAM_PHONE_RESET _IO(IOC_SEC_MAGIC, 0xc5) -#define HN_DPRAM_DUMP _IO(IOC_SEC_MAGIC, 0xc6) +#define HN_DPRAM_DUMP _IO(IOC_SEC_MAGIC, 0xc6) #define HN_DPRAM_WAKELOCK _IO(IOC_SEC_MAGIC, 0xc7) -#define HN_DPRAM_WAKEUNLOCK _IO(IOC_SEC_MAGIC, 0xca) -#define DPRAM_GET_DGS_INFO _IOR(IOC_SEC_MAGIC, 0xc8, unsigned char [0x100]) +#define HN_DPRAM_EXTRA_MEM_RW _IO(IOC_SEC_MAGIC, 0xc8) #define HN_DPRAM_RAMDUMP _IO(IOC_SEC_MAGIC, 0xc9) +#define HN_DPRAM_WAKEUNLOCK _IO(IOC_SEC_MAGIC, 0xca) /* * structure definitions. @@ -250,6 +257,24 @@ struct _mem_param { int dir; }; +struct _param_em { + unsigned int offset; + unsigned char *addr; + unsigned int size; + int rw; +}; -#endif /* __DPRAM_H__ */ +extern int charging_boot; +extern int dump_enable_flag; +int multipdp_write(const unsigned char *, int); +int multipdp_dump(void); +void yhexdump(const char *buf, int len); +void multipdp_rx_noti_regi(int (*rx_func)(char *, int)); +extern void power_down_timeout(unsigned long arg); +extern void power_down_registertimer(struct timer_list *ptimer,\ + unsigned long timeover); + +/* TODO: add more definitions */ + +#endif /* __DPRAM_H__ */ diff --git a/drivers/dpram/multipdp.c b/drivers/dpram/multipdp.c index 215536225ad..136387cac96 100644 --- a/drivers/dpram/multipdp.c +++ b/drivers/dpram/multipdp.c @@ -33,21 +33,22 @@ #include #include #include +#include "dpram.h" #define NO_TTY_DPRAM 1 #define NO_TTY_RX_BUFF 1 #define NO_TTY_MUTEX_VNET 1 /* Multiple PDP */ -typedef struct pdp_arg { - unsigned char id; - char ifname[16]; -} __attribute__ ((packed)) pdp_arg_t; +struct pdp_arg { + unsigned char id; + char ifname[16]; +} __packed; #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) +#define HN_PDP_ACTIVATE _IOWR(IOC_MZ2_MAGIC, 0xe0, struct pdp_arg) +#define HN_PDP_DEACTIVATE _IOW(IOC_MZ2_MAGIC, 0xe1, struct pdp_arg) +#define HN_PDP_ADJUST _IOW(IOC_MZ2_MAGIC, 0xe2, int) #define HN_PDP_TXSTART _IO(IOC_MZ2_MAGIC, 0xe3) #define HN_PDP_TXSTOP _IO(IOC_MZ2_MAGIC, 0xe4) #define HN_PDP_CSDSTART _IO(IOC_MZ2_MAGIC, 0xe5) @@ -57,8 +58,8 @@ typedef struct pdp_arg { * Driver macros */ -#define MULTIPDP_ERROR /* Define this for error messages */ -#undef USE_LOOPBACK_PING /* Use loopback ping test */ +#define MULTIPDP_ERROR /* Define this for error messages */ +#undef USE_LOOPBACK_PING /* Use loopback ping test */ #ifdef USE_LOOPBACK_PING #include @@ -66,24 +67,18 @@ typedef struct pdp_arg { #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 - +/* 0 : do not print log msg + 1 : error log msg + 2 : low level debug log msg + 3~ : high level debug log msg +*/ +#define CONFIG_MULTIPDP_DEBUG 0 #if (CONFIG_MULTIPDP_DEBUG > 0) #define DPRINTK(N, X...) \ do { \ if (N <= CONFIG_MULTIPDP_DEBUG) { \ - printk("%s(): ", __FUNCTION__); \ - printk(X); \ + printk(KERN_INFO "%s(): ", __func__); \ + printk(KERN_INFO X); \ } \ } while (0) #else @@ -104,66 +99,46 @@ typedef struct pdp_arg { /* Device node name for application interface */ #define APP_DEVNAME "multipdp" +#define APP_NAME_MAX_LEN 16 /* DPRAM device node name */ #define DPRAM_DEVNAME "/dev/dpram1" /* Device types */ -#define DEV_TYPE_NET 0 /* network device for IP data */ -#define DEV_TYPE_SERIAL 1 /* serial device for CSD */ +#define DEV_TYPE_NET 0 /* network device for IP data */ +#define DEV_TYPE_SERIAL 1 /* serial device for CSD */ /* Device flags */ -#define DEV_FLAG_STICKY 0x1 /* Sticky */ +#define DEV_FLAG_STICKY 0x1 /* Sticky */ /* Device major & minor number */ -#define CSD_MAJOR_NUM 234 +#define CSD_MAJOR_NUM 235 #define CSD_MINOR_NUM 0 -static int pdp_net_activation_count = 0; -static int vnet_start_xmit_flag = 0; +static int pdp_net_activation_count; +static int vnet_start_xmit_flag; +/********** for CPLog Test **************/ +static struct sk_buff_head cplog_sk_buf_rx_q; +static struct workqueue_struct *cplog_rx_wq; +static struct work_struct cplog_work; +static void cplog_work_func(struct work_struct *work); +#define APP_LOOPBACK_TEST 1 #ifdef LOOP_BACK_TEST - -/********************************************************************** - loop back test implementation - - Usage : - - 1. start test - - loopback test can be triggered by setting '/sys/class/misc/multipdp/loopback' - - " - # cd /sys/class/misc/multipdp/ - # echo start > loopback - - 2. get stastic result - - it shows some result value for this test) - - " - # cat loopback - - 3. stop test - - it stops loopback test - - " - # echo stop > loopback - (be careful, it does not show any result) - - -**********************************************************************/ +/* + Usage + 1. #cd /sys/class/misc/multipdp/ + 2. #echo start > loopback + 3. #cat loopback + 4. #echo stop > loopback + */ #define LOOP_BACK_CHANNEL 31 -int loopback_ongoing = 0; - +int loopback_ongoing; char loopback_data[MAX_PDP_DATA_LEN]; - char loopback_value[256]; -struct loopback_result -{ +struct loopback_result { int nTransfered; int nPacketDataSize; struct timeval nStartTime; @@ -172,140 +147,131 @@ struct loopback_result static struct loopback_result loopback_res; -static ssize_t show_loopback_value(struct device *dev, struct device_attribute *attr, char * buf) +static ssize_t show_loopback_value(struct device *dev, + struct device_attribute *attr, char *buf) { unsigned int nElapsedtime_s, total_size; - if(!strncmp(loopback_value, "start", 5)) { - // show elapsed value + if (!strncmp(loopback_value, "start", 5)) { + /* show elapsed value */ do_gettimeofday(&loopback_res.nEndTime); - nElapsedtime_s = (loopback_res.nEndTime.tv_sec - loopback_res.nStartTime.tv_sec) - + (loopback_res.nEndTime.tv_usec - loopback_res.nStartTime.tv_usec)/1000000; - - total_size = loopback_res.nTransfered * loopback_res.nPacketDataSize; - - return sprintf(buf, - "\n===== LoopBack Test Result =====\n\n" - "Transfered Items = %d\n" - "Packet Data Size = %d\n" - "Total transfer size = %d\n" - "Elapsed Time = %d (s)\n" - "Mean Value = %d (byte/sec)\n" - "\n=====================================\n" - , - loopback_res.nTransfered, - loopback_res.nPacketDataSize, - total_size, - nElapsedtime_s, - total_size/nElapsedtime_s - ); - + nElapsedtime_s = + (loopback_res.nEndTime.tv_sec - + loopback_res.nStartTime.tv_sec) + + (loopback_res.nEndTime.tv_usec - + loopback_res.nStartTime.tv_usec) / 1000000; + + total_size = + loopback_res.nTransfered * loopback_res.nPacketDataSize; + + /* edit */ + return sprintf(buf, 512, + "\n===== LoopBack Test Result =====\n\n" + "Transfered Items = %d\n" + "Packet Data Size = %d\n" + "Total transfer size = %d\n" + "Elapsed Time = %d (s)\n" + "Mean Value = %d (byte/sec)\n" + "\n=====================================\n", + loopback_res.nTransfered, + loopback_res.nPacketDataSize, + total_size, + nElapsedtime_s, total_size / nElapsedtime_s); } else { - - return sprintf(buf, "loopback test is not on going\n"); + /* edit */ + return sprintf(buf, 32, "loopback test is not on going\n"); } } -static struct pdp_info * pdp_get_dev(u8 id); +static struct pdp_info *pdp_get_dev(u8 id); static int pdp_mux(struct pdp_info *dev, const void *data, size_t len); -static send_loop_back_packet(const char* data, int size) +static send_loop_back_packet(const char *data, int size) { - struct pdp_info* dev = pdp_get_dev(LOOP_BACK_CHANNEL); + struct pdp_info *dev = pdp_get_dev(LOOP_BACK_CHANNEL); if (loopback_ongoing) { pdp_mux(dev, data, size); loopback_res.nTransfered++; - } - + } } -static ssize_t store_loopback_value(struct device *dev, struct device_attribute *attr, char * buf, size_t count) +static ssize_t store_loopback_value(struct device *dev, + struct device_attribute *attr, char *buf, + size_t count) { - int i; - - // we can send various size of data by setting this value as mutiple of 10 - int data_size = 1500; - + int i, data_size = 1500; char temp_str[10] = "0123456789"; - if ( !strncmp(buf, "start", 5)) { + + if (!strncmp(buf, "start", 5)) { sscanf(buf, "%s", loopback_value); - // initialize stastics value loopback_res.nTransfered = 0; loopback_res.nPacketDataSize = data_size; - - // make data - for (i = 0; i < (data_size/10); i++) { - memcpy((loopback_data + i*10), temp_str, 10); - } + + for (i = 0; i < (data_size / 10); i++) + memcpy((loopback_data + i * 10), temp_str, 10); loopback_ongoing = 1; - do_gettimeofday(&loopback_res.nStartTime); - send_loop_back_packet(loopback_data, data_size); } else if (!strncmp(buf, "stop", 4)) { sscanf(buf, "%s", loopback_value); - + loopback_ongoing = 0; - do_gettimeofday(&loopback_res.nEndTime); } return strnlen(buf, 256); } -static DEVICE_ATTR(loopback, S_IRUGO|S_IWUSR, show_loopback_value, store_loopback_value); +static DEVICE_ATTR(loopback, S_IRUGO | S_IWUSR, show_loopback_value, + store_loopback_value); #endif - /* * Variable types */ /* PDP data packet header format */ struct pdp_hdr { - u16 len; /* Data length */ - u8 id; /* Channel ID */ - u8 control; /* Control field */ -} __attribute__ ((packed)); + u16 len; /* Data length */ + u8 id; /* Channel ID */ + u8 control; /* Control field */ +} __packed; /* PDP information type */ struct pdp_info { /* PDP context ID */ - u8 id; + u8 id; /* Device type */ - unsigned type; + unsigned type; /* Device flags */ - unsigned flags; + unsigned flags; /* Tx packet buffer */ - u8 *tx_buf; + u8 *tx_buf; /* App device interface */ union { /* Virtual network interface */ struct { - struct net_device *net; - struct net_device_stats stats; - struct work_struct xmit_task; + struct net_device *net; + struct net_device_stats stats; + struct work_struct xmit_task; } vnet_u; /* Virtual serial interface */ struct { -#ifdef CONFIG_ENABLE_TTY_CIQ - struct tty_driver tty_driver[7]; // CSD, ROUTER, GPS, XGPS, SMD -#else - struct tty_driver tty_driver[5]; // CSD, ROUTER, GPS, XGPS, SMD -#endif - int refcount; - struct tty_struct *tty_table[1]; - struct ktermios *termios[1]; - char tty_name[16]; - struct tty_struct *tty; - struct semaphore write_lock; + /* CSD, ROUTER, GPS, XGPS, CDMA, SMD, CPLOG, LOOPBACK */ + struct tty_driver tty_driver[8]; + int refcount; + struct tty_struct *tty_table[1]; + struct ktermios *termios[1]; + char tty_name[16]; + struct tty_struct *tty; + struct semaphore write_lock; } vs_u; } dev_u; #define vn_dev dev_u.vnet_u @@ -329,51 +295,64 @@ static struct file *dpram_filp; static DECLARE_COMPLETION(dpram_complete); static int g_adjust = 9; -static unsigned long workqueue_data = 0; +static unsigned long workqueue_data; #ifndef NO_TTY_RX_BUFF static unsigned char pdp_rx_buf[MAX_PDP_DATA_LEN]; #else -#define MAX_RX_BUFF_LEN 16*1024 +#define MAX_RX_BUFF_LEN (16*1024) static unsigned char pdp_rx_buf[MAX_RX_BUFF_LEN]; #endif -static int pdp_tx_flag = 0; -unsigned char *prx_buf = NULL; -unsigned int count = 0; -static int pdp_csd_flag = 0; - -int fp_vsCSD = 0; -int fp_vsGPS = 0; -int fp_vsEXGPS = 0; -int fp_vsEFS = 0; -int fp_vsSMD = 0; -#ifdef CONFIG_ENABLE_TTY_CIQ -int fp_vsCIQ0 = 0; -int fp_vsCIQ1 = 0; -#endif - +static int pdp_tx_flag; +unsigned char *prx_buf; +unsigned int count; +static int pdp_csd_flag; + +int fp_vsCSD; +int fp_vsGPS; +int fp_vsEXGPS; +int fp_vsEFS; +int fp_vsSMD; +int fp_vsCPLOG; +int fp_vsLOOPBACK; /* * Function declarations */ 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 inline struct pdp_info *pdp_get_serdev(const char *name); -static struct tty_driver* get_tty_driver_by_id(struct pdp_info *dev) +static struct tty_driver *get_tty_driver_by_id(struct pdp_info *dev) { int index = 0; switch (dev->id) { - case 1: index = 0; break; - case 8: index = 1; break; - case 5: index = 2; break; - case 6: index = 3; break; - case 25: index = 4; break; -#ifdef CONFIG_ENABLE_TTY_CIQ - case 9: index = 5; break; - case 26: index = 6; break; -#endif - default: index = 0; + case 1: + index = 0; + break; + case 8: + index = 1; + break; + case 5: + index = 2; + break; + case 6: + index = 3; + break; + case 7: + index = 7; + break; + case 25: + index = 4; + break; + case 29: + index = 5; + break; + case 31: + index = 6; + break; + default: + index = 0; } return &dev->vs_dev.tty_driver[index]; @@ -384,49 +363,66 @@ static int get_minor_start_index(int id) int start = 0; switch (id) { - case 1: start = 0; break; - case 8: start = 1; break; - case 5: start = 2; break; - case 6: start = 3; break; - case 25: start = 4; break; -#ifdef CONFIG_ENABLE_TTY_CIQ - case 9: start = 5; break; - case 26: start = 6; break; -#endif - default: start = 0; + case 1: + start = 0; + break; + case 8: + start = 1; + break; + case 5: + start = 2; + break; + case 6: + start = 3; + break; + case 7: + start = 7; + break; + case 25: + start = 4; + break; + case 29: + start = 5; + break; + case 31: + start = 6; + break; + default: + start = 0; } return start; } struct wake_lock pdp_wake_lock; -/* added wake_lock time for RIL to change the waketime for implementing Fast Dormancy LCD On/Off Timer */ +/* added wake_lock time for RIL to change the waketime + for implementing Fast Dormancy LCD On/Off Timer */ #define DEFAULT_RAW_WAKE_TIME (6*HZ) -static long pdp_wake_time; /* jiffies */ /* wake time for not fmt packet */ - +/* jiffies *//* wake time for not fmt packet */ +static long pdp_wake_time; /* sys fs */ struct class *pdp_class; EXPORT_SYMBOL(pdp_class); struct device *pdp_dev; EXPORT_SYMBOL(pdp_dev); - static ssize_t show_waketime(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { char *p = buf; unsigned int msec; unsigned long j; - j = pdp_wake_time; + j = pdp_wake_time; msec = jiffies_to_msecs(j); - p += sprintf(p, "%u\n", msec); + p += sprintf(p, sizeof(msec), "%u\n", msec); return p - buf; } static ssize_t store_waketime(struct device *d, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, const char *buf, + size_t count) { unsigned long msec; unsigned long j; @@ -437,14 +433,13 @@ static ssize_t store_waketime(struct device *d, return count; j = msecs_to_jiffies(msec); - pdp_wake_time = j; + pdp_wake_time = j; return count; } static DEVICE_ATTR(waketime, 0664, show_waketime, store_waketime); - /* * DPRAM I/O functions */ @@ -457,12 +452,12 @@ static inline struct file *dpram_open(void) filp = filp_open(DPRAM_DEVNAME, O_RDWR|O_NONBLOCK, 0); if (IS_ERR(filp)) { - DPRINTK(1, "filp_open() failed~!: %ld\n", PTR_ERR(filp)); + pr_err("[MULTIPDP] filp_open() failed~!: %ld\n", PTR_ERR(filp)); return NULL; } - oldfs = get_fs(); set_fs(get_ds()); - + oldfs = get_fs(); + set_fs(get_ds()); ret = filp->f_op->unlocked_ioctl(filp, TCGETA, (unsigned long)&termios); set_fs(oldfs); if (ret < 0) { @@ -478,7 +473,8 @@ static inline struct file *dpram_open(void) termios.c_cc[VMIN] = 1; termios.c_cc[VTIME] = 1; - oldfs = get_fs(); set_fs(get_ds()); + oldfs = get_fs(); + set_fs(get_ds()); ret = filp->f_op->unlocked_ioctl(filp, TCSETA, (unsigned long)&termios); set_fs(oldfs); if (ret < 0) { @@ -499,13 +495,17 @@ static inline int dpram_poll(struct file *filp) int ret; unsigned int mask; struct poll_wqueues wait_table; + /* + poll_table wait_table; + */ mm_segment_t oldfs; poll_initwait(&wait_table); for (;;) { set_current_state(TASK_INTERRUPTIBLE); - oldfs = get_fs(); set_fs(get_ds()); + oldfs = get_fs(); + set_fs(get_ds()); mask = filp->f_op->poll(filp, &wait_table.pt); set_fs(oldfs); @@ -516,7 +516,7 @@ static inline int dpram_poll(struct file *filp) } if (wait_table.error) { - DPRINTK(1, "error in f_op->poll()\n"); + pr_err("[MULTIPDP] error in f_op->poll()\n"); ret = wait_table.error; break; } @@ -541,25 +541,27 @@ static inline int dpram_write(struct file *filp, const void *buf, size_t count, int ret, n = 0; mm_segment_t oldfs; - if(pdp_tx_flag) { + if (pdp_tx_flag) { + pr_err("[MULTIPDP] Invalid flag\n"); return -EAGAIN; } while (count) { if (!dpram_filp) { - DPRINTK(1, "DPRAM not available\n"); + pr_err("[MULTIPDP] DPRAM not available\n"); return -ENODEV; } dpram_filp->f_flags |= O_NONBLOCK; - oldfs = get_fs(); set_fs(get_ds()); + oldfs = get_fs(); + set_fs(get_ds()); ret = filp->f_op->write(filp, buf + n, count, &filp->f_pos); set_fs(oldfs); dpram_filp->f_flags &= ~O_NONBLOCK; if (ret < 0) { - if (ret == -EAGAIN && !nonblock) { + if (ret == -EAGAIN && !nonblock) continue; - } - DPRINTK(1, "f_op->write() failed: %d\n", ret); + + pr_err("[MULTIPDP] f_op->write() failed: %d\n", ret); return ret; } n += ret; @@ -574,15 +576,16 @@ static inline int dpram_read(struct file *filp, void *buf, size_t count) mm_segment_t oldfs; while (count) { dpram_filp->f_flags |= O_NONBLOCK; - oldfs = get_fs(); set_fs(get_ds()); + oldfs = get_fs(); + set_fs(get_ds()); ret = filp->f_op->read(filp, buf + n, count, &filp->f_pos); set_fs(oldfs); dpram_filp->f_flags &= ~O_NONBLOCK; if (ret < 0) { - if (ret == -EAGAIN) { + if (ret == -EAGAIN) continue; - } - DPRINTK(1, "f_op->read() failed: %d\n", ret); + + pr_err("[MULTIPDP] f_op->read() failed: %d\n", ret); return ret; } n += ret; @@ -598,17 +601,22 @@ static inline int dpram_flush_rx(struct file *filp, size_t count) mm_segment_t oldfs; buf = vmalloc(count); - if (buf == NULL) return -ENOMEM; + if (buf == NULL) { + pr_err("[MULTIPDP] Memory alloc failed\n"); + return -ENOMEM; + } while (count) { dpram_filp->f_flags |= O_NONBLOCK; - oldfs = get_fs(); set_fs(get_ds()); + oldfs = get_fs(); + set_fs(get_ds()); ret = filp->f_op->read(filp, buf + n, count, &filp->f_pos); set_fs(oldfs); dpram_filp->f_flags &= ~O_NONBLOCK; if (ret < 0) { - if (ret == -EAGAIN) continue; - DPRINTK(1, "f_op->read() failed: %d\n", ret); + if (ret == -EAGAIN) + continue; + pr_err("[MULTIPDP] f_op->read() failed: %d\n", ret); vfree(buf); return ret; } @@ -621,31 +629,30 @@ static inline int dpram_flush_rx(struct file *filp, size_t count) #ifdef NO_TTY_DPRAM static int multipdp_demux(char *buf, int len); -int multipdp_rx_cback( char *buf, int len) +int multipdp_rx_cback(char *buf, int len) { - int i=0; + int i = 0; int ret = 0; - struct pdp_hdr * phdr = NULL; + struct pdp_hdr *phdr = NULL; + + DPRINTK(2, "Receive packet size from cp=%d\n", len); - for( i=0; i < len; i++) { + for (i = 0; i < len; i++) { if (buf[i] == 0x7f) { + phdr = (struct pdp_hdr *)&buf[i + 1]; - phdr = (struct pdp_hdr*)&buf[i+1]; - - if( buf[i+phdr->len+1] != 0x7E) - printk("==== NOT 0x7E ...\n"); - - ret = multipdp_demux( (char *)&buf[i+1], len-i-1); + if (buf[i + phdr->len + 1] != 0x7E) + pr_err("[MULTIPDP] NOT 0x7E (Not end byte)\n"); - i = i + phdr->len+1; + ret = multipdp_demux((char *)&buf[i + 1], len - i - 1); + i = i + phdr->len + 1; - if( ret < 0 || ret == 0 ) { - printk("multipdp_demux : Error .. ret[%d]!!!!!!\n", ret); + if (ret < 0 || ret == 0) break; - } - } + } else + pr_err("[MULTIPDP] NOT 0x7F (Not start byte)\n"); } - return(i); + return i; } #endif @@ -657,9 +664,10 @@ static int dpram_thread(void *data) struct sched_param schedpar; dpram_task = current; - daemonize("dpram_thread"); - strcpy(current->comm, "multipdp"); + strncpy(current->comm, + APP_DEVNAME, + APP_NAME_MAX_LEN); schedpar.sched_priority = 1; sched_setscheduler(current, SCHED_FIFO, &schedpar); @@ -669,15 +677,18 @@ static int dpram_thread(void *data) recalc_sigpending(); for (i = 0; i < 10; i++) { - filp = dpram_open(); - if (filp == NULL) { - EPRINTK("dpram_open failed! retry\n"); - msleep(1000); + filp = dpram_open(); + if (filp == NULL) { + pr_err("[MULTIPDP] dpram_open failed! retry\n"); + if (i < 2) + msleep(100); + else + msleep(1000); } else break; } if (filp == NULL) { - EPRINTK("dpram_open failed!\n"); + pr_err("[MULTIPDP] dpram_open failed!\n"); goto out; } @@ -696,44 +707,46 @@ static int dpram_thread(void *data) ret = 0; break; } - } else if (ret < 0) { - EPRINTK("dpram_poll() failed\n"); + } + + else if (ret < 0) { + pr_err("[MULTIPDP] dpram_poll() failed\n"); break; - } else { + } + + else { char ch; ret = dpram_read(dpram_filp, &ch, sizeof(ch)); - if(ret < 0) { + if (ret < 0) return ret; - } - if (ch == 0x7f) { + if (ch == 0x7f) pdp_demux(); - } } } dpram_close(filp); dpram_filp = NULL; -out: + out: dpram_task = NULL; /* send finish signal and exit */ complete_and_exit(&dpram_complete, ret); } + /* * Virtual Network Interface functions */ static int vnet_open(struct net_device *net) { - struct pdp_info *dev = (struct pdp_info *)net->ml_priv; if (pdp_net_activation_count == 0) { vnet_start_xmit_flag = 0; - printk("[%s] clear xmit_flag, there's no net device\n", __func__); + pr_err("[MULTIPDP] clear xmit_flag, there's no net device\n"); } INIT_WORK(&dev->vn_dev.xmit_task, NULL); netif_start_queue(net); @@ -743,24 +756,22 @@ static int vnet_open(struct net_device *net) static int vnet_stop(struct net_device *net) { + struct pdp_info *dev = (struct pdp_info *)net->ml_priv; + netif_stop_queue(net); - flush_scheduled_work(); /* flush any pending tx tasks */ + flush_work(&dev->vn_dev.xmit_task); /* flush any pending tx tasks */ return 0; } - - static void vnet_defer_xmit(struct work_struct *data) { - struct sk_buff *skb = (struct sk_buff *)workqueue_data; - struct net_device *net = (struct net_device *)skb->dev; - struct pdp_info *dev = (struct pdp_info *)net->ml_priv; - + struct sk_buff *skb = (struct sk_buff *)workqueue_data; + struct net_device *net = (struct net_device *)skb->dev; + struct pdp_info *dev = (struct pdp_info *)net->ml_priv; int ret = 0; - - down(&pdp_txlock); + down(&pdp_txlock); ret = pdp_mux(dev, skb->data, skb->len); if (ret < 0) { @@ -774,15 +785,12 @@ static void vnet_defer_xmit(struct work_struct *data) vnet_start_xmit_flag = 0; up(&pdp_txlock); - netif_wake_queue(net); } static int vnet_start_xmit(struct sk_buff *skb, struct net_device *net) { - struct pdp_info *dev = (struct pdp_info *)net->ml_priv; - #ifdef USE_LOOPBACK_PING int ret; struct sk_buff *skb2; @@ -796,7 +804,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *net) skb2 = alloc_skb(skb->len, GFP_ATOMIC); if (skb2 == NULL) { - DPRINTK(1, "alloc_skb() failed\n"); + pr_err("[MULTIPDP] alloc_skb() failed\n"); dev_kfree_skb_any(skb); return -ENOMEM; } @@ -824,12 +832,12 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *net) dev->vn_dev.stats.rx_packets++; dev->vn_dev.stats.rx_bytes += skb->len; #else - if (vnet_start_xmit_flag != 0) { - return NETDEV_TX_BUSY; - } + if (vnet_start_xmit_flag != 0) + return NETDEV_TX_BUSY; + vnet_start_xmit_flag = 1; workqueue_data = (unsigned long)skb; - PREPARE_WORK(&dev->vn_dev.xmit_task,vnet_defer_xmit); + PREPARE_WORK(&dev->vn_dev.xmit_task, vnet_defer_xmit); schedule_work(&dev->vn_dev.xmit_task); netif_stop_queue(net); #endif @@ -844,23 +852,25 @@ static int multipdp_vnet_recv(struct pdp_info *dev, char *buf, size_t len) int ret; /* @LDK@ for multiple pdp.. , ex) email & streaming.. by hobac. */ - if (!dev) { + if (!dev) return 0; + + if (dev->vn_dev.net == NULL) { + pr_err("[MULTIPDP] dev->vn_dev.net == NULL!\n"); + return -ENODEV; } - if( dev->vn_dev.net == NULL ) - printk("====================> dev->vn_dev.net == NULL .. !!!!!!!\n"); - if (!netif_running(dev->vn_dev.net)) { - DPRINTK(1, "%s(id: %u) is not running\n", - dev->vn_dev.net->name, dev->id); + pr_err("[MULTIPDP] %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"); + pr_err("[MULTIPDP] alloc_skb() failed\n"); return -ENOMEM; } @@ -868,7 +878,7 @@ static int multipdp_vnet_recv(struct pdp_info *dev, char *buf, size_t len) ret = len; if (ret < 0) { - DPRINTK(1, "dpram_read() failed: %d\n", ret); + pr_err("[MULTIPDP] dpram_read() failed: %d\n", ret); dev_kfree_skb_any(skb); return ret; } @@ -892,26 +902,25 @@ static int vnet_recv(struct pdp_info *dev, size_t len) int ret; /* @LDK@ for multiple pdp.. , ex) email & streaming.. by hobac. */ - if (!dev) { + if (!dev) return 0; - } if (!netif_running(dev->vn_dev.net)) { - DPRINTK(1, "%s(id: %u) is not running\n", - dev->vn_dev.net->name, dev->id); + pr_err("[MULTIPDP] %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"); + pr_err("[MULTIPDP] 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); + pr_err("[MULTIPDP] dpram_read() failed: %d\n", ret); dev_kfree_skb_any(skb); return ret; } @@ -928,6 +937,7 @@ static int vnet_recv(struct pdp_info *dev, size_t len) return 0; } + static struct net_device_stats *vnet_get_stats(struct net_device *net) { struct pdp_info *dev = (struct pdp_info *)net->ml_priv; @@ -936,7 +946,6 @@ static struct net_device_stats *vnet_get_stats(struct net_device *net) static void vnet_tx_timeout(struct net_device *net) { - struct pdp_info *dev = (struct pdp_info *)net->ml_priv; net->trans_start = jiffies; @@ -945,24 +954,23 @@ static void vnet_tx_timeout(struct net_device *net) } static const struct net_device_ops pdp_netdev_ops = { - .ndo_open = vnet_open, - .ndo_stop = vnet_stop, - .ndo_start_xmit = vnet_start_xmit, - .ndo_get_stats = vnet_get_stats, - .ndo_tx_timeout = vnet_tx_timeout, + .ndo_open = vnet_open, + .ndo_stop = vnet_stop, + .ndo_start_xmit = vnet_start_xmit, + .ndo_get_stats = vnet_get_stats, + .ndo_tx_timeout = vnet_tx_timeout, }; - static void vnet_setup(struct net_device *dev) { dev->netdev_ops = &pdp_netdev_ops; - dev->type = ARPHRD_PPP; - dev->hard_header_len = 0; - dev->mtu = MAX_PDP_DATA_LEN; - dev->addr_len = 0; - dev->tx_queue_len = 1000; - dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; - dev->watchdog_timeo = 40 * HZ; + dev->type = ARPHRD_PPP; + dev->hard_header_len = 0; + dev->mtu = MAX_PDP_DATA_LEN; + dev->addr_len = 0; + dev->tx_queue_len = 1000; + dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; + dev->watchdog_timeo = 40 * HZ; } static struct net_device *vnet_add_dev(void *priv) @@ -972,23 +980,25 @@ static struct net_device *vnet_add_dev(void *priv) dev = alloc_netdev(0, "pdp%d", vnet_setup); if (dev == NULL) { - DPRINTK(1, "out of memory\n"); + pr_err("[MULTIPDP] out of memory\n"); return NULL; } - - dev->ml_priv = priv; - + dev->ml_priv = priv; ret = register_netdev(dev); if (ret != 0) { - DPRINTK(1, "register_netdevice failed: %d\n", ret); + pr_err("[MULTIPDP] register_netdevice failed: %d\n", + ret); kfree(dev); return NULL; } return dev; } + static void vnet_del_dev(struct net_device *net) { + DPRINTK(2, "%s network device removed\n", + net->name); unregister_netdev(net); kfree(net); } @@ -1001,49 +1011,53 @@ static int vs_open(struct tty_struct *tty, struct file *filp) { struct pdp_info *dev; - dev = pdp_get_serdev(tty->driver->name); // 2.6 kernel porting + DPRINTK(1, "into => tty[%s]\n", tty->name); + /* 2.6 kernel porting */ + dev = pdp_get_serdev(tty->driver->name); if (dev == NULL) { + pr_err("[MULTIPDP] dev is null\n"); return -ENODEV; } switch (dev->id) { - case 1: - fp_vsCSD = 1; - break; + case 1: + fp_vsCSD = 1; + break; - case 5: - fp_vsGPS = 1; - break; + case 5: + fp_vsGPS = 1; + break; - case 6: - fp_vsEXGPS = 1; - break; + case 6: + fp_vsEXGPS = 1; + break; - case 8 : - fp_vsEFS = 1; - break; + case 8: + fp_vsEFS = 1; + break; - case 25 : - fp_vsSMD = 1; - break; + case 25: + fp_vsSMD = 1; + break; -#ifdef CONFIG_ENABLE_TTY_CIQ - case 9 : - fp_vsCIQ1 = 1; - break; + case 29: + fp_vsCPLOG = 1; + break; - case 26 : - fp_vsCIQ0 = 1; - break; -#endif - default: - break; + case 31: + fp_vsLOOPBACK = 1; + break; + + default: + break; } tty->driver_data = (void *)dev; - tty->low_latency = 1; + /* change 1 to 0 */ + tty->low_latency = 0; dev->vs_dev.tty = tty; + dev->vs_dev.refcount++; return 0; } @@ -1052,176 +1066,259 @@ static void vs_close(struct tty_struct *tty, struct file *filp) { struct pdp_info *dev = (struct pdp_info *)tty->driver_data; + DPRINTK(1, "into => tty[%s]\n", tty->name); switch (dev->id) { - case 1: - fp_vsCSD = 0; - break; + case 1: + fp_vsCSD = 0; + break; - case 5: - fp_vsGPS = 0; - break; + case 5: + fp_vsGPS = 0; + break; - case 6: - fp_vsEXGPS = 0; - break; + case 6: + fp_vsEXGPS = 0; + break; - case 8 : - fp_vsEFS = 0; - break; + case 8: + fp_vsEFS = 0; + break; - case 25 : - fp_vsSMD = 0; - break; + case 25: + fp_vsSMD = 0; + break; -#ifdef CONFIG_ENABLE_TTY_CIQ - case 9 : - fp_vsCIQ1 = 0; - break; + case 29: + fp_vsCPLOG = 0; + break; - case 26 : - fp_vsCIQ0 = 0; - break; -#endif - default: - break; -} + case 31: + fp_vsLOOPBACK = 0; + break; + default: + break; + } + dev->vs_dev.refcount--; } -static int vs_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int vs_write(struct tty_struct *tty, const unsigned char *buf, int count) { int ret; - struct pdp_info *dev; - - dev = (struct pdp_info *)tty->driver_data; - + struct pdp_info *dev; + /* + mutex_lock(&pdp_lock); + */ + dev = (struct pdp_info *)tty->driver_data; ret = pdp_mux(dev, buf, count); - if (ret == 0) { + if (ret == 0) ret = count; - } - + /* + mutex_unlock(&pdp_lock); + */ + return ret; } -static int vs_write_room(struct tty_struct *tty) +static int vs_write_room(struct tty_struct *tty) { - return 16384; + return 8192 * 2; } -static int vs_chars_in_buffer(struct tty_struct *tty) +static int vs_chars_in_buffer(struct tty_struct *tty) { return 0; } #ifdef NO_TTY_DPRAM - -static inline int multipdp_tty_insert_data(struct tty_struct *tty, const u8 *psrc, u16 size) -{ #define CLUSTER_SEGMENT 1550 - u16 copied_size = 0; +static inline int multipdp_tty_insert_data(struct tty_struct *tty, + const u8 *psrc, u16 size) +{ + u16 copied_size = 0, real_copied_size = 0; int retval = 0; - if (size > CLUSTER_SEGMENT){ + if (size > CLUSTER_SEGMENT) { while (size) { - copied_size = (size > CLUSTER_SEGMENT) ? CLUSTER_SEGMENT : size; - tty_insert_flip_string(tty, psrc + retval, copied_size); - - size = size - copied_size; - retval += copied_size; + copied_size = + (size > CLUSTER_SEGMENT) ? CLUSTER_SEGMENT : size; + real_copied_size = + tty_insert_flip_string(tty, psrc + retval, + copied_size); + size = size - real_copied_size; + retval += real_copied_size; } - return retval; } + retval = tty_insert_flip_string(tty, psrc, size); + return retval; +} - return tty_insert_flip_string(tty, psrc, size); +static void cplog_work_func(struct work_struct *work) +{ + struct pdp_info *dev = pdp_get_serdev("ttyCPLOG"); + struct sk_buff *skb; + int ret = 0; + int reschedule = 0; + + if (fp_vsCPLOG > 0) { + while ((skb = skb_dequeue(&cplog_sk_buf_rx_q))) { + ret = multipdp_tty_insert_data(dev->vs_dev.tty, + skb->data, skb->len); + if (ret == 0) { + skb_queue_head(&cplog_sk_buf_rx_q, skb); + reschedule = 1; + pr_err("[MULTIPDP] insert_data_size is ZERO!!\n"); + break; + } else if (ret != skb->len) { + skb_pull(skb, ret); + skb_queue_head(&cplog_sk_buf_rx_q, skb); + tty_flip_buffer_push(dev->vs_dev.tty); + break; + } else { + tty_flip_buffer_push(dev->vs_dev.tty); + dev_kfree_skb_any(skb); + } + } + if (reschedule == 1) + queue_work(cplog_rx_wq, &cplog_work); + } else { + /* Do Something */ + pr_err("[MULTIPDP] RIL didn't open CPLop node (ch.29)\n"); + return; + } } static int multipdp_vs_read(struct pdp_info *dev, char *buf, size_t len) { - int ret = 0; + int ret = -1; + struct sk_buff *skb; if (!dev) { + pr_err("[MULTIPDP] dev is null!\n"); return 0; } #ifndef NO_TTY_RX_BUFF - if(len > 1500) { + if (len > 1500) { #else - if(len > MAX_RX_BUFF_LEN) { + if (len > MAX_RX_BUFF_LEN) { #endif - unsigned char *prx_buf = kzalloc(len, GFP_KERNEL); + unsigned char *prx_buf = kzalloc(len, GFP_ATOMIC); - if(prx_buf == NULL) { + if (prx_buf == NULL) { + pr_err("[MULTIPDP] prx_buf is null!\n"); return 0; } - memcpy(prx_buf, buf, len); - ret = len; + memcpy(prx_buf, buf, len); + ret = len; - if(ret != len) { + if (ret != len) { + pr_err("[MULTIPDP] ret != len!\n"); return ret; } - - if(dev->vs_dev.tty == NULL) { - printk(">>>>> TTY is NULL : (1)~ !!!! \n"); - } - if (ret > 0 && dev->vs_dev.tty != NULL) { - ret = multipdp_tty_insert_data(dev->vs_dev.tty, prx_buf, ret); - if( ret > 0 ) - tty_flip_buffer_push(dev->vs_dev.tty); + if (dev->vs_dev.tty == NULL || (dev->id == 1 && !fp_vsCSD) + || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 + && !fp_vsEFS) + || (dev->id == 25 && !fp_vsSMD) || (dev->id == 6 + && !fp_vsEXGPS) + || (dev->id == 29 && !fp_vsCPLOG) + || (dev->id == 31 && !fp_vsLOOPBACK)) { + pr_err("[MULTIPDP] TTY is NULL : (1)~ !!!!\n"); + return 0; } - printk("RF cal data read.(1) len: %d ret: %d\n", len, ret); + if (dev->vs_dev.refcount == 0) + pr_err("[MULTIPDP] REFCOUNT is NULL : (1B)~ !!!!\n"); + + if (ret > 0 && dev->vs_dev.tty != NULL + && dev->vs_dev.refcount) { + if (dev->id == 29) { + skb = alloc_skb(len, GFP_ATOMIC); + if (unlikely(!skb)) + pr_err("[MULTIPDP] sk_buff alloc failed!\n"); + + memcpy(skb_put(skb, len), prx_buf, len); + skb_queue_tail(&cplog_sk_buf_rx_q, skb); + queue_work(cplog_rx_wq, &cplog_work); + } else { + ret = multipdp_tty_insert_data( + dev->vs_dev.tty, prx_buf, ret); + if (ret > 0) { + dev->vs_dev.tty->low_latency = 0; + tty_flip_buffer_push(dev->vs_dev.tty); + } + } + } kfree(prx_buf); } else { /* pdp data length.. */ - memcpy(pdp_rx_buf, buf, len); - ret = len; + memcpy(pdp_rx_buf, buf, len); + + ret = len; if (ret != len) { + pr_err("[MULTIPDP] ret != len!\n"); return ret; } - #ifdef LOOP_BACK_TEST if (dev->id == LOOP_BACK_CHANNEL) { - if (loopback_ongoing) { - if (strncmp(pdp_rx_buf, loopback_data, loopback_res.nPacketDataSize)){ - //printk("receive packet is not identical to that sent\n"); + if (strncmp(pdp_rx_buf, + loopback_data, + loopback_res. + nPacketDataSize)) { + /* DO SOMETHING */ } else { - send_loop_back_packet(loopback_data, loopback_res.nPacketDataSize); + send_loop_back_packet( + loopback_data, + loopback_res. + nPacketDataSize); } + } else { + /* DO SOMETHING */ } - } - else if (ret > 0 && dev->vs_dev.tty != NULL) { - tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, ret); + } else if (ret > 0 && dev->vs_dev.tty != NULL) { + tty_insert_flip_string( + dev->vs_dev.tty, + pdp_rx_buf, ret); + dev->vs_dev.tty->low_latency = 0; tty_flip_buffer_push(dev->vs_dev.tty); } #else - if(dev->vs_dev.tty == NULL) { - printk(">>>>> TTY is NULL : (2)~ !!!! \n"); - } - - if (ret > 0 && dev->vs_dev.tty != NULL) { - -#if 1 - ret = multipdp_tty_insert_data(dev->vs_dev.tty, pdp_rx_buf, ret); -#else - ret = tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, ret); -#endif - - if( ret > 0 ) { - tty_flip_buffer_push(dev->vs_dev.tty); + if (dev->vs_dev.tty == NULL) + pr_err("[MULTIPDP] TTY is NULL : (2)~ !!!!\n"); + + if (dev->vs_dev.refcount == 0) + pr_err("[MULTIPDP] REFCOUNT is NULL : (2B)~ !!!!\n"); + + if (ret > 0 && dev->vs_dev.tty != NULL + && dev->vs_dev.refcount) { + if (dev->id == 29) { + skb = alloc_skb(len, GFP_ATOMIC); + + if (unlikely(!skb)) + pr_err("[MULTIPDP] Allocation sk_buff error!\n"); + + memcpy(skb_put(skb, len), pdp_rx_buf, len); + skb_queue_tail(&cplog_sk_buf_rx_q, skb); + queue_work(cplog_rx_wq, &cplog_work); + } else { + ret = multipdp_tty_insert_data( + dev->vs_dev.tty, + pdp_rx_buf, ret); + if (ret > 0) { + dev->vs_dev.tty->low_latency = 0; + tty_flip_buffer_push(dev->vs_dev.tty); + } } } -#endif +#endif } - return ret; } - #endif static int vs_read(struct pdp_info *dev, size_t len) @@ -1236,74 +1333,111 @@ static int vs_read(struct pdp_info *dev, size_t len) if (len > MAX_PDP_DATA_LEN) { - DPRINTK(1, "CAL DATA\n"); - size = dpram_read(dpram_filp, prx_buf, len); - DPRINTK(1, "multipdp_thread request read size : %d readed size %d, count : %d\n",len ,size,count); + DPRINTK(2, "CAL DATA\n"); + size = dpram_read(dpram_filp, prx_buf, len); + DPRINTK(2, + "multipdp_thread request read size : %d readed size %d, count : %d\n", + len, size, count); + + if ((dev->id == 1 && !fp_vsCSD) + || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 + && !fp_vsEFS) + || (dev->id == 25 && !fp_vsSMD) + || (dev->id == 6 && !fp_vsEXGPS) || (dev->id == 29 + && !fp_vsCPLOG) + || (dev->id == 31 && !fp_vsLOOPBACK)) { + pr_err("[MULTIPDP] %s, discard data.\n", + dev->vs_dev.tty->name); + } else { + while (size) { + copied_size = (size > + MAX_PDP_DATA_LEN) ? + MAX_PDP_DATA_LEN : size; + + if (size > 0 + && dev->vs_dev.tty != NULL) { + insert_size = + tty_insert_flip_string + (dev->vs_dev.tty, + prx_buf + retval, + copied_size); + } + + if (insert_size != copied_size) { + pr_err("[MULTIPDP] flip buffer full : %s," + "insert size : %d," + "real size : %d\n", + dev->vs_dev. + tty->name, + copied_size, + insert_size); + return -ERANGE; + } + size = size - copied_size; + retval += copied_size; + } -#ifdef CONFIG_ENABLE_TTY_CIQ - if ((dev->id == 26 && !fp_vsCIQ0) ||(dev->id == 9 && !fp_vsCIQ1)||(dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)){ -#else - if ((dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)) { -#endif - EPRINTK("vs_read : %s, discard data.\n", dev->vs_dev.tty->name); - } else { - while (size) { - copied_size = (size > MAX_PDP_DATA_LEN) ? MAX_PDP_DATA_LEN : size; - if (size > 0 && dev->vs_dev.tty != NULL) - insert_size = tty_insert_flip_string(dev->vs_dev.tty, prx_buf+retval, copied_size); - if (insert_size != copied_size) { - EPRINTK("flip buffer full : %s, insert size : %d, real size : %d\n",dev->vs_dev.tty->name,copied_size,insert_size); - return -1; - } - size = size - copied_size; - retval += copied_size; - } - DPRINTK(1, "retval : %d\n",retval); - tty_flip_buffer_push(dev->vs_dev.tty); - count++; - } + DPRINTK(2, "retval : %d\n", retval); + tty_flip_buffer_push(dev->vs_dev.tty); + count++; + } } else { retval = dpram_read(dpram_filp, pdp_rx_buf, len); - if (retval != len) { + if (retval != len) return retval; - } - if(retval > 0) { -#ifdef CONFIG_ENABLE_TTY_CIQ - if((dev->id == 26 && !fp_vsCIQ0) ||(dev->id == 9 && !fp_vsCIQ1) ||( dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)) { -#else - if((dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)) { -#endif - EPRINTK("vs_read : %s, discard data.\n", dev->vs_dev.tty->name); - } else { - insert_size = tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, retval); - if (insert_size != retval) { - EPRINTK("flip buffer full : %s, insert size : %d, real size : %d\n",dev->vs_dev.tty->name,retval,insert_size); - return -1; - } - tty_flip_buffer_push(dev->vs_dev.tty); - } - } + if (retval > 0) { + if ((dev->id == 1 && !fp_vsCSD) + || (dev->id == 5 && !fp_vsGPS) + || (dev->id == 8 && !fp_vsEFS) + || (dev->id == 25 && !fp_vsSMD) + || (dev->id == 6 && !fp_vsEXGPS) + || (dev->id == 29 && !fp_vsCPLOG) + || (dev->id == 31 && !fp_vsLOOPBACK)) { + pr_err("[MULTIPDP] %s, discard data.\n", + dev->vs_dev.tty->name); + } else { + insert_size = + tty_insert_flip_string(dev-> + vs_dev.tty, + pdp_rx_buf, + retval); + + if (insert_size != retval) { + pr_err("[MULTIPDP] flip buffer full : %s," + "insert size : %d," + "real size : %d\n", + dev->vs_dev. + tty->name, + retval, + insert_size); + return -ERANGE; + } + + tty_flip_buffer_push(dev->vs_dev.tty); + } + } } } return 0; } -static int vs_ioctl(struct tty_struct *tty, unsigned int cmd, - unsigned long arg) + +static int vs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, + unsigned long arg) { return -ENOIOCTLCMD; } static struct tty_operations multipdp_tty_ops = { - .open = vs_open, - .close = vs_close, - .write = vs_write, + .open = vs_open, + .close = vs_close, + .write = vs_write, .write_room = vs_write_room, - .ioctl = vs_ioctl, + .ioctl = vs_ioctl, .chars_in_buffer = vs_chars_in_buffer, - + /* TODO: add more operations */ }; static int vs_add_dev(struct pdp_info *dev) @@ -1314,17 +1448,21 @@ static int vs_add_dev(struct pdp_info *dev) kref_init(&tty_driver->kref); - 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->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->minor_start = get_minor_start_index(dev->id); - 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->ttys = dev->vs_dev.tty_table; // 2.6 kernel porting - tty_driver->termios = dev->vs_dev.termios; + 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; + */ + /* 2.6 kernel porting */ + tty_driver->ttys = dev->vs_dev.tty_table; + tty_driver->termios = dev->vs_dev.termios; tty_set_operations(tty_driver, &multipdp_tty_ops); return tty_register_driver(tty_driver); @@ -1335,6 +1473,8 @@ static void vs_del_dev(struct pdp_info *dev) struct tty_driver *tty_driver = NULL; tty_driver = get_tty_driver_by_id(dev); + DPRINTK(2, "%s serial device removed id[%u]\n", + tty_driver->name, dev->id); tty_unregister_driver(tty_driver); return; } @@ -1343,19 +1483,18 @@ static void vs_del_dev(struct pdp_info *dev) * PDP context and mux/demux functions */ -static inline struct pdp_info * pdp_get_dev(u8 id) +static inline struct pdp_info *pdp_get_dev(u8 id) { int slot; for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { - if (pdp_table[slot] && pdp_table[slot]->id == id) { + 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) +static inline struct pdp_info *pdp_get_serdev(const char *name) { int slot; struct pdp_info *dev; @@ -1363,9 +1502,10 @@ static inline struct pdp_info * pdp_get_serdev(const char *name) 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) { + strncmp(name, + dev->vs_dev.tty_name, + APP_NAME_MAX_LEN) == 0) return dev; - } } return NULL; } @@ -1374,9 +1514,8 @@ static inline int pdp_add_dev(struct pdp_info *dev) { int slot; - if (pdp_get_dev(dev->id)) { + if (pdp_get_dev(dev->id)) return -EBUSY; - } for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { if (pdp_table[slot] == NULL) { @@ -1387,7 +1526,7 @@ static inline int pdp_add_dev(struct pdp_info *dev) return -ENOSPC; } -static inline struct pdp_info * pdp_remove_dev(u8 id) +static inline struct pdp_info *pdp_remove_dev(u8 id) { int slot; struct pdp_info *dev; @@ -1402,7 +1541,7 @@ static inline struct pdp_info * pdp_remove_dev(u8 id) return NULL; } -static inline struct pdp_info * pdp_remove_slot(int slot) +static inline struct pdp_info *pdp_remove_slot(int slot) { struct pdp_info *dev; @@ -1411,11 +1550,7 @@ static inline struct pdp_info * pdp_remove_slot(int slot) return dev; } -#ifdef NO_TTY_DPRAM -extern int multipdp_write( char *, int) ; -#endif - -static int pdp_mux(struct pdp_info *dev, const void *data, size_t len ) +static int pdp_mux(struct pdp_info *dev, const void *data, size_t len) { int ret; size_t nbytes; @@ -1423,10 +1558,10 @@ static int pdp_mux(struct pdp_info *dev, const void *data, size_t len ) struct pdp_hdr *hdr; const u8 *buf; - if(pdp_tx_flag){ - if (dev->type == DEV_TYPE_NET) - return -EAGAIN; - } + if (pdp_tx_flag) { + if (dev->type == DEV_TYPE_NET) + return -EAGAIN; + } tx_buf = dev->tx_buf; hdr = (struct pdp_hdr *)(tx_buf + 1); @@ -1436,29 +1571,25 @@ static int pdp_mux(struct pdp_info *dev, const void *data, size_t len ) hdr->control = 0; while (len) { - if (len > MAX_PDP_DATA_LEN) { + if (len > MAX_PDP_DATA_LEN) nbytes = MAX_PDP_DATA_LEN; - } else { - nbytes = len; - } - hdr->len = nbytes + sizeof(struct pdp_hdr); + else + nbytes = len; + hdr->len = nbytes + sizeof(struct pdp_hdr); tx_buf[0] = 0x7f; - - memcpy(tx_buf + 1 + sizeof(struct pdp_hdr), buf, nbytes); - + 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); - wake_lock_timeout(&pdp_wake_lock, pdp_wake_time); #ifdef NO_TTY_DPRAM - ret = multipdp_write(tx_buf, hdr->len +2); - if( ret <= 0 ) - printk("pdp_mux:multipdp_write : len = %d\n", hdr->len+2); + ret = multipdp_write(tx_buf, hdr->len + 2); + if (ret <= 0) + pr_err("[MULTIPDP] multipdp_write len=%d, ret=%d\n", + hdr->len + 2, ret); #endif if (ret < 0) { - DPRINTK(1, "dpram_write() failed: %d\n", ret); + pr_err("[MULTIPDP] dpram_write() failed: %d\n", ret); return ret; } buf += nbytes; @@ -1467,81 +1598,84 @@ static int pdp_mux(struct pdp_info *dev, const void *data, size_t len ) return 0; } + #ifdef NO_TTY_DPRAM -extern int multipdp_dump(void); -extern void yhexdump(const char *buf, int len); static int multipdp_demux(char *buf, int size) { - int ret; u8 ch; size_t len; struct pdp_info *dev = NULL; struct pdp_hdr hdr; - - memcpy( (void *)&hdr, (void *)buf, sizeof( struct pdp_hdr)); + /* + mutex_lock(&pdp_lock); + */ + memcpy((void *)&hdr, (void *)buf, sizeof(struct pdp_hdr)); len = hdr.len - sizeof(struct pdp_hdr); - dev = pdp_get_dev(hdr.id); if (dev == NULL) { - printk("========================================= : (1)\n"); - yhexdump((char*)&hdr, sizeof(struct pdp_hdr)); - printk("========================================= : (2)\n"); - yhexdump((char*)buf, size); - printk("========================================= : (3)\n"); - EPRINTK("invalid id: %u, there is no existing device.\n", hdr.id); + pr_err("[MULTIPDP] invalid id: %u, no existing device.\n", + hdr.id); + yhexdump((char *)&hdr, sizeof(struct pdp_hdr)); multipdp_dump(); ret = -ENODEV; goto err; } - if( buf[-1] != 0x7F) { - printk("============ multipdp_demux : ******** not 0x7F \n"); - } - - if( len > size ) { - printk("============== multipdp_demux : len>size : len=%d, size=%d\n", size, len); - } + if (buf[-1] != 0x7F) + pr_err("[MULTIPDP] Start byte is not 0x7F\n"); + + if (len > size) + pr_err("[MULTIPDP] len>size : len=%d, size=%d\n", size, len); /* read data */ switch (dev->type) { - case DEV_TYPE_NET: - if( len > 1500 ) { - printk("-------------> len is [%d]\n", len); - multipdp_dump(); - } - ret = multipdp_vnet_recv(dev, (char *)&buf[sizeof(struct pdp_hdr)], len); - break; - case DEV_TYPE_SERIAL: - ret = multipdp_vs_read(dev, (char *)&buf[sizeof(struct pdp_hdr)], len); - break; - default: - printk("-------------> type invalid [%d]\n", dev->type); + case DEV_TYPE_NET: + if (len > 1500) { + pr_err("[MULTIPDP] TYPE_NET len is [%d]\n", len); multipdp_dump(); - ret = -1; + } + ret = multipdp_vnet_recv(dev, + (char *)&buf[sizeof(struct pdp_hdr)], + len); + break; + case DEV_TYPE_SERIAL: + ret = multipdp_vs_read(dev, + (char *)&buf[sizeof(struct pdp_hdr)], + len); + break; + default: + pr_err("[MULTIPDP] Type invalid [%d]\n", dev->type); + multipdp_dump(); + ret = -1; } - if (ret < 0) { + if (ret < 0) goto err; - } + /* check stop byte */ ch = buf[hdr.len]; - if ( ch != 0x7e) { - printk(" *******Not 0x7E ... !!!!\n"); + if (ch != 0x7e) { + pr_err("[MULTIPDP] End byte is Not 0x7E ... !!!!\n"); + /* + mutex_unlock(&pdp_lock); + */ return ret; } - return ret; - -err: + return ret; + + err: /* flush the remaining data including stop byte. */ + /* + mutex_unlock(&pdp_lock); + */ return ret; } - #endif static int pdp_demux(void) @@ -1555,9 +1689,8 @@ static int pdp_demux(void) /* read header */ ret = dpram_read(dpram_filp, &hdr, sizeof(hdr)); - if (ret < 0) { + if (ret < 0) return ret; - } len = hdr.len - sizeof(struct pdp_hdr); @@ -1566,37 +1699,37 @@ static int pdp_demux(void) dev = pdp_get_dev(hdr.id); if (dev == NULL) { - printk("invalid id: %u, there is no existing device.\n", hdr.id); + pr_err("[MULTIPDP] invalid id: %u, no existing device.\n", + hdr.id); ret = -ENODEV; goto err; } /* read data */ switch (dev->type) { - case DEV_TYPE_NET: - ret = vnet_recv(dev, len); - break; - case DEV_TYPE_SERIAL: - ret = vs_read(dev, len); - break; - default: - ret = -1; + case DEV_TYPE_NET: + ret = vnet_recv(dev, len); + break; + case DEV_TYPE_SERIAL: + ret = vs_read(dev, len); + break; + default: + ret = -1; } - if (ret < 0) { + if (ret < 0) goto err; - } + up(&pdp_lock); /* check stop byte */ ret = dpram_read(dpram_filp, &ch, sizeof(ch)); - if (ret < 0 || ch != 0x7e) { + if (ret < 0 || ch != 0x7e) return ret; - } return 0; -err: + err: up(&pdp_lock); /* flush the remaining data including stop byte. */ @@ -1604,7 +1737,7 @@ static int pdp_demux(void) return ret; } -static int pdp_activate(pdp_arg_t *pdp_arg, unsigned type, unsigned flags) +static int pdp_activate(struct pdp_arg *pdp_arg, unsigned type, unsigned flags) { int ret; struct pdp_info *dev; @@ -1612,37 +1745,40 @@ static int pdp_activate(pdp_arg_t *pdp_arg, unsigned type, unsigned flags) dev = vmalloc(sizeof(struct pdp_info) + MAX_PDP_PACKET_LEN); if (dev == NULL) { - DPRINTK(1, "out of memory\n"); + pr_err("[MULTIPDP] out of memory\n"); return -ENOMEM; } memset(dev, 0, sizeof(struct pdp_info)); /* @LDK@ added by gykim on 20070203 for adjusting IPC 3.0 spec. */ - if (type == DEV_TYPE_NET) { + if (type == DEV_TYPE_NET) dev->id = pdp_arg->id + g_adjust; - } else { - dev->id = pdp_arg->id; - } - /* @LDK@ added by gykim on 20070203 for adjusting IPC 3.0 spec. */ + else + dev->id = pdp_arg->id; + /* @LDK@ added by gykim on 20070203 for adjusting IPC 3.0 spec. */ dev->type = type; dev->flags = flags; - dev->tx_buf = (u8 *)(dev + 1); + dev->tx_buf = (u8 *) (dev + 1); if (type == DEV_TYPE_NET) { net = vnet_add_dev((void *)dev); if (net == NULL) { + pr_err("[MULTIPDP] vnet_add_dev is failed"); vfree(dev); return -ENOMEM; } dev->vn_dev.net = net; - strcpy(pdp_arg->ifname, net->name); + + strncpy(pdp_arg->ifname, + net->name, + APP_NAME_MAX_LEN); down(&pdp_lock); ret = pdp_add_dev(dev); if (ret < 0) { - EPRINTK("pdp_add_dev() failed\n"); + pr_err("[MULTIPDP] pdp_add_dev() failed\n"); up(&pdp_lock); vnet_del_dev(dev->vn_dev.net); vfree(dev); @@ -1651,11 +1787,14 @@ static int pdp_activate(pdp_arg_t *pdp_arg, unsigned type, unsigned flags) pdp_net_activation_count++; up(&pdp_lock); - DPRINTK(1, "%s(id: %u) network device created\n", + DPRINTK(2, "%s(id: %u) network device created\n", net->name, dev->id); } else if (type == DEV_TYPE_SERIAL) { sema_init(&dev->vs_dev.write_lock, 1); - strcpy(dev->vs_dev.tty_name, pdp_arg->ifname); + + strncpy(dev->vs_dev.tty_name, + pdp_arg->ifname, + APP_NAME_MAX_LEN); ret = vs_add_dev(dev); if (ret < 0) { @@ -1666,53 +1805,37 @@ static int pdp_activate(pdp_arg_t *pdp_arg, unsigned type, unsigned flags) down(&pdp_lock); ret = pdp_add_dev(dev); if (ret < 0) { - DPRINTK(1, "pdp_add_dev() failed\n"); + pr_err("[MULTIPDP] pdp_add_dev() failed\n"); up(&pdp_lock); vs_del_dev(dev); vfree(dev); return ret; } up(&pdp_lock); - - { - struct tty_driver * tty_driver = get_tty_driver_by_id(dev); - - DPRINTK(1, "%s(id: %u) serial device is created.\n", - tty_driver->name, dev->id); - } + DPRINTK(2, "serial device is created id[%u]\n", + dev->id); } return 0; } -static int pdp_deactivate(pdp_arg_t *pdp_arg, int force) +static int pdp_deactivate(struct pdp_arg *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); + DPRINTK(2, "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); + pr_err("[MULTIPDP] 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); + pr_err("[MULTIPDP] sticky id: %u\n", pdp_arg->id); up(&pdp_lock); return -EACCES; } @@ -1722,22 +1845,16 @@ static int pdp_deactivate(pdp_arg_t *pdp_arg, int force) if (dev->type == DEV_TYPE_NET) { #ifdef NO_TTY_MUTEX_VNET - vnet_stop(dev->vn_dev.net); + vnet_stop(dev->vn_dev.net); down(&pdp_txlock); pdp_net_activation_count--; #endif - DPRINTK(1, "%s(id: %u) network device removed\n", - dev->vn_dev.net->name, dev->id); vnet_del_dev(dev->vn_dev.net); #ifdef NO_TTY_MUTEX_VNET up(&pdp_txlock); #endif } else if (dev->type == DEV_TYPE_SERIAL) { - struct tty_driver * tty_driver = get_tty_driver_by_id(dev); - - DPRINTK(1, "%s(id: %u) serial device removed\n", - tty_driver->name, dev->id); vs_del_dev(dev); } @@ -1754,18 +1871,12 @@ static void __exit pdp_cleanup(void) 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); + if (dev->type == DEV_TYPE_NET) vnet_del_dev(dev->vn_dev.net); - } else if (dev->type == DEV_TYPE_SERIAL) { - struct tty_driver * tty_driver = get_tty_driver_by_id(dev); - - DPRINTK(1, "%s(id: %u) serial device removed\n", - tty_driver->name, dev->id); - + else if (dev->type == DEV_TYPE_SERIAL) vs_del_dev(dev); - } + else + pr_err("[MULTIPDP] Invalid device type\n"); vfree(dev); } @@ -1776,29 +1887,28 @@ static void __exit pdp_cleanup(void) static int pdp_adjust(const int adjust) { g_adjust = adjust; - printk("adjusting value: %d\n", adjust); + DPRINTK(2, "adjusting value: %d\n", adjust); return 0; } -/* - * App. Interfece Device functions - */ +/* App. Interfece Device functions */ /* have to use kernel 2.6.38 or later */ static long multipdp_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { int ret, adjust; - pdp_arg_t pdp_arg; + struct pdp_arg 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) { + + if (ret < 0) return ret; - } + return copy_to_user((void *)arg, &pdp_arg, sizeof(pdp_arg)); case HN_PDP_DEACTIVATE: @@ -1807,7 +1917,7 @@ static long multipdp_ioctl(struct file *file, unsigned int cmd, return pdp_deactivate(&pdp_arg, 0); case HN_PDP_ADJUST: - if (copy_from_user(&adjust, (void *)arg, sizeof (int))) + if (copy_from_user(&adjust, (void *)arg, sizeof(int))) return -EFAULT; return pdp_adjust(adjust); @@ -1822,7 +1932,7 @@ static long multipdp_ioctl(struct file *file, unsigned int cmd, case HN_PDP_CSDSTART: pdp_csd_flag = 0; return 0; - + case HN_PDP_CSDSTOP: pdp_csd_flag = 1; return 0; @@ -1839,9 +1949,10 @@ static struct file_operations multipdp_fops = { }; static struct miscdevice multipdp_dev = { - .minor = 132, - .name = APP_DEVNAME, - .fops = &multipdp_fops, + /* MISC_DYNAMIC_MINOR, */ + .minor = 132, + .name = APP_DEVNAME, + .fops = &multipdp_fops, }; /* @@ -1858,18 +1969,19 @@ static int multipdp_proc_read(char *page, char **start, off_t off, down(&pdp_lock); - p += sprintf(p, "modified multipdp driver on 20070205"); + p += sprintf(p, 50, "modified multipdp driver on 20070205"); for (len = 0; len < MAX_PDP_CONTEXT; len++) { struct pdp_info *dev = pdp_table[len]; - if (!dev) continue; + 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); + p += sprintf(p, 128, + "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); @@ -1884,61 +1996,48 @@ static int multipdp_proc_read(char *page, char **start, off_t off, } #endif -#ifdef NO_TTY_DPRAM -extern void multipdp_rx_noti_regi( int (*rx_func)(char *, int) ); -#endif - /* * Module init/clanup functions */ static struct workqueue_struct *multipdp_workq; static struct work_struct dpram_open_work; + static void dpram_open_work_func(struct work_struct *work) { int ret; -#ifdef CONFIG_ENABLE_TTY_CIQ - pdp_arg_t pdp_args[7] = { - { .id = 1, .ifname = "ttyCSD" }, - { .id = 8, .ifname = "ttyEFS" }, - { .id = 5, .ifname = "ttyGPS" }, - { .id = 6, .ifname = "ttyXTRA" }, - { .id = 25, .ifname = "ttySMD" }, - { .id = 9, .ifname = "ttyCIQ1" }, - { .id = 26, .ifname = "ttyCIQ0" }, + struct pdp_arg pdp_args[8] = { + {.id = 1, .ifname = "ttyCSD"}, + {.id = 8, .ifname = "ttyEFS"}, + {.id = 5, .ifname = "ttyGPS"}, + {.id = 6, .ifname = "ttyXTRA"}, + {.id = 7, .ifname = "ttyCDMA"}, + {.id = 25, .ifname = "ttySMD"}, + {.id = 29, .ifname = "ttyCPLOG"}, + {.id = 31, .ifname = "ttyLOOPBACK"}, }; -#else - pdp_arg_t pdp_args[5] = { - { .id = 1, .ifname = "ttyCSD" }, - { .id = 8, .ifname = "ttyEFS" }, - { .id = 5, .ifname = "ttyGPS" }, - { .id = 6, .ifname = "ttyXTRA" }, - { .id = 25, .ifname = "ttySMD" }, - }; -#endif msleep(100); - /* run DPRAM I/O thread */ + /* run DPRAM I/O thread */ ret = kernel_thread(dpram_thread, NULL, CLONE_FS | CLONE_FILES); if (ret < 0) { - EPRINTK("kernel_thread() failed\n"); + pr_err("[MULTIPDP] kernel_thread() failed\n"); return; } wait_for_completion(&dpram_complete); if (!dpram_task) { - EPRINTK("DPRAM I/O thread error\n"); + pr_err("[MULTIPDP] DPRAM I/O thread error\n"); return; } /* create serial device for Circuit Switched Data */ -#ifdef CONFIG_ENABLE_TTY_CIQ - for (ret = 0; ret < 7; ret++) { -#else - for (ret = 0; ret < 5; ret++) { -#endif - if (pdp_activate(&pdp_args[ret], DEV_TYPE_SERIAL, DEV_FLAG_STICKY) < 0) { - EPRINTK("failed to create a serial device for %s\n", pdp_args[ret].ifname); + for (ret = 0; ret < 8; ret++) { + if (pdp_activate(&pdp_args[ret], + DEV_TYPE_SERIAL, + DEV_FLAG_STICKY) < 0) { + pr_err("[MULTIPDP] failed to create a serial device %s\n", + pdp_args[ret].ifname); } } } @@ -1947,7 +2046,8 @@ static int __init multipdp_init(void) { int ret; - DPRINTK(2, "++\n"); + pdp_net_activation_count = 0; + vnet_start_xmit_flag = 0; wake_lock_init(&pdp_wake_lock, WAKE_LOCK_SUSPEND, "MULTI_PDP"); pdp_wake_time = DEFAULT_RAW_WAKE_TIME; @@ -1957,38 +2057,49 @@ static int __init multipdp_init(void) queue_work(multipdp_workq, &dpram_open_work); + skb_queue_head_init(&cplog_sk_buf_rx_q); + INIT_WORK(&cplog_work, cplog_work_func); + cplog_rx_wq = + create_singlethread_workqueue("cplog_work_queue"); + if (cplog_rx_wq == NULL) { + pr_err("[MULTIPDP] create workqueue thread failed\n"); + return -ENOMEM; + } + /* create app. interface device */ ret = misc_register(&multipdp_dev); if (ret < 0) { - EPRINTK("misc_register() failed\n"); + pr_err("[MULTIPDP] misc_register() failed\n"); goto err1; } - #ifdef CONFIG_PROC_FS - create_proc_read_entry(APP_DEVNAME, 0, 0, - multipdp_proc_read, NULL); + create_proc_read_entry(APP_DEVNAME, 0, 0, multipdp_proc_read, NULL); #endif #ifdef NO_TTY_DPRAM - printk("multipdp_init:multipdp_rx_noti_regi calling"); - multipdp_rx_noti_regi(multipdp_rx_cback ); + multipdp_rx_noti_regi(multipdp_rx_cback); #endif /* sys fs - start */ pdp_class = class_create(THIS_MODULE, "pdp"); if (IS_ERR(pdp_class)) - EPRINTK("Failed to create class(pdp)!\n"); + pr_err("[MULTIPDP] Failed to create class(pdp)!\n"); pdp_dev = device_create(pdp_class, NULL, 0, NULL, "pdp"); if (IS_ERR(pdp_dev)) - EPRINTK("Failed to create device(pdp)!\n"); + pr_err("[MULTIPDP] Failed to create device(pdp)!\n"); if (device_create_file(pdp_dev, &dev_attr_waketime) < 0) - EPRINTK("Failed to create device file(%s)!\n", dev_attr_waketime.attr.name); + pr_err("[MULTIPDP] Failed to create device file(%s)!\n", + dev_attr_waketime.attr.name); return 0; -err1: + err1: + /* undo serial device for Circuit Switched Data */ + /* + pdp_deactivate(&pdp_arg, 1); + */ /* kill DPRAM I/O thread */ if (dpram_task) { @@ -2004,7 +2115,7 @@ static void __exit multipdp_exit(void) #ifdef CONFIG_PROC_FS remove_proc_entry(APP_DEVNAME, 0); #endif - vfree(prx_buf); + vfree(prx_buf); /* remove app. interface device */ misc_deregister(&multipdp_dev); @@ -2028,4 +2139,3 @@ module_exit(multipdp_exit); MODULE_AUTHOR("SAMSUNG ELECTRONICS CO., LTD"); MODULE_DESCRIPTION("Multiple PDP Muxer / Demuxer"); MODULE_LICENSE("GPL"); -