📄 belkin_sa.c
字号:
priv->control_state &= ~TIOCM_DSR; if (priv->last_msr & BELKIN_SA_MSR_CTS) priv->control_state |= TIOCM_CTS; else priv->control_state &= ~TIOCM_CTS; if (priv->last_msr & BELKIN_SA_MSR_RI) priv->control_state |= TIOCM_RI; else priv->control_state &= ~TIOCM_RI; if (priv->last_msr & BELKIN_SA_MSR_CD) priv->control_state |= TIOCM_CD; else priv->control_state &= ~TIOCM_CD; /* Now to report any errors */ priv->last_lsr = data[BELKIN_SA_LSR_INDEX];#if 0 /* * fill in the flip buffer here, but I do not know the relation * to the current/next receive buffer or characters. I need * to look in to this before committing any code. */ if (priv->last_lsr & BELKIN_SA_LSR_ERR) { tty = port->tty; /* Overrun Error */ if (priv->last_lsr & BELKIN_SA_LSR_OE) { } /* Parity Error */ if (priv->last_lsr & BELKIN_SA_LSR_PE) { } /* Framing Error */ if (priv->last_lsr & BELKIN_SA_LSR_FE) { } /* Break Indicator */ if (priv->last_lsr & BELKIN_SA_LSR_BI) { } }#endif /* INT urbs are automatically re-submitted */}static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios *old_termios){ struct usb_serial *serial = port->serial; struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private; unsigned int iflag; unsigned int cflag; unsigned int old_iflag = 0; unsigned int old_cflag = 0; __u16 urb_value = 0; /* Will hold the new flags */ if ((!port->tty) || (!port->tty->termios)) { dbg ("%s - no tty or termios structure", __FUNCTION__); return; } iflag = port->tty->termios->c_iflag; cflag = port->tty->termios->c_cflag; /* check that they really want us to change something */ if (old_termios) { if ((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { dbg("%s - nothing to change...", __FUNCTION__); return; } old_iflag = old_termios->c_iflag; old_cflag = old_termios->c_cflag; } /* Set the baud rate */ if( (cflag&CBAUD) != (old_cflag&CBAUD) ) { /* reassert DTR and (maybe) RTS on transition from B0 */ if( (old_cflag&CBAUD) == B0 ) { priv->control_state |= (TIOCM_DTR|TIOCM_RTS); if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0) err("Set DTR error"); /* don't set RTS if using hardware flow control */ if (!(old_cflag&CRTSCTS) ) if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0) err("Set RTS error"); } switch(cflag & CBAUD) { case B0: /* handled below */ break; case B300: urb_value = BELKIN_SA_BAUD(300); break; case B600: urb_value = BELKIN_SA_BAUD(600); break; case B1200: urb_value = BELKIN_SA_BAUD(1200); break; case B2400: urb_value = BELKIN_SA_BAUD(2400); break; case B4800: urb_value = BELKIN_SA_BAUD(4800); break; case B9600: urb_value = BELKIN_SA_BAUD(9600); break; case B19200: urb_value = BELKIN_SA_BAUD(19200); break; case B38400: urb_value = BELKIN_SA_BAUD(38400); break; case B57600: urb_value = BELKIN_SA_BAUD(57600); break; case B115200: urb_value = BELKIN_SA_BAUD(115200); break; case B230400: urb_value = BELKIN_SA_BAUD(230400); break; default: err("BELKIN USB Serial Adapter: unsupported baudrate request, using default of 9600"); urb_value = BELKIN_SA_BAUD(9600); break; } if ((cflag & CBAUD) != B0 ) { if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) err("Set baudrate error"); } else { /* Disable flow control */ if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0) err("Disable flowcontrol error"); /* Drop RTS and DTR */ priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0) err("DTR LOW error"); if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0) err("RTS LOW error"); } } /* set the parity */ if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) { if (cflag & PARENB) urb_value = (cflag & PARODD) ? BELKIN_SA_PARITY_ODD : BELKIN_SA_PARITY_EVEN; else urb_value = BELKIN_SA_PARITY_NONE; if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0) err("Set parity error"); } /* set the number of data bits */ if( (cflag&CSIZE) != (old_cflag&CSIZE) ) { switch (cflag & CSIZE) { case CS5: urb_value = BELKIN_SA_DATA_BITS(5); break; case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break; case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break; case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break; default: err("CSIZE was not CS5-CS8, using default of 8"); urb_value = BELKIN_SA_DATA_BITS(8); break; } if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0) err("Set data bits error"); } /* set the number of stop bits */ if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) { urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2) : BELKIN_SA_STOP_BITS(1); if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST, urb_value) < 0) err("Set stop bits error"); } /* Set flow control */ if( (iflag&IXOFF) != (old_iflag&IXOFF) || (iflag&IXON) != (old_iflag&IXON) || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) { urb_value = 0; if ((iflag & IXOFF) || (iflag & IXON)) urb_value |= (BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON); else urb_value &= ~(BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON); if (cflag & CRTSCTS) urb_value |= (BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS); else urb_value &= ~(BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS); if (priv->bad_flow_control) urb_value &= ~(BELKIN_SA_FLOW_IRTS); if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0) err("Set flow control error"); }} /* belkin_sa_set_termios */static void belkin_sa_break_ctl( struct usb_serial_port *port, int break_state ){ struct usb_serial *serial = port->serial; if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0) err("Set break_ctl %d", break_state);}static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg){ struct usb_serial *serial = port->serial; __u16 urb_value; /* Will hold the new flags */ struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private; int ret, mask; /* Based on code from acm.c and others */ switch (cmd) { case TIOCMGET: return put_user(priv->control_state, (unsigned long *) arg); break; case TIOCMSET: /* Turns on and off the lines as specified by the mask */ case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */ case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */ if (get_user(mask, (unsigned long *) arg)) return -EFAULT; if ((cmd == TIOCMSET) || (mask & TIOCM_RTS)) { /* RTS needs set */ urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_RTS)) || (cmd == TIOCMBIS) ? 1 : 0; if (urb_value) priv->control_state |= TIOCM_RTS; else priv->control_state &= ~TIOCM_RTS; if ((ret = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, urb_value)) < 0) { err("Set RTS error %d", ret); return(ret); } } if ((cmd == TIOCMSET) || (mask & TIOCM_DTR)) { /* DTR needs set */ urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_DTR)) || (cmd == TIOCMBIS) ? 1 : 0; if (urb_value) priv->control_state |= TIOCM_DTR; else priv->control_state &= ~TIOCM_DTR; if ((ret = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, urb_value)) < 0) { err("Set DTR error %d", ret); return(ret); } } break; case TIOCMIWAIT: /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ /* TODO */ return( 0 ); case TIOCGICOUNT: /* return count of modemline transitions */ /* TODO */ return 0; default: dbg("belkin_sa_ioctl arg not supported - 0x%04x",cmd); return(-ENOIOCTLCMD); break; } return 0;} /* belkin_sa_ioctl */static int __init belkin_sa_init (void){ usb_serial_register (&belkin_device); info(DRIVER_DESC " " DRIVER_VERSION); return 0;}static void __exit belkin_sa_exit (void){ usb_serial_deregister (&belkin_device);}module_init (belkin_sa_init);module_exit (belkin_sa_exit);MODULE_AUTHOR( DRIVER_AUTHOR );MODULE_DESCRIPTION( DRIVER_DESC );MODULE_LICENSE("GPL");MODULE_PARM(debug, "i");MODULE_PARM_DESC(debug, "Debug enabled or not");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -