static int vs_add_dev(struct pdp_info *dev) { struct tty_driver *tty_driver; tty_driver = get_tty_driver_by_id(dev); kref_init(&tty_driver->kref); tty_driver->magic = TTY_DRIVER_MAGIC; tty_driver->driver_name = "multipdp"; tty_driver->name = dev->vs_dev.tty_name; tty_driver->major = CSD_MAJOR_NUM; tty_driver->minor_start = get_minor_start_index(dev->id); tty_driver->num = 1; tty_driver->type = TTY_DRIVER_TYPE_SERIAL; tty_driver->subtype = SERIAL_TYPE_NORMAL; tty_driver->flags = TTY_DRIVER_REAL_RAW; // tty_driver->refcount = dev->vs_dev.refcount; tty_driver->ttys = dev->vs_dev.tty_table; // 2.6 kernel porting tty_driver->termios = dev->vs_dev.termios; tty_driver->termios_locked = dev->vs_dev.termios_locked; tty_set_operations(tty_driver, &multipdp_tty_ops); return tty_register_driver(tty_driver); }
static int multipdp_vs_read(struct pdp_info *dev, char *buf, size_t len) { int ret = 0; if (!dev) { return 0; } #ifndef NO_TTY_RX_BUFF if(len > 1500) { #else if(len > MAX_RX_BUFF_LEN) { #endif unsigned char *prx_buf = kzalloc(len, GFP_ATOMIC); if(prx_buf == NULL) return 0; memcpy(prx_buf, buf, len); ret = len; if(ret != len) return ret; if(dev->vs_dev.tty == NULL) printk(">>>>> TTY is NULL : (1)~ !!!! \n"); if (ret > 0 && dev->vs_dev.tty != NULL) { ret = multipdp_tty_insert_data(dev->vs_dev.tty, prx_buf, ret); if( ret > 0 ) tty_flip_buffer_push(dev->vs_dev.tty); } printk("RF cal data read.(1) len: %d ret: %d\n", len, ret); kfree(prx_buf); } else { /* pdp data length.. */ memcpy(pdp_rx_buf, buf, len); ret = len; if (ret != len) { return ret; } #ifdef LOOP_BACK_TEST if (dev->id == LOOP_BACK_CHANNEL) { // compare and resend , update stastic data //printk("receive loopback packet[%d]\n",loopback_res.nTransfered); //printk("read data : %x %x %x %x %x %x\n",pdp_rx_buf[0],pdp_rx_buf[1],pdp_rx_buf[2],pdp_rx_buf[3],pdp_rx_buf[4],pdp_rx_buf[5]); //printk("write data : %x %x %x %x %x %x\n",loopback_data[0],loopback_data[1],loopback_data[2],loopback_data[3],loopback_data[4],loopback_data[5]); if (loopback_ongoing) { if (strncmp(pdp_rx_buf, loopback_data, loopback_res.nPacketDataSize)){ //printk("receive packet is not identical to that sent\n"); } else { send_loop_back_packet(loopback_data, loopback_res.nPacketDataSize); } } else { //do nothing //printk("loopback channel has gotten data, but test is no ongoing\n"); } } else if (ret > 0 && dev->vs_dev.tty != NULL) { tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, ret); tty_flip_buffer_push(dev->vs_dev.tty); } #else if(dev->vs_dev.tty == NULL) printk(">>>>> TTY is NULL : (2)~ !!!! \n"); if (ret > 0 && dev->vs_dev.tty != NULL) { #if 1 ret = multipdp_tty_insert_data(dev->vs_dev.tty, pdp_rx_buf, ret); #else ret = tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, ret); #endif if( ret > 0 ) tty_flip_buffer_push(dev->vs_dev.tty); } //printk("RF cal data read.(2) len: %d ret: %d\n", len, ret); #endif } //printk("multipdp_vs_read : len = %d\n", ret); return ret; } //////////// #endif static int vs_read(struct pdp_info *dev, size_t len) { int retval = 0; u32 size; u32 copied_size; int insert_size = 0; if (dev) { /* pdp data length. */ if (len > MAX_PDP_DATA_LEN) { // RF cal data? DPRINTK(1, "CAL DATA\n"); size = dpram_read(dpram_filp, prx_buf, len); DPRINTK(1, "multipdp_thread request read size : %d readed size %d, count : %d\n",len ,size,count); #ifdef CONFIG_ENABLE_TTY_CIQ if ((dev->id == 26 && !fp_vsCIQ0) ||(dev->id == 9 && !fp_vsCIQ1)||(dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)){ #else if ((dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)){ #endif EPRINTK("vs_read : %s, discard data.\n", dev->vs_dev.tty->name); } else { while (size) { copied_size = (size > MAX_PDP_DATA_LEN) ? MAX_PDP_DATA_LEN : size; if (size > 0 && dev->vs_dev.tty != NULL) insert_size = tty_insert_flip_string(dev->vs_dev.tty, prx_buf+retval, copied_size); if (insert_size != copied_size) { EPRINTK("flip buffer full : %s, insert size : %d, real size : %d\n",dev->vs_dev.tty->name,copied_size,insert_size); return -1; } size = size - copied_size; retval += copied_size; } DPRINTK(1, "retval : %d\n",retval); tty_flip_buffer_push(dev->vs_dev.tty); count++; } } else { retval = dpram_read(dpram_filp, pdp_rx_buf, len); if (retval != len) return retval; if(retval > 0){ #ifdef CONFIG_ENABLE_TTY_CIQ if((dev->id == 26 && !fp_vsCIQ0) ||(dev->id == 9 && !fp_vsCIQ1) ||( dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)) { #else if((dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)) { #endif EPRINTK("vs_read : %s, discard data.\n", dev->vs_dev.tty->name); } else { insert_size = tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, retval); if (insert_size != retval) { EPRINTK("flip buffer full : %s, insert size : %d, real size : %d\n",dev->vs_dev.tty->name,retval,insert_size); return -1; } tty_flip_buffer_push(dev->vs_dev.tty); } } } } return 0; } static int vs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { return -ENOIOCTLCMD; } #if 0 static void vs_break_ctl(struct tty_struct *tty, int break_state) { } #endif static struct tty_operations multipdp_tty_ops = { .open = vs_open, .close = vs_close, .write = vs_write, .write_room = vs_write_room, .ioctl = vs_ioctl, .chars_in_buffer = vs_chars_in_buffer, /* TODO: add more operations */ }; static int vs_add_dev(struct pdp_info *dev) { struct tty_driver *tty_driver; tty_driver = get_tty_driver_by_id(dev); kref_init(&tty_driver->kref); tty_driver->magic = TTY_DRIVER_MAGIC; tty_driver->driver_name = "multipdp"; tty_driver->name = dev->vs_dev.tty_name; tty_driver->major = CSD_MAJOR_NUM; tty_driver->minor_start = get_minor_start_index(dev->id); tty_driver->num = 1; tty_driver->type = TTY_DRIVER_TYPE_SERIAL; tty_driver->subtype = SERIAL_TYPE_NORMAL; tty_driver->flags = TTY_DRIVER_REAL_RAW; // tty_driver->refcount = dev->vs_dev.refcount; tty_driver->ttys = dev->vs_dev.tty_table; // 2.6 kernel porting tty_driver->termios = dev->vs_dev.termios; tty_driver->termios_locked = dev->vs_dev.termios_locked; tty_set_operations(tty_driver, &multipdp_tty_ops); return tty_register_driver(tty_driver); } static void vs_del_dev(struct pdp_info *dev) { struct tty_driver *tty_driver = NULL; tty_driver = get_tty_driver_by_id(dev); tty_unregister_driver(tty_driver); return; } /* * PDP context and mux/demux functions */ static inline struct pdp_info * pdp_get_dev(u8 id) { int slot; for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { if (pdp_table[slot] && pdp_table[slot]->id == id) { 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; }