📄 jpt_driver.c
字号:
info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1); info->wbl[i & 3] = c; tbuf[i] = c; } spin_lock_irqsave(&info->lock, flags); nuart_write_buf(info->base, buf_pos, tbuf, wbl_pos + count); spin_unlock_irqrestore(&info->lock, flags); info->xmit_cnt -= count; info->twp += count; spin_lock_irqsave(&info->lock, flags); nuart_set_twp(info->base, &info->reg, info->twp); spin_unlock_irqrestore(&info->lock, flags); if(info->xmit_cnt < WAKEUP_CHARS) { set_bit(NUART_EVENT_TXLOW, &info->event); schedule_work(&info->tqueue); } return;}static void nuart16_transmit_chars(struct nuart_struct *info){ int count, i; int wbl_pos; int buf_pos; char tbuf[256]; int c; unsigned long flags = 0; count = 120 - ((info->twp - info->trp) & 0x7f); count = MIN(info->xmit_cnt, count); if(count <= 0) return; wbl_pos = info->twp & 3; buf_pos = info->twp & (~3); if(wbl_pos) memcpy(tbuf,info->wbl,wbl_pos); for(i = wbl_pos;i < count + wbl_pos; i++) { c = info->xmit_buf[info->xmit_tail++]; info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1); info->wbl[i & 3] = c; tbuf[i] = c; } spin_lock_irqsave(&info->lock, flags); nuart_write_buf(info->base, buf_pos, tbuf, wbl_pos + count); spin_unlock_irqrestore(&info->lock, flags); info->xmit_cnt -= count; info->twp += count; spin_lock_irqsave(&info->lock, flags); nuart_set_twp(info->base, &info->reg, info->twp); spin_unlock_irqrestore(&info->lock, flags); if(info->xmit_cnt < WAKEUP_CHARS) { set_bit(NUART_EVENT_TXLOW, &info->event); schedule_work(&info->tqueue); } return;}static void nuart_timeout_port(struct nuart_struct * info){ unsigned long status, flags; spin_lock_irqsave(&info->lock, flags); status = nuart_get_stat(info->base); spin_unlock_irqrestore(&info->lock, flags); info->rwp = ((status & 0xff00) >> 8) & 0xff; info->trp = status & 0xff; if((status & (NUART_RI | NUART_DSR | NUART_DCD | NUART_CTS)) != (info->reg.mpr & (NUART_RI | NUART_DSR | NUART_DCD | NUART_CTS))) nuart_check_modem_status(info, status); nuart_receive_chars(info, status); info->reg.mpr = status; if (info->xmit_cnt && !info->tty->stopped && !info->tty->hw_stopped) nuart_transmit_chars(info); }static void nuart_timeout_single(int board, struct nuart_hwconf *hwconf){ struct nuart_struct *info; int i, n; n = board * NUART_PORTS_PER_BOARD; info = &nuvar_table[n]; for (i = 0; i < hwconf->ports; i++, n++, info++) { if(info->port != n) continue; if (info->flags & ASYNC_INITIALIZED) nuart_timeout_port(info); }}static void nuart_timeout(unsigned long ptr){ int i; for (i = 0; i < NUART_BOARDS; i++) { if (nuartcfg[i].board_type == -1) continue; nuart_timeout_single(i, &nuartcfg[i]); } nuart_timer.function = nuart_timeout; nuart_timer.data = (unsigned long)0; nuart_timer.expires = jiffies + 1; /* 1ms */ add_timer(&nuart_timer); return;}static int nuart_open(struct tty_struct *tty, struct file *filp){ struct nuart_struct *info; int retval, line; unsigned long page; line = PORTNO(tty); if ((line < 0) || (line >= NUART_PORTS)) return (-ENODEV); info = &nuvar_table[line]; if (!info->base) return (-ENODEV); tty->driver_data = info; info->tty = tty; if (!nuvar_tmp_buf) { page = get_zeroed_page(GFP_KERNEL); if (!page) return (-ENOMEM); if (nuvar_tmp_buf) free_page(page); else nuvar_tmp_buf = (unsigned char *) page; } /* * Start up serial port */ info->count++; retval = nuart_startup(info); if (retval) return (retval); return nuart_block_til_ready(tty, filp, info);}static int nuart_get_line(struct file * f, char * buf, ssize_t size, loff_t * off){ int n, i; loff_t offset = *off; n = f->f_op->read(f, buf, size, &offset); if(n <= 0) return 0; for(i = 0; i < n ; i++) { if(buf[i] == 0xa) break; } buf[i] = 0; i++; *off += i; return i;}static int nuart_atoi(char * s){ int n = 0; char * p = s; while((*p == ' ') || (*p == '\t')) p ++; while((*p >= '0') && (*p <= '9')) { n *= 10; n += *p - '0'; p ++; } return n;} static void nuart_get_mode(struct nuart_struct * info){ struct file * f; char buf[256]; char *s; mm_segment_t fs; loff_t offset = 0; if(info->type == NUART_BOARD_RS232) { info->mode = NUART_PORT_RS232; return; } f = filp_open("/etc/jpt.conf",O_RDWR, 0600); if(IS_ERR(f)) { printk("WARNING : /etc/jpt.conf does not exist\n"); info->mode = -1; } else { info->mode = -1; fs = get_fs(); set_fs(KERNEL_DS); while(nuart_get_line(f, buf, sizeof(buf), &offset)) { if(memcmp(buf, "ttyn", 4)) continue; s = buf + 4; if(nuart_atoi(s) != info->port) continue; while((*s != ' ') && (*s != '\t')) s++; info->mode = nuart_atoi(s); break; } set_fs(fs); filp_close(f, NULL); } switch(info->type) { case NUART_BOARD_RS232: break; case NUART_BOARD_RS485: if((info->mode != NUART_PORT_RS485F) && (info->mode != NUART_PORT_RS485H)) { printk("WARNING : set ttyn%d to default mode(rs_485 full)\n", info->port); info->mode = NUART_PORT_RS485F; } break; case NUART_BOARD_RS422_RS485: if((info->mode != NUART_PORT_RS422) && (info->mode != NUART_PORT_RS485F) && (info->mode != NUART_PORT_RS485H)) { printk("WARNING : set ttyn%d to default mode(rs_485 full)\n", info->port); info->mode = NUART_PORT_RS485F; } break; case NUART_BOARD_RS232_RS422_RS485: if((info->mode != NUART_PORT_RS232) && (info->mode != NUART_PORT_RS422) && (info->mode != NUART_PORT_RS485F) && (info->mode != NUART_PORT_RS485H)) { printk("WARNING : set ttyn%d to default mode(rs_232)\n", info->port); info->mode = NUART_PORT_RS232; } break; default: printk("WARNING : set ttyn%d to default mode(rs_232)\n", info->port); info->mode = NUART_PORT_RS232; } return;}static int nuart_startup(struct nuart_struct *info){ unsigned long flags = 0; unsigned long page; page = get_zeroed_page(GFP_KERNEL); if (!page) return (-ENOMEM); spin_lock_irqsave(&info->lock, flags); if (info->flags & ASYNC_INITIALIZED) { free_page(page); spin_unlock_irqrestore(&info->lock, flags); return (0); } if (!info->base) { if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); free_page(page); spin_unlock_irqrestore(&info->lock, flags); return (0); } if (info->xmit_buf) free_page(page); else info->xmit_buf = (unsigned char *) page; /* initialize the port */ nuart_get_mode(info); nuart_port_enable_and_init(info->base, &info->reg, info->mode); nuart_dtr(info->base, &info->reg, 1); nuart_rts(info->base, &info->reg, 1); info->lflag = (NUART_LFLAG_RDI | NUART_LFLAG_MSI | NUART_LFLAG_THRI | NUART_LFLAG_RLSI); if (info->tty) test_and_clear_bit(TTY_IO_ERROR, &info->tty->flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; spin_unlock_irqrestore(&info->lock, flags); /* * and set the speed of the serial port */ nuart_change_speed(info, 0); info->flags |= ASYNC_INITIALIZED; return (0);}static int nuart_change_speed(struct nuart_struct *info, struct termios *old_termios){ unsigned cflag, cval; int i; int ret = 0; unsigned long flags; unsigned long quot = 0; unsigned long pcr = 0; unsigned long pcr_mask = 0; if (!info->tty || !info->tty->termios) return ret; cflag = info->tty->termios->c_cflag; if (!(info->base)) return ret;#ifndef B921600#define B921600 (B460800 +1)#endif switch (cflag & (CBAUD | CBAUDEX)) { case B921600: i = 20; break; case B460800: i = 19; break; case B230400: i = 18; break; case B115200: i = 17; break; case B57600: i = 16; break; case B38400: i = 15; break; case B19200: i = 14; break; case B9600: i = 13; break; case B4800: i = 12; break; case B2400: i = 11; break; case B1800: i = 10; break; case B1200: i = 9; break; case B600: i = 8; break; case B300: i = 7; break; case B200: i = 6; break; case B150: i = 5; break; case B134: i = 4; break; case B110: i = 3; break; case B75: i = 2; break; case B50: i = 1; break; default: i = 0; break; } if(i == 15) { if((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) i = 16; if((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) i = 17;#ifdef ASYNC_SPD_SHI if((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) i = 18;#endif#ifdef ASYNC_SPD_WARP if((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) i = 19;#endif } if (nuart_baud_table[i]) quot = info->baud_base / nuart_baud_table[i]; else quot = 0; if(quot) quot --; /* byte size and parity */ pcr = 0; cval = 9; if (cflag & CSTOPB) { pcr |= NUART_SBITS; } if (cflag & PARENB) { pcr |= NUART_PEN; if (!(cflag & PARODD)) pcr |= NUART_P_EVEN; cval -= 1; } switch (cflag & CSIZE) { case CS5: pcr |= cval - 5;; break; case CS6: pcr |= cval - 6;; break; case CS7: pcr |= cval - 7; break; case CS8: pcr |= cval - 8; break; default: break; /* too keep GCC shut... */ } if (cflag & CRTSCTS) { if(!(info->reg.pcr & NUART_RTSC_FLOW)) { info->flags |= ASYNC_CTS_FLOW; pcr_mask |= NUART_RTSC_MASK; pcr |= (NUART_OCTS | NUART_RTSC_FLOW);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -