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