diff options
| author | Yuval Adam <_@yuv.al> | 2017-08-30 08:25:59 +0000 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2017-08-30 08:25:59 +0000 |
| commit | 8e4bff4cab0ddac6060645b0715210484d02ff40 (patch) | |
| tree | 3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/misc/mdbg | |
Diffstat (limited to 'drivers/misc/mdbg')
| -rw-r--r-- | drivers/misc/mdbg/Kconfig | 24 | ||||
| -rw-r--r-- | drivers/misc/mdbg/Makefile | 9 | ||||
| -rw-r--r-- | drivers/misc/mdbg/mdbg.c | 621 | ||||
| -rw-r--r-- | drivers/misc/mdbg/mdbg.h | 24 | ||||
| -rw-r--r-- | drivers/misc/mdbg/mdbg_ring.c | 234 | ||||
| -rw-r--r-- | drivers/misc/mdbg/mdbg_ring.h | 54 | ||||
| -rw-r--r-- | drivers/misc/mdbg/mdbg_sdio.c | 158 | ||||
| -rw-r--r-- | drivers/misc/mdbg/mdbg_sdio.h | 37 | ||||
| -rw-r--r-- | drivers/misc/mdbg/mdbg_type.h | 65 |
9 files changed, 1226 insertions, 0 deletions
diff --git a/drivers/misc/mdbg/Kconfig b/drivers/misc/mdbg/Kconfig new file mode 100644 index 00000000..8da0c1c4 --- /dev/null +++ b/drivers/misc/mdbg/Kconfig @@ -0,0 +1,24 @@ + +menu "MARLIN DEBUG modules" +config MDBG_SDIO + bool "MDBG SDIO INTERFACE" + default y + help + FOR MDBG SDIO INTERFACE + +config MDBG_RING + bool "MDBG RING BUFFER" + default y + help + FOR MDBG RING BUFFER + +config MDBG + tristate "MDBG" + depends on SDIODEV + depends on MDBG_RING + help + DEBUG SYSTEM FOR MARLIN. + If unsure, say N. + + +endmenu diff --git a/drivers/misc/mdbg/Makefile b/drivers/misc/mdbg/Makefile new file mode 100644 index 00000000..db378e8d --- /dev/null +++ b/drivers/misc/mdbg/Makefile @@ -0,0 +1,9 @@ +#mdbgdrv +obj-$(CONFIG_MDBG) := mdbgdrv.o + +mdbgdrv-c-objs += mdbg_ring.o +mdbgdrv-c-objs += mdbg_sdio.o +mdbgdrv-c-objs += mdbg.o + +mdbgdrv-objs += $(mdbgdrv-c-objs) + diff --git a/drivers/misc/mdbg/mdbg.c b/drivers/misc/mdbg/mdbg.c new file mode 100644 index 00000000..d377e481 --- /dev/null +++ b/drivers/misc/mdbg/mdbg.c @@ -0,0 +1,621 @@ +/************************************************************************************************************ */ +/*****Copyright: 2014 Spreatrum. All Right Reserved */ +/*****File: mdbg.c */ +/*****Description: Marlin Debug System main file. Module,device & driver related defination. */ +/*****Developer: fan.kou@spreadtrum.com */ +/*****Date: 06/01/2014 */ +/************************************************************************************************************ */ + +#include "mdbg.h" +#include "mdbg_sdio.h" +#include <linux/mutex.h> +#include <linux/wait.h> +#include <linux/poll.h> +#include <linux/proc_fs.h> + +#define MDBG_MAX_BUFFER_LEN (PAGE_SIZE) + +#define MDBG_WCN_WRITE (5) +#define MDBG_CHANNEL_ASSERT (13) +#define MDBG_CHANNEL_WDTIRQ (4) +#define MDBG_CHANNEL_LOOPCHECK (15) +#define MDBG_CHANNEL_AT_CMD (11) + +#define MDBG_WRITE_SIZE (64) +#define MDBG_ASSERT_SIZE (1024) +#define MDBG_WDTIRQ_SIZE (128) +#define MDBG_LOOPCHECK_SIZE (128) +#define MDBG_AT_CMD_SIZE (128) + +unsigned int mdbg_read_count = 0; +unsigned int first_boot = 0; + +struct mdbg_devvice_t *mdbg_dev=NULL; +wait_queue_head_t mdbg_wait; + +struct mdbg_proc_entry { + char *name; + struct proc_dir_entry *entry; + struct completion completed; + wait_queue_head_t rxwait; + unsigned int rcv_len; + void *buf; +}; + +struct mdbg_proc_t{ + char *dir_name; + struct proc_dir_entry *procdir; + struct mdbg_proc_entry assert; + struct mdbg_proc_entry wdtirq; + struct mdbg_proc_entry loopcheck; + struct mdbg_proc_entry at_cmd; + char write_buf[MDBG_WRITE_SIZE]; +}; + +static struct mdbg_proc_t *mdbg_proc=NULL; + + +void mdbg_assert_interface(void) +{ + strncpy(mdbg_proc->assert.buf,"wifi channel is blocked",23); + printk(KERN_INFO "mdbg_assert_interface:%s\n",mdbg_proc->assert.buf); + mdbg_proc->assert.rcv_len = 23; + complete(&mdbg_proc->assert.completed); + wake_up_interruptible(&mdbg_proc->assert.rxwait); + + return; +} +EXPORT_SYMBOL_GPL(mdbg_assert_interface); + +void mdbg_assert_read(void) +{ + int read_len; + read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_ASSERT); + if(read_len <= 0){ + return; + } + + if(read_len > MDBG_ASSERT_SIZE) + MDBG_ERR( "The assert data len:%d, beyond max read:%d",read_len,MDBG_ASSERT_SIZE); + + sdio_dev_read(MDBG_CHANNEL_ASSERT,mdbg_proc->assert.buf,&read_len); + printk(KERN_INFO "mdbg_assert_read:%s\n",mdbg_proc->assert.buf); + mdbg_proc->assert.rcv_len = read_len; + complete(&mdbg_proc->assert.completed); + wake_up_interruptible(&mdbg_proc->assert.rxwait); + + return; +} +EXPORT_SYMBOL_GPL(mdbg_assert_read); + +void mdbg_wdtirq_read(void) +{ + int read_len; + read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_WDTIRQ); + if(read_len <= 0){ + return; + } + + if(read_len > MDBG_WDTIRQ_SIZE) + MDBG_ERR( "The assert data len:%d, beyond max read:%d",read_len,MDBG_WDTIRQ_SIZE); + + sdio_dev_read(MDBG_CHANNEL_WDTIRQ,mdbg_proc->wdtirq.buf,&read_len); + printk(KERN_INFO "mdbg_wdtirq_read:%s\n",mdbg_proc->wdtirq.buf); + mdbg_proc->wdtirq.rcv_len = read_len; + complete(&mdbg_proc->wdtirq.completed); + wake_up_interruptible(&mdbg_proc->wdtirq.rxwait); + + return; +} +EXPORT_SYMBOL_GPL(mdbg_wdtirq_read); + +void mdbg_loopcheck_read(void) +{ + int read_len; + + read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_LOOPCHECK); + if(read_len <= 0){ + return; + } + + if(read_len > MDBG_LOOPCHECK_SIZE) + MDBG_ERR( "The loopcheck data len:%d, beyond max read:%d",read_len,MDBG_LOOPCHECK_SIZE); + + sdio_dev_read(MDBG_CHANNEL_LOOPCHECK,mdbg_proc->loopcheck.buf,&read_len); + printk(KERN_INFO "mdbg_loopcheck_read:%s\n",mdbg_proc->loopcheck.buf); + mdbg_proc->loopcheck.rcv_len = read_len; + complete(&mdbg_proc->loopcheck.completed); + + return; +} +EXPORT_SYMBOL_GPL(mdbg_loopcheck_read); + +void mdbg_at_cmd_read(void) +{ + int read_len; + + read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_AT_CMD); + if(read_len <= 0){ + MDBG_ERR("MDBG_CHANNEL_AT_CMD len err\n"); + return; + } + + if(read_len > MDBG_AT_CMD_SIZE) + MDBG_ERR( "The at cmd data len:%d, beyond max read:%d",read_len,MDBG_AT_CMD_SIZE); + + sdio_dev_read(MDBG_CHANNEL_AT_CMD,mdbg_proc->at_cmd.buf,&read_len); + mdbg_proc->at_cmd.rcv_len = read_len; + printk(KERN_INFO "mdbg_at_cmd_read:%s\n",mdbg_proc->at_cmd.buf); + complete(&mdbg_proc->at_cmd.completed); + + return; +} +EXPORT_SYMBOL_GPL(mdbg_at_cmd_read); + +static int mdbg_proc_open(struct inode *inode, struct file *filp) +{ + struct mdbg_proc_entry *entry = (struct mdbg_proc_entry *)PDE_DATA(inode); + char *type = entry->name; + + filp->private_data = entry; + //MDBG_ERR("%s type:%s\n",__func__,type); + + return 0; +} + +static int mdbg_proc_release(struct inode *inode, struct file *filp) +{ + struct mdbg_proc_entry *entry = (struct mdbg_proc_entry *)PDE_DATA(inode); + char *type = entry->name; + + //MDBG_ERR("%s type:%s\n",__func__,type); + + return 0; +} + +static ssize_t mdbg_proc_read(struct file *filp, + char __user *buf, size_t count, loff_t *ppos) +{ + struct mdbg_proc_entry *entry = (struct mdbg_proc_entry *)filp->private_data; + char *type = entry->name; + int timeout = -1; + int len = 0; + int ret; + + //printk(KERN_INFO "type:%s\n",type); + if (filp->f_flags & O_NONBLOCK) { + timeout = 0; + } + + if(strcmp(type, "assert") == 0) { + if (timeout < 0){ + while(1){ + ret = wait_for_completion_timeout(&mdbg_proc->assert.completed,msecs_to_jiffies(1000)); + if (ret != -ERESTARTSYS) + break; + } + } + + if(copy_to_user((void __user *)buf, mdbg_proc->assert.buf, min(count,(size_t)MDBG_ASSERT_SIZE))){ + MDBG_ERR( "Read assert info error\n"); + } + len = mdbg_proc->assert.rcv_len; + mdbg_proc->assert.rcv_len = 0; + memset(mdbg_proc->assert.buf,0,MDBG_ASSERT_SIZE); + } + + if(strcmp(type, "wdtirq") == 0) { + if (timeout < 0){ + while(1){ + ret = wait_for_completion_timeout(&mdbg_proc->wdtirq.completed,msecs_to_jiffies(1000)); + if (ret != -ERESTARTSYS) + break; + } + } + + if(copy_to_user((void __user *)buf, mdbg_proc->wdtirq.buf, min(count,(size_t)MDBG_WDTIRQ_SIZE))){ + MDBG_ERR( "Read wdtirq info error\n"); + } + + len = mdbg_proc->wdtirq.rcv_len; + mdbg_proc->wdtirq.rcv_len = 0; + memset(mdbg_proc->wdtirq.buf,0,MDBG_WDTIRQ_SIZE); + } + + if(strcmp(type, "loopcheck") == 0) { + if (timeout < 0){ + while(1){ + ret = wait_for_completion_timeout(&mdbg_proc->loopcheck.completed,msecs_to_jiffies(1000)); + if (ret != -ERESTARTSYS) + break; + } + } + + if(first_boot < 2){ + if(copy_to_user((void __user *)buf, "loopcheck_ack", 13)){ + MDBG_ERR("Read loopcheck first info error\n"); + } + first_boot++; + len = 13; + }else if(get_sprd_marlin_status()){ + if(copy_to_user((void __user *)buf, "loopcheck_ack", 13)){ + MDBG_ERR("loopcheck gpio info error\n"); + } + len = 13; + }else{ + if(copy_to_user((void __user *)buf, mdbg_proc->loopcheck.buf, min(count,(size_t)MDBG_LOOPCHECK_SIZE))){ + MDBG_ERR("Read loopcheck sdio info error\n"); + } + len = mdbg_proc->loopcheck.rcv_len; + } + memset(mdbg_proc->loopcheck.buf,0,MDBG_LOOPCHECK_SIZE); + mdbg_proc->loopcheck.rcv_len = 0; + } + + if(strcmp(type, "at_cmd") == 0) { + if (timeout < 0){ + while(1){ + ret = wait_for_completion_timeout(&mdbg_proc->at_cmd.completed,msecs_to_jiffies(1000)); + if (ret != -ERESTARTSYS) + break; + } + } + + if(copy_to_user((void __user *)buf, mdbg_proc->at_cmd.buf, min(count,(size_t)MDBG_AT_CMD_SIZE))){ + MDBG_ERR("Read at cmd ack info error\n"); + } + + len = mdbg_proc->at_cmd.rcv_len; + mdbg_proc->at_cmd.rcv_len = 0; + memset(mdbg_proc->at_cmd.buf,0,MDBG_AT_CMD_SIZE); + } + + return len; +} + +static ssize_t mdbg_proc_write(struct file *filp, + const char __user *buf, size_t count, loff_t *ppos) +{ + int cnt = 0; + if(count > MDBG_WRITE_SIZE){ + MDBG_ERR( "mdbg_proc_write count > MDBG_WRITE_SIZE\n"); + return -ENOMEM; + } + memset(mdbg_proc->write_buf,0,MDBG_WRITE_SIZE); + + if (copy_from_user(mdbg_proc->write_buf,buf,count )){ + return -EFAULT; + } + + printk(KERN_INFO "mdbg_proc->write_buf:%s\n",mdbg_proc->write_buf); + + if(strncmp(mdbg_proc->write_buf,"startwcn",8) == 0){ + first_boot = 0; + return count; + } + + if(strncmp(mdbg_proc->write_buf,"dumpwcn",7) == 0){ + mdbg_channel_init(); + return count; + } + + if(strncmp(mdbg_proc->write_buf,"at+loopcheck",12) == 0){ + printk(KERN_INFO "mdbg start wake marlin\n"); + while((set_marlin_wakeup(MDBG_CHANNEL_WRITE,0x3) < 0) && (cnt <= 3)) + { + msleep(300); + cnt++; + } + cnt = 0; + } + else{ + mdbg_send(mdbg_proc->write_buf , count, MDBG_WCN_WRITE); + } + + return count; +} + +static unsigned int mdbg_proc_poll(struct file *filp, poll_table *wait) +{ + struct mdbg_proc_entry *entry = (struct mdbg_proc_entry *)filp->private_data; + char *type = entry->name; + unsigned int mask = 0; + //printk(KERN_INFO "%s type:%s\n",__func__,type); + + if(strcmp(type, "assert") == 0) + { + poll_wait(filp, &mdbg_proc->assert.rxwait, wait); + if(mdbg_proc->assert.rcv_len > 0) + mask |= POLLIN | POLLRDNORM; + } + + if(strcmp(type, "wdtirq") == 0) + { + poll_wait(filp, &mdbg_proc->wdtirq.rxwait, wait); + if(mdbg_proc->wdtirq.rcv_len > 0) + mask |= POLLIN | POLLRDNORM; + } + + return mask; +} + +struct file_operations mdbg_proc_fops = { + .open = mdbg_proc_open, + .release = mdbg_proc_release, + .read = mdbg_proc_read, + .write = mdbg_proc_write, + .poll = mdbg_proc_poll, +}; + +LOCAL void mdbg_fs_channel_init(void) +{ + int retval=0; + + mdbg_proc->assert.buf = kzalloc(MDBG_ASSERT_SIZE, GFP_KERNEL); + retval = sdiodev_readchn_init(MDBG_CHANNEL_ASSERT, mdbg_assert_read,0); + + mdbg_proc->wdtirq.buf = kzalloc(MDBG_WDTIRQ_SIZE, GFP_KERNEL); + retval = sdiodev_readchn_init(MDBG_CHANNEL_WDTIRQ, mdbg_wdtirq_read,0); + + mdbg_proc->loopcheck.buf = kzalloc(MDBG_LOOPCHECK_SIZE, GFP_KERNEL); + retval = sdiodev_readchn_init(MDBG_CHANNEL_LOOPCHECK, mdbg_loopcheck_read,0); + + mdbg_proc->at_cmd.buf = kzalloc(MDBG_AT_CMD_SIZE, GFP_KERNEL); + retval = sdiodev_readchn_init(MDBG_CHANNEL_AT_CMD, mdbg_at_cmd_read,0); +} + +LOCAL void mdbg_fs_channel_uninit(void) +{ + sdiodev_readchn_uninit(MDBG_CHANNEL_ASSERT); + kfree(mdbg_proc->assert.buf); + mdbg_proc->assert.buf= NULL; + + sdiodev_readchn_uninit(MDBG_CHANNEL_WDTIRQ); + kfree(mdbg_proc->wdtirq.buf); + mdbg_proc->wdtirq.buf= NULL; + + sdiodev_readchn_uninit(MDBG_CHANNEL_LOOPCHECK); + kfree(mdbg_proc->loopcheck.buf); + mdbg_proc->loopcheck.buf= NULL; + + sdiodev_readchn_uninit(MDBG_CHANNEL_AT_CMD); + kfree(mdbg_proc->at_cmd.buf); + mdbg_proc->at_cmd.buf= NULL; +} + + +LOCAL void mdbg_fs_init(void) +{ + mdbg_proc = kzalloc(sizeof(struct mdbg_proc_t), GFP_KERNEL); + if (!mdbg_proc) + return; + + mdbg_proc->dir_name = "mdbg"; + mdbg_proc->procdir = proc_mkdir(mdbg_proc->dir_name, NULL); + + mdbg_proc->assert.name = "assert"; + mdbg_proc->assert.entry = proc_create_data(mdbg_proc->assert.name, S_IRUSR |S_IWUSR, + mdbg_proc->procdir, &mdbg_proc_fops, &(mdbg_proc->assert)); + + mdbg_proc->wdtirq.name = "wdtirq"; + mdbg_proc->wdtirq.entry = proc_create_data(mdbg_proc->wdtirq.name, S_IRUSR | S_IWUSR, + mdbg_proc->procdir, &mdbg_proc_fops, &(mdbg_proc->wdtirq)); + + mdbg_proc->loopcheck.name = "loopcheck"; + mdbg_proc->loopcheck.entry = proc_create_data(mdbg_proc->loopcheck.name, S_IRUSR | S_IWUSR, + mdbg_proc->procdir, &mdbg_proc_fops, &(mdbg_proc->loopcheck)); + + mdbg_proc->at_cmd.name = "at_cmd"; + mdbg_proc->at_cmd.entry = proc_create_data(mdbg_proc->at_cmd.name, S_IRUSR | S_IWUSR, + mdbg_proc->procdir, &mdbg_proc_fops, &(mdbg_proc->at_cmd)); + + mdbg_fs_channel_init(); + + init_completion(&mdbg_proc->assert.completed); + init_completion(&mdbg_proc->wdtirq.completed); + init_completion(&mdbg_proc->loopcheck.completed); + init_completion(&mdbg_proc->at_cmd.completed); + init_waitqueue_head(&mdbg_proc->assert.rxwait); + init_waitqueue_head(&mdbg_proc->wdtirq.rxwait); + init_waitqueue_head(&mdbg_dev->rxwait); +} + +LOCAL void mdbg_fs_init_exit(void) +{ + mdbg_fs_channel_uninit(); + + remove_proc_entry(mdbg_proc->assert.name , mdbg_proc->procdir); + remove_proc_entry(mdbg_proc->wdtirq.name , mdbg_proc->procdir); + remove_proc_entry(mdbg_proc->loopcheck.name , mdbg_proc->procdir); + remove_proc_entry(mdbg_proc->at_cmd.name , mdbg_proc->procdir); + remove_proc_entry(mdbg_proc->dir_name, NULL); + + kfree(mdbg_proc); + mdbg_proc=NULL; +} + + +LOCAL ssize_t mdbg_read(struct file *filp,char __user *buf,size_t count,loff_t *pos) +{ + MDBG_SIZE_T read_size;; + int timeout = -1; + int rval; + + if (filp->f_flags & O_NONBLOCK) { + timeout = 0; + } + + if(count > MDBG_MAX_BUFFER_LEN) + count = MDBG_MAX_BUFFER_LEN; + + if (timeout < 0){ + /* wait forever */ + rval = wait_event_interruptible(mdbg_wait,mdbg_read_count > 0); + if (rval < 0){ + MDBG_ERR("mdbg_read wait interrupted!\n"); + } + }else{ + //MDBG_ERR("mdbg_read no blok\n"); + } + + mutex_lock(&mdbg_dev->mdbg_lock); + + if(mdbg_read_count <= 0){ + mutex_unlock(&mdbg_dev->mdbg_lock); + //MDBG_ERR("data no ready"); + return 0; + } + + read_size = mdbg_receive(mdbg_dev->read_buf , MDBG_MAX_BUFFER_LEN); + printk_ratelimited(KERN_INFO "%s read_size: %d mdbg_read_count:%d\n",__func__,read_size,mdbg_read_count); + + if((read_size > 0) && (read_size <= MDBG_MAX_BUFFER_LEN)){ + MDBG_LOG("Show %d bytes data.",read_size); + + if(copy_to_user((void __user *)buf,mdbg_dev->read_buf ,read_size)){ + mutex_unlock(&mdbg_dev->mdbg_lock); + MDBG_ERR("copy from user fail!"); + return -EFAULT; + } + mdbg_read_count -= read_size; + mutex_unlock(&mdbg_dev->mdbg_lock); + return read_size; + }else{ + mdbg_read_count = 0; + mutex_unlock(&mdbg_dev->mdbg_lock); + MDBG_LOG("Show no data"); + return (0); + } +} + +LOCAL ssize_t mdbg_write(struct file *filp, const char __user *buf,size_t count,loff_t *pos) +{ + MDBG_SIZE_T sent_size = 0; + + if(NULL == buf || 0 == count){ + MDBG_ERR("Param Error!"); + return count; + } + mutex_lock(&mdbg_dev->mdbg_lock); + + if (count > MDBG_MAX_BUFFER_LEN ){ + mutex_unlock(&mdbg_dev->mdbg_lock); + MDBG_ERR("write too long!"); + return -EINVAL; + } + + memset(mdbg_dev->write_buf,0,MDBG_MAX_BUFFER_LEN); + if (copy_from_user(mdbg_dev->write_buf ,(void __user *)buf,count )){ + mutex_unlock(&mdbg_dev->mdbg_lock); + MDBG_ERR("to user fail!"); + return -EFAULT; + } + + sent_size = mdbg_send(mdbg_dev->write_buf , count, MDBG_CHANNEL_WRITE); + mutex_unlock(&mdbg_dev->mdbg_lock); + + MDBG_LOG("sent_size = %d",sent_size); + return count; +} + +static int mdbg_open(struct inode *inode,struct file *filp) +{ + //printk(KERN_INFO "MDBG:%s entry\n",__func__); + + if (mdbg_dev->open_count!=0) { + MDBG_ERR( "mdbg_open %d \n",mdbg_dev->open_count); + } + + mdbg_dev->open_count++; + + return 0; +} + +static int mdbg_release(struct inode *inode,struct file *filp) +{ + //printk(KERN_INFO "MDBG:%s entry\n",__func__); + + mdbg_dev->open_count--; + return 0; +} + +static unsigned int mdbg_poll(struct file *filp, poll_table *wait) +{ + unsigned int mask = 0; + + poll_wait(filp, &mdbg_dev->rxwait, wait); + if(mdbg_read_count > 0) + mask |= POLLIN | POLLRDNORM; + + return mask; +} + +static struct file_operations mdbg_fops = { + .owner = THIS_MODULE, + .read = mdbg_read, + .write = mdbg_write, + .open = mdbg_open, + .release = mdbg_release, + .poll = mdbg_poll, +}; +static struct miscdevice mdbg_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "slog_wcn", + .fops = &mdbg_fops, +}; + +LOCAL int __init mdbg_module_init(void) +{ + int err; + + MDBG_FUNC_ENTERY; + + mdbg_dev = kzalloc(sizeof(*mdbg_dev), GFP_KERNEL); + if (!mdbg_dev) + return -ENOMEM; + + mdbg_dev->read_buf = kzalloc(MDBG_MAX_BUFFER_LEN, GFP_KERNEL); + if (mdbg_dev->read_buf == NULL) { + MDBG_ERR("faile (NO MEM) Error!"); + return -ENOMEM; + } + mdbg_dev->write_buf = kzalloc(MDBG_MAX_BUFFER_LEN, GFP_KERNEL); + if (mdbg_dev->write_buf == NULL) { + kfree(mdbg_dev->read_buf); + mdbg_dev->write_buf = NULL; + MDBG_ERR("faile (NO MEM) Error!"); + return -ENOMEM; + } + + mdbg_dev->open_count = 0; + mutex_init(&mdbg_dev->mdbg_lock); + init_waitqueue_head(&mdbg_wait); + err = mdbg_sdio_init(); + if(err < 0) + return -ENOMEM; + + mdbg_fs_init(); + + return misc_register(&mdbg_device); +} + +LOCAL void __exit mdbg_module_exit(void) +{ + MDBG_FUNC_ENTERY; + mdbg_sdio_remove(); + mdbg_fs_init_exit(); + mutex_destroy(&mdbg_dev->mdbg_lock); + kfree(mdbg_dev->read_buf); + kfree(mdbg_dev->write_buf); + mdbg_dev->read_buf = NULL; + mdbg_dev->write_buf = NULL; + misc_deregister(&mdbg_device); +} + +module_init(mdbg_module_init); +module_exit(mdbg_module_exit); + +MODULE_AUTHOR("Fan Kou<fan.kou@spreadtrum.com>"); +MODULE_DESCRIPTION("MARLIN DEBUG SYSTEM."); +MODULE_LICENSE("GPL"); + diff --git a/drivers/misc/mdbg/mdbg.h b/drivers/misc/mdbg/mdbg.h new file mode 100644 index 00000000..1293c5b5 --- /dev/null +++ b/drivers/misc/mdbg/mdbg.h @@ -0,0 +1,24 @@ +/************************************************************************************************************ */ +/*****Copyright: 2014 Spreatrum. All Right Reserved */ +/*****File: mdbg.h */ +/*****Description: Marlin Debug System main file. Module,device & driver related defination. */ +/*****Developer: fan.kou@spreadtrum.com */ +/*****Date: 06/01/2014 */ +/************************************************************************************************************ */ + +#ifndef _MARLIN_DEBUG_H +#define _MARLIN_DEBUG_H + + +#include "mdbg_type.h" + +struct mdbg_devvice_t{ + int open_count; + struct mutex mdbg_lock; + char *read_buf; + char *write_buf; + wait_queue_head_t rxwait; +}; + + +#endif diff --git a/drivers/misc/mdbg/mdbg_ring.c b/drivers/misc/mdbg/mdbg_ring.c new file mode 100644 index 00000000..830fc788 --- /dev/null +++ b/drivers/misc/mdbg/mdbg_ring.c @@ -0,0 +1,234 @@ +/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_ring.c */
+/*****Description: Marlin Debug System ring buffer implementation. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/01/2014 */
+/************************************************************************************************************ */
+
+/*******************************************************/
+/*********************INCLUDING********************/
+/*******************************************************/
+#include "mdbg_ring.h"
+
+/*******************************************************/
+/***********Local Functions Declaration************/
+/*******************************************************/
+#define MDBG_RING_LOCK_INIT(pRing) mutex_init(pRing->plock)
+#define MDBG_RING_LOCK_UNINIT(pRing) mutex_destroy(pRing->plock)
+#define MDBG_RING_LOCK(pRing) mutex_lock(pRing->plock)
+#define MDBG_RING_UNLOCK(pRing) mutex_unlock(pRing->plock)
+#define _MDBG_RING_REMAIN(rp,wp,size) ((u_long)wp >= (u_long)rp?(size - (u_long)wp + (u_long)rp - 1): ((u_long)rp - (u_long)wp -1))
+
+LOCAL MDBG_SIZE_T mdbg_ring_remain(MDBG_RING_T* pRing);
+LOCAL MDBG_SIZE_T mdbg_ring_content_len(MDBG_RING_T* pRing);
+LOCAL char* mdbg_ring_start(MDBG_RING_T* pRing);
+LOCAL char* mdbg_ring_end(MDBG_RING_T* pRing);
+LOCAL bool mdbg_ring_over_loop(MDBG_RING_T* pRing, u_long len, int rw);
+
+
+/*******************************************************/
+/******************Ring Life Cycle*******************/
+/*******************************************************/
+PUBLIC MDBG_RING_T* mdbg_ring(MDBG_SIZE_T size)
+{
+ MDBG_RING_T* pRing = NULL;
+ do{
+ if(size < MDBG_RING_MIN_SIZE){
+ MDBG_ERR("size error:%d",size);
+ break;
+ }
+ pRing = kmalloc(sizeof(MDBG_RING_T),GFP_KERNEL);
+ if(NULL == pRing){
+ MDBG_ERR("Ring malloc Failed.");
+ break;
+ }
+ pRing->pbuff = kmalloc(size,GFP_KERNEL);
+ if(NULL == pRing->pbuff){
+ MDBG_ERR("Ring buff malloc Failed.");
+ break;
+ }
+ pRing->plock = kmalloc(MDBG_RING_LOCK_SIZE, GFP_KERNEL);
+ if(NULL == pRing->plock){
+ MDBG_ERR("Ring lock malloc Failed.");
+ break;
+ }
+ MDBG_RING_LOCK_INIT(pRing);
+ memset(pRing->pbuff,0,size);
+ pRing->size = size;
+ pRing->rp = pRing->pbuff;
+ pRing->wp = pRing->pbuff;
+ pRing->end = (char*)(((u_long)pRing->pbuff) + (pRing->size - 1));
+ return (pRing);//created a MDBG_RING!
+ }while(0);
+ mdbg_ring_destroy(pRing);
+ return (NULL);//failed
+}
+
+PUBLIC void mdbg_ring_destroy(MDBG_RING_T* pRing)
+{
+ MDBG_LOG("pRing = %p",pRing);
+ MDBG_LOG("pRing->pbuff = %p",pRing->pbuff);
+ if(pRing != NULL){
+ if(pRing->pbuff != NULL){
+ MDBG_LOG("to free pRing->pbuff.");
+ kfree(pRing->pbuff);
+ pRing->pbuff = NULL;
+ }
+ if(pRing->plock != NULL){
+ MDBG_LOG("to free pRing->plock.");
+ MDBG_RING_LOCK_UNINIT(pRing);
+ kfree(pRing->plock);
+ pRing->plock = NULL;
+ }
+ MDBG_LOG("to free pRing.");
+ kfree(pRing);
+ pRing = NULL;
+ }
+ return;
+}
+
+/*******************************************************/
+/****************Ring RW Fucntions*****************/
+/*******************************************************/
+PUBLIC int mdbg_ring_read(MDBG_RING_T* pRing, char* buf, int len)
+{
+ int len1,len2 = 0;
+ int cont_len = 0;
+ int read_len = 0;
+ char* pstart = NULL;
+ char* pend = NULL;
+
+ if((NULL == buf) ||(NULL == pRing) ||(0 == len)){
+ MDBG_ERR("Ring Read Failed, Param Error!,buf=%p,pRing=%p,len=%d",buf,pRing,len);
+ return (MDBG_ERR_BAD_PARAM);
+ }
+ MDBG_RING_LOCK(pRing);
+ cont_len = mdbg_ring_content_len(pRing);
+ read_len = cont_len >= len?len:cont_len;
+ pstart = mdbg_ring_start(pRing);
+ pend = mdbg_ring_end(pRing);
+ MDBG_LOG("read_len=%d",read_len);
+ MDBG_LOG("buf=%p",buf);
+ MDBG_LOG("pstart=%p",pstart);
+ MDBG_LOG("pend=%p",pend);
+ MDBG_LOG("pRing->rp=%p",pRing->rp);
+
+ if((0 == read_len)||(0 == cont_len)){
+ MDBG_LOG("read_len=0 OR Ring Empty.");
+ MDBG_RING_UNLOCK(pRing);
+ return (0);//ring empty + }
+
+ if(mdbg_ring_over_loop(pRing,read_len,MDBG_RING_R)){
+ MDBG_LOG("Ring loopover.");
+ len1 = pend - pRing->rp + 1;
+ len2 = read_len -len1; + memcpy(buf, pRing->rp, len1);
+ memcpy((buf+ len1), pstart, len2);
+ pRing->rp = (char *)((u_long)pstart + len2);
+ }else{ + memcpy(buf, pRing->rp, read_len);
+ pRing->rp += read_len;
+ } + MDBG_LOG("Ring did read len =%d.",read_len);
+ MDBG_RING_UNLOCK(pRing);
+ return (read_len); +} + +PUBLIC int mdbg_ring_write(MDBG_RING_T* pRing, char* buf, int len)
+{ + int len1,len2 = 0;
+ char* pstart = NULL;
+ char* pend = NULL;
+
+ if((NULL == pRing) || (NULL == buf)||(0 == len)){
+ MDBG_ERR("Ring Write Failed, Param Error!,buf=%p,pRing=%p,len=%d",buf,pRing,len);
+ return (MDBG_ERR_BAD_PARAM);
+ }
+ pstart = mdbg_ring_start(pRing);
+ pend = mdbg_ring_end(pRing);
+ MDBG_LOG("pstart = %p",pstart);
+ MDBG_LOG("pend = %p",pend);
+ MDBG_LOG("buf = %p",buf);
+ MDBG_LOG("len = %d",len);
+ MDBG_LOG("pRing->wp = %p",pRing->wp);
+
+ if(mdbg_ring_over_loop(pRing, len, MDBG_RING_W)){
+ MDBG_LOG("Ring overloop.");
+ len1 = pend - pRing->wp + 1;
+ len2 = len - len1;
+ memcpy(pRing->wp, buf, len1);
+ memcpy(pstart, (buf + len1), len2);
+ pRing->wp = (char *)((u_long)pstart + len2);
+ + }else{ + memcpy(pRing->wp, buf, len);
+ pRing->wp += len;
+ } + MDBG_LOG("Ring Wrote len = %d",len);
+ return (len); +}
+
+PUBLIC char* mdbg_ring_write_ext(MDBG_RING_T* pRing, MDBG_SIZE_T len)
+{
+ char* wp = NULL;
+ MDBG_LOG("pRing=%p,pRing->wp=%p,len=%d.", pRing, pRing->wp, len);
+
+ if((NULL == pRing)||(0 == len)){
+ MDBG_ERR("Ring Write Ext Failed, Param Error!");
+ return (NULL);
+ }
+
+ if(mdbg_ring_over_loop(pRing, len, MDBG_RING_R)||mdbg_ring_will_full(pRing, len)){
+ MDBG_LOG("Ring Write Ext Failed, Ring State Error!,overloop=%d,full=%d.",mdbg_ring_over_loop(pRing, len, MDBG_RING_R),mdbg_ring_will_full(pRing, len));
+ return (NULL);
+ }
+ MDBG_RING_LOCK(pRing);
+ wp = pRing->wp;
+ pRing->wp += len;
+ MDBG_LOG("return wp=%p,pRing->wp=%p.", wp, pRing->wp);
+ MDBG_RING_UNLOCK(pRing);
+ return (wp);
+}
+
+/*******************************************************/
+/******************Utility Fucntions*******************/
+/*******************************************************/
+
+PUBLIC bool mdbg_ring_will_full(MDBG_RING_T* pRing, int len)
+{
+ return(len > mdbg_ring_remain(pRing));
+}
+
+
+LOCAL MDBG_SIZE_T mdbg_ring_remain(MDBG_RING_T* pRing)
+{
+ return ((MDBG_SIZE_T)_MDBG_RING_REMAIN(pRing->rp, pRing->wp, pRing->size));
+}
+
+LOCAL MDBG_SIZE_T mdbg_ring_content_len(MDBG_RING_T* pRing)
+{
+ return (pRing->size - mdbg_ring_remain(pRing) - 1);
+}
+
+LOCAL char* mdbg_ring_start(MDBG_RING_T* pRing)
+{
+ return(pRing->pbuff);
+}
+
+LOCAL char* mdbg_ring_end(MDBG_RING_T* pRing)
+{
+ return(pRing->end);
+}
+
+LOCAL bool mdbg_ring_over_loop(MDBG_RING_T* pRing, u_long len, int rw)
+{
+ if(MDBG_RING_R == rw){
+ return ((u_long)pRing->rp + len > (u_long)mdbg_ring_end(pRing));
+ }else{
+ return ((u_long)pRing->wp + len > (u_long)mdbg_ring_end(pRing));
+ }
+}
+
+
diff --git a/drivers/misc/mdbg/mdbg_ring.h b/drivers/misc/mdbg/mdbg_ring.h new file mode 100644 index 00000000..f09d3513 --- /dev/null +++ b/drivers/misc/mdbg/mdbg_ring.h @@ -0,0 +1,54 @@ +/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_ring.h */
+/*****Description: Marlin Debug System ring buffer definition. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/01/2014 */
+/************************************************************************************************************ */
+
+#ifndef _MDBG_RING_H
+#define _MDBG_RING_H
+
+/*******************************************************/
+/*********************INCLUDING********************/
+/*******************************************************/
+#include "mdbg_type.h"
+#include <linux/mutex.h>
+
+/*******************************************************/
+/******************Macor Definitions****************/
+/*******************************************************/
+#define MDBG_RING_R 0
+#define MDBG_RING_W 1
+
+#define MDBG_RING_MIN_SIZE (1024 * 4)
+
+#define MDBG_RING_LOCK_SIZE (sizeof(mdbg_ring_lock))
+
+
+/*******************************************************/
+/******************Type Definitions*****************/
+/*******************************************************/
+typedef struct mutex mdbg_ring_lock;
+
+typedef struct mdbg_ring_t {
+ MDBG_SIZE_T size;
+ char * pbuff;
+ char* rp;
+ char* wp;
+ char* end;
+ mdbg_ring_lock* plock;
+}MDBG_RING_T;
+
+/*******************************************************/
+/***********Public Interface Declaration************/
+/*******************************************************/
+MDBG_RING_T* mdbg_ring(MDBG_SIZE_T size);
+void mdbg_ring_destroy(MDBG_RING_T* pRing);
+int mdbg_ring_read(MDBG_RING_T* pRing, char* buf, int len);
+int mdbg_ring_write(MDBG_RING_T* pRing, char* buf, int len);
+char* mdbg_ring_write_ext(MDBG_RING_T* pRing, MDBG_SIZE_T len);
+bool mdbg_ring_will_full(MDBG_RING_T* pRing, int len);
+
+#endif
+
diff --git a/drivers/misc/mdbg/mdbg_sdio.c b/drivers/misc/mdbg/mdbg_sdio.c new file mode 100644 index 00000000..f7367bed --- /dev/null +++ b/drivers/misc/mdbg/mdbg_sdio.c @@ -0,0 +1,158 @@ +/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_sdio.c */
+/*****Description: Marlin Debug System Sdio related interface functions. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/09/2014 */
+/************************************************************************************************************ */
+
+/*******************************************************/
+/*********************INCLUDING********************/
+/*******************************************************/
+#include "mdbg_sdio.h"
+#include "mdbg_ring.h"
+#include "mdbg.h"
+#include <linux/mutex.h>
+
+
+/*******************************************************/
+/******************Global Variables*****************/
+/*******************************************************/
+MDBG_RING_T* rx_ring;
+struct mutex mdbg_read_mutex;
+extern unsigned int mdbg_read_count;
+extern wait_queue_head_t mdbg_wait;
+extern unsigned int first_boot;
+extern struct mdbg_devvice_t *mdbg_dev;
+/*******************************************************/
+/******************Local Variables*******************/
+/*******************************************************/
+LOCAL uint8_t* mdbg_rx_buff;
+MDBG_SIZE_T sdio_read_len;
+static struct wake_lock mdbg_wake_lock;
+/*******************************************************/
+/***********Local Functions Declaration************/
+/*******************************************************/
+LOCAL void mdbg_sdio_read(void);
+LOCAL MDBG_SIZE_T mdbg_sdio_write(char* buff, MDBG_SIZE_T len,uint32 chn);
+
+/*******************************************************/
+/************MDBG SDIO Life Cycle****************/
+/*******************************************************/
+PUBLIC int mdbg_sdio_init(void)
+{
+ int err = 0;
+ rx_ring = mdbg_ring(MDBG_RX_RING_SIZE);
+ if(!rx_ring){
+ MDBG_ERR("Ring malloc error.");
+ err = (MDBG_ERR_MALLOC_FAIL);
+ }
+
+ mdbg_rx_buff = kmalloc(MDBG_RX_BUFF_SIZE, GFP_KERNEL);
+ if(!mdbg_rx_buff){
+ MDBG_ERR("mdbg_rx_buff malloc error.");
+ err = (MDBG_ERR_MALLOC_FAIL);
+ }
+
+ mutex_init(&mdbg_read_mutex);
+
+ wake_lock_init(&mdbg_wake_lock, WAKE_LOCK_SUSPEND, "mdbg_wake_lock");
+ MDBG_LOG("mdbg_sdio_init!");
+
+ return (err);
+}
+
+PUBLIC void mdbg_sdio_remove(void)
+{
+ MDBG_FUNC_ENTERY;
+ wake_lock_destroy(&mdbg_wake_lock);
+ sdiodev_readchn_uninit(MDBG_CHANNEL_READ);
+ mdbg_ring_destroy(rx_ring);
+ if(mdbg_rx_buff){
+ kfree(mdbg_rx_buff);
+ }
+}
+
+int mdbg_channel_init(void)
+{
+ int err = 0;
+
+ mdbg_read_count = 0;
+ first_boot = 0;
+ err = sdiodev_readchn_init(MDBG_CHANNEL_READ, mdbg_sdio_read,0);
+ if(err != 0){
+ MDBG_ERR("Sdio dev read channel init failed!");
+ }
+
+ if(rx_ring->pbuff != NULL)
+ memset(rx_ring->pbuff,0,MDBG_RX_RING_SIZE);
+ return err;
+}
+EXPORT_SYMBOL_GPL(mdbg_channel_init);
+
+
+/*******************************************************/
+/***********MDBG SDIO IO Functions**************/
+/*******************************************************/
+LOCAL MDBG_SIZE_T mdbg_sdio_write(char* buff, MDBG_SIZE_T len,uint32 chn)
+{
+ int cnt = 0;
+ MDBG_LOG("buff=%p,len=%d,[%s]",buff,len,buff);
+ if(1 != get_sdiohal_status()){
+ return 0;
+ }
+ while((set_marlin_wakeup(MDBG_CHANNEL_WRITE,0x3) < 0) && (cnt <= 3))
+ {
+ msleep(300);
+ cnt++;
+ }
+
+ sdio_dev_write(chn, buff, len);
+ return len;
+}
+
+PUBLIC void mdbg_sdio_read(void)
+{
+ wake_lock(&mdbg_wake_lock);
+ mutex_lock(&mdbg_read_mutex);
+ //set_marlin_wakeup(MDBG_CHANNEL_READ,0x1);
+ sdio_read_len = sdio_dev_get_chn_datalen(MDBG_CHANNEL_READ);
+ if(sdio_read_len <= 0)
+ {
+ MDBG_ERR("[%s][%d]\n",__func__, sdio_read_len);
+ wake_unlock(&mdbg_wake_lock);
+ mutex_unlock(&mdbg_read_mutex);
+ return;
+ }
+ sdio_dev_read(MDBG_CHANNEL_READ,mdbg_rx_buff,&sdio_read_len);
+ sdio_read_len = mdbg_ring_write(rx_ring,mdbg_rx_buff, sdio_read_len);
+ mdbg_read_count += sdio_read_len;
+ wake_up_interruptible(&mdbg_wait);
+ wake_up_interruptible(&mdbg_dev->rxwait);
+
+ wake_unlock(&mdbg_wake_lock);
+ mutex_unlock(&mdbg_read_mutex);
+ return;
+}
+EXPORT_SYMBOL_GPL(mdbg_sdio_read);
+
+/*******************************************************/
+/**************MDBG IO Functions******************/
+/*******************************************************/
+PUBLIC MDBG_SIZE_T mdbg_send(char* buff, MDBG_SIZE_T len,uint32 chn)
+{
+ MDBG_SIZE_T sent_size = 0;
+
+ MDBG_LOG("BYTE MODE");
+ wake_lock(&mdbg_wake_lock);
+ sent_size = mdbg_sdio_write(buff, len,chn);
+ wake_unlock(&mdbg_wake_lock);
+ return len;
+}
+
+PUBLIC MDBG_SIZE_T mdbg_receive(char* buff, MDBG_SIZE_T len)
+{
+ return (mdbg_ring_read(rx_ring, buff, len));
+}
+
+
diff --git a/drivers/misc/mdbg/mdbg_sdio.h b/drivers/misc/mdbg/mdbg_sdio.h new file mode 100644 index 00000000..97106f26 --- /dev/null +++ b/drivers/misc/mdbg/mdbg_sdio.h @@ -0,0 +1,37 @@ +/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_sdio.h */
+/*****Description: Marlin Debug System Sdio related interface functions. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/09/2014 */
+/************************************************************************************************************ */
+
+#ifndef _MDBG_SDIO_H
+#define _MDBG_SDIO_H
+
+/*******************************************************/
+/*********************INCLUDING********************/
+/*******************************************************/
+#include "mdbg_type.h"
+
+/*******************************************************/
+/******************Macor Definitions****************/
+/*******************************************************/
+#define MDBG_BYTE_MODE 0
+#define MDBG_WRITE_LEN (128)
+
+#define MDBG_CHANNEL_READ (14)
+#define MDBG_CHANNEL_WRITE (6)
+#define MDBG_MAX_RETRY (3)
+#define MDBG_RX_BUFF_SIZE (4096)
+
+/*******************************************************/
+/***********Public Interface Declaration************/
+/*******************************************************/
+int mdbg_sdio_init(void);
+void mdbg_sdio_remove(void);
+MDBG_SIZE_T mdbg_send(char* buff, MDBG_SIZE_T len, uint32 chn);
+MDBG_SIZE_T mdbg_receive(char* buff, MDBG_SIZE_T len);
+int mdbg_channel_init(void);
+
+#endif
diff --git a/drivers/misc/mdbg/mdbg_type.h b/drivers/misc/mdbg/mdbg_type.h new file mode 100644 index 00000000..40974e79 --- /dev/null +++ b/drivers/misc/mdbg/mdbg_type.h @@ -0,0 +1,65 @@ +/************************************************************************************************************ */
+/*****Copyright: 2014 Spreatrum. All Right Reserved */
+/*****File: mdbg_type.h */
+/*****Description: Marlin Debug System type defination. */
+/*****Developer: fan.kou@spreadtrum.com */
+/*****Date: 06/01/2014 */
+/************************************************************************************************************ */
+
+#ifndef _MDBG_TYPE_H
+#define _MDBG_TYPE_H
+
+#include <linux/fs.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/miscdevice.h> +#include <linux/delay.h> +#include <linux/module.h>
+#include <linux/slab.h> +#include <linux/irq.h> +#include <linux/input.h>
+#include <linux/fs.h> +#include <asm/uaccess.h> +#include <linux/miscdevice.h> +#include <linux/platform_device.h> + +#include "../sdiodev/sdio_dev.h"
+
+#define PUBLIC
+#define LOCAL static
+
+#define MDBG_HEADER "MDBG: "
+#define MDBG_HEADER_ERR "MDBG_ERR: "
+#define MDBG_DEBUG_MODE 0
+
+#define MDBG_ERR(fmt,args...) printk(MDBG_HEADER_ERR "%s:" fmt "\n", __func__, ## args)
+#if MDBG_DEBUG_MODE +#define MDBG_LOG(fmt,args...) printk(MDBG_HEADER "%s:" fmt "\n", __func__, ## args)
+#else +#define MDBG_LOG(fmt,args...)
+#endif
+
+#define MDBG_FUNC_ENTERY MDBG_LOG("ENTER.")
+#define MDBG_FUNC_EXIT MDBG_LOG("EXIT.")
+
+
+#define MDBG_RX_RING_SIZE (1024*1024)
+
+
+/*******************************************************/ +/**************MDBG ERROR CODE***************/
+/*******************************************************/
+#define MDBG_SUCCESS (0)
+#define MDBG_ERR_RING_FULL (-1)
+#define MDBG_ERR_MALLOC_FAIL (-2)
+#define MDBG_ERR_BAD_PARAM (-3)
+#define MDBG_ERR_SDIO_ERR (-4)
+#define MDBG_ERR_TIMEOUT (-5)
+#define MDBG_ERR_NO_FILE (-6)
+
+
+typedef long int MDBG_SIZE_T;
+
+
+#endif
|
