static int emd_cfifo_open(struct inode *inode, struct file *file) { int minor = iminor(inode); int major = imajor(inode); int index, minor_start; int md_id; int ret = 0; char *name; cfifo_ctl_block_t *ctlb; cfifo_instance_t *cfifo_instance = NULL; md_id = emd_get_md_id_by_dev_major(major); if(md_id<0) { EMD_MSG_INF("cfifo","get_md_id_by_dev_major(%d)=%d\n", major,md_id); return -ENODEV; } ret = emd_get_dev_id_by_md_id(md_id, "cfifo", NULL, &minor_start); if(ret < 0){ EMD_MSG_INF("cfifo","get minor start fail(%d)\n", ret); return -ENODEV; } index = minor - minor_start; ctlb = emd_cfifo_ctlb[md_id]; switch(index) { case EMD_CFIFO_MODEM: name = "emd_modem"; EMD_MSG_INF("cfifo","emd_cfifo_open: emd_modem\n"); cfifo_instance = &ctlb->emd_cfifo_modem; break; case EMD_CFIFO_MUXD: name = "emd_muxd"; EMD_MSG_INF("cfifo","emd_cfifo_open: emd_muxd\n"); cfifo_instance = &ctlb->emd_cfifo_muxd; cfifo_instance->reset_handle = emd_reset_register(name); if(cfifo_instance->reset_handle<0) { EMD_MSG_INF("cfifo","open emd_reset_register: failed\n"); } break; default: EMD_MSG_INF("cfifo","error index(%d)=minor(%d)-minor_start(%d)\n", index,minor,minor_start); return -ENODEV; } mutex_lock(&cfifo_instance->emd_cfifo_mutex); cfifo_instance->count++; cfifo_instance->m_md_id = md_id; if(cfifo_instance->count > 1){ EMD_MSG_INF("cfifo","[cfifo_open]Multi-Open! %s open %s%d, %s, count:%d\n", current->comm, ctlb->node_name, index, name, cfifo_instance->count); mutex_unlock(&cfifo_instance->emd_cfifo_mutex); return -EMFILE; } else { EMD_MSG_INF("cfifo","[cfifo_open]%s open %s%d, %s, nb_flag:%x\n", current->comm, ctlb->node_name, index, name, file->f_flags & O_NONBLOCK); write_lock_bh(&cfifo_instance->emd_cfifo_rwlock); cfifo_instance->ready = 1; write_unlock_bh(&cfifo_instance->emd_cfifo_rwlock); file->private_data=cfifo_instance; nonseekable_open(inode,file); mutex_unlock(&cfifo_instance->emd_cfifo_mutex); } return ret; }
int emd_cfifo_init(int md_id) { int ret = 0; int cfifo_buf_len; int major,minor; cfifo_ctl_block_t *ctlb; char name[16]; // Create control block structure ctlb = (cfifo_ctl_block_t *)kmalloc(sizeof(cfifo_ctl_block_t), GFP_KERNEL); if(ctlb == NULL) { EMD_MSG_INF("cfifo","emd_cfifo_init kmalloc(%d) fail\n",sizeof(cfifo_ctl_block_t)); return -1; } memset(ctlb, 0, sizeof(cfifo_ctl_block_t)); emd_cfifo_ctlb[md_id] = ctlb; // Init ctlb ctlb->m_md_id = md_id; ret = emd_get_dev_id_by_md_id(md_id, "cfifo", &major, &minor); if(ret < 0) { EMD_MSG_INF("cfifo","emd_get_dev_id_by_md_id(cfifo) ret=%d fail\n",ret); goto _RELEASE_CTL_MEMORY; } snprintf(name, 16, "%s", EMD_CFIFO_NAME); if (register_chrdev_region(MKDEV(major, minor), EMD_CFIFO_NUM*2, name) != 0) { EMD_MSG_INF("cfifo","regsiter emd_cfifo fail\n"); ret = -1; goto _RELEASE_CTL_MEMORY; } cdev_init(&ctlb->emd_cfifo_dev, &emd_cfifo_ops); ctlb->emd_cfifo_dev.owner = THIS_MODULE; ret = cdev_add(&ctlb->emd_cfifo_dev, MKDEV(major,minor), EMD_CFIFO_NUM*2); if (ret) { EMD_MSG_INF("cfifo","cdev_add fail\n"); goto _DEL_cfifo_DRV; } snprintf(ctlb->drv_name, 32, EMD_CFIFO_NAME); snprintf(ctlb->node_name, 16, "emd_cfifo"); ctlb->uart1_shared_mem = (shared_mem_t*)kmalloc(EMD_SHARE_MEM_SIZE, GFP_KERNEL); if(ctlb->uart1_shared_mem ==NULL) { EMD_MSG_INF("cfifo","kmalloc share memory fail\n"); goto _DEL_cfifo_DRV; } cfifo_buf_len = (EMD_SHARE_MEM_SIZE - sizeof(shared_mem_t))/2; ctlb->cfifo_buf_size = cfifo_buf_len; ctlb->uart1_shared_mem->tx_control.length = cfifo_buf_len; ctlb->uart1_shared_mem->tx_control.read = 0; ctlb->uart1_shared_mem->tx_control.write = 0; ctlb->uart1_shared_mem->rx_control.length = cfifo_buf_len; ctlb->uart1_shared_mem->rx_control.read = 0; ctlb->uart1_shared_mem->rx_control.write = 0; ctlb->emd_cfifo_modem.count = 0; ctlb->emd_cfifo_modem.shared_mem.rx_control.length = &(ctlb->uart1_shared_mem->rx_control.length); ctlb->emd_cfifo_modem.shared_mem.rx_control.read = &(ctlb->uart1_shared_mem->rx_control.read); ctlb->emd_cfifo_modem.shared_mem.rx_control.write = &(ctlb->uart1_shared_mem->rx_control.write); ctlb->emd_cfifo_modem.shared_mem.rx_control.buffer = ctlb->uart1_shared_mem->buffer; ctlb->emd_cfifo_modem.shared_mem.tx_control.length = &(ctlb->uart1_shared_mem->tx_control.length); ctlb->emd_cfifo_modem.shared_mem.tx_control.read = &(ctlb->uart1_shared_mem->tx_control.read); ctlb->emd_cfifo_modem.shared_mem.tx_control.write = &(ctlb->uart1_shared_mem->tx_control.write); ctlb->emd_cfifo_modem.shared_mem.tx_control.buffer = ctlb->uart1_shared_mem->buffer+cfifo_buf_len; ctlb->emd_cfifo_modem.ready = 1; ctlb->emd_cfifo_modem.idx = 0; ctlb->emd_cfifo_modem.reset_handle =-1; ctlb->emd_cfifo_modem.other_side = &ctlb->emd_cfifo_muxd; snprintf(ctlb->emd_cfifo_modem.wakelock_name, sizeof(ctlb->emd_cfifo_muxd.wakelock_name), "%s", "emd_modem"); emd_cfifo_instance_init(&ctlb->emd_cfifo_modem); ctlb->emd_cfifo_muxd.count = 0; ctlb->emd_cfifo_muxd.shared_mem.rx_control.length = &(ctlb->uart1_shared_mem->tx_control.length); ctlb->emd_cfifo_muxd.shared_mem.rx_control.read = &(ctlb->uart1_shared_mem->tx_control.read); ctlb->emd_cfifo_muxd.shared_mem.rx_control.write = &(ctlb->uart1_shared_mem->tx_control.write); ctlb->emd_cfifo_muxd.shared_mem.rx_control.buffer = ctlb->uart1_shared_mem->buffer+cfifo_buf_len; ctlb->emd_cfifo_muxd.shared_mem.tx_control.length = &(ctlb->uart1_shared_mem->rx_control.length); ctlb->emd_cfifo_muxd.shared_mem.tx_control.read = &(ctlb->uart1_shared_mem->rx_control.read); ctlb->emd_cfifo_muxd.shared_mem.tx_control.write = &(ctlb->uart1_shared_mem->rx_control.write); ctlb->emd_cfifo_muxd.shared_mem.tx_control.buffer = ctlb->uart1_shared_mem->buffer; ctlb->emd_cfifo_muxd.ready = 1; ctlb->emd_cfifo_muxd.idx = 1; ctlb->emd_cfifo_muxd.reset_handle = -1; ctlb->emd_cfifo_muxd.other_side = &ctlb->emd_cfifo_modem; snprintf(ctlb->emd_cfifo_muxd.wakelock_name, sizeof(ctlb->emd_cfifo_muxd.wakelock_name), "%s", "emd_muxd"); emd_cfifo_instance_init(&ctlb->emd_cfifo_muxd); EMD_MSG_INF("cfifo","emd_cfifo_init success\n"); return 0; _DEL_cfifo_DRV: unregister_chrdev_region(MKDEV(major,minor), EMD_CFIFO_NUM*2); _RELEASE_CTL_MEMORY: if(ctlb->uart1_shared_mem) { kfree(ctlb->uart1_shared_mem); } if(ctlb) { kfree(ctlb); } emd_cfifo_ctlb[md_id] = NULL; return ret; }
int emd_chr_init(int md_id) { int ret=0, i; int major,minor; mutex_init(&emd_reset_mutex); EMD_MSG_INF("chr","ver: 20111111\n"); ret = emd_get_dev_id_by_md_id(md_id, "chr", &major, &minor); if(ret < 0) { EMD_MSG_INF("chr","emd_get_dev_id_by_md_id(chr) ret=%d fail\n",ret); goto _ERR; } /* 1. Register device region. 0~2 */ if (register_chrdev_region(MKDEV(major,minor),EMD_CHR_CLIENT_NUM,EMD_DEV_NAME) != 0) { EMD_MSG_INF("chr","Regsiter EMD_CHR_DEV failed\n"); ret=-1; goto _ERR; } /* 2. Alloc charactor devices */ emd_chr_dev=cdev_alloc(); if (NULL == emd_chr_dev) { EMD_MSG_INF("chr","cdev_alloc failed\n"); ret=-1; goto cdev_alloc_fail; } /* 3. Initialize and add devices */ cdev_init(emd_chr_dev,&emd_chr_dev_fops); emd_chr_dev->owner=THIS_MODULE; ret = cdev_add(emd_chr_dev,MKDEV(major,minor),EMD_CHR_CLIENT_NUM); if (ret){ EMD_MSG_INF("chr","cdev_add failed\n"); goto cdev_add_fail; } /* 4. Register platform driver */ ret = platform_driver_register(&emd_ctl_driver); if(ret){ EMD_MSG_INF("chr","platform_driver_register failed\n"); goto platform_driver_register_fail; } /* 5. Init driver client */ for(i=0; i<EMD_CHR_CLIENT_NUM; i++){ if( 0!=client_init(&drv_client[i],major, i) ){ EMD_MSG_INF("chr","driver client init failed\n"); goto driver_client_init_fail; } } return 0; driver_client_init_fail: platform_driver_register_fail: cdev_add_fail: cdev_del(emd_chr_dev); cdev_alloc_fail: unregister_chrdev_region(MKDEV(EMD_CHR_DEV_MAJOR,0),EMD_CHR_CLIENT_NUM); _ERR: return ret; }