// SPDX-License-Identifier: GPL-2.0+ /* * Belkin USB Serial Adapter Driver * * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) * * This program is largely derived from work by the linux-usb group * and associated source files. Please see the usb/serial files for * individual credits and copyrights. * * See Documentation/usb/usb-serial.rst for more information on using this * driver * * TODO: * -- Add true modem control line query capability. Currently we track the * states reported by the interrupt and the states we request. * -- Add support for flush commands
*/
/* * *************************************************************************** * Belkin USB Serial Adapter F5U103 specific driver functions * ***************************************************************************
*/
staticvoid belkin_sa_read_int_callback(struct urb *urb)
{ struct usb_serial_port *port = urb->context; struct belkin_sa_private *priv; unsignedchar *data = urb->transfer_buffer; int retval; int status = urb->status; unsignedlong flags;
switch (status) { case 0: /* success */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */
dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
__func__, status); return; default:
dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
__func__, status); gotoexit;
}
/* get a local copy of the current port settings */
spin_lock_irqsave(&priv->lock, flags);
control_state = priv->control_state;
bad_flow_control = priv->bad_flow_control;
spin_unlock_irqrestore(&priv->lock, flags);
/* Set the baud rate */ if ((cflag & CBAUD) != (old_cflag & CBAUD)) { /* reassert DTR and (maybe) RTS on transition from B0 */ if ((old_cflag & CBAUD) == B0) {
control_state |= (TIOCM_DTR|TIOCM_RTS); if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
dev_err(&port->dev, "Set DTR error\n"); /* don't set RTS if using hardware flow control */ if (!(old_cflag & CRTSCTS)) if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST
, 1) < 0)
dev_err(&port->dev, "Set RTS error\n");
}
}
baud = tty_get_baud_rate(tty); if (baud) {
urb_value = BELKIN_SA_BAUD(baud); /* Clip to maximum speed */ if (urb_value == 0)
urb_value = 1; /* Turn it back into a resulting real baud rate */
baud = BELKIN_SA_BAUD(urb_value);
/* Report the actual baud rate back to the caller */
tty_encode_baud_rate(tty, baud, baud); if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0)
dev_err(&port->dev, "Set baudrate error\n");
} else { /* Disable flow control */ if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST,
BELKIN_SA_FLOW_NONE) < 0)
dev_err(&port->dev, "Disable flowcontrol error\n"); /* Drop RTS and DTR */
control_state &= ~(TIOCM_DTR | TIOCM_RTS); if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
dev_err(&port->dev, "DTR LOW error\n"); if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
dev_err(&port->dev, "RTS LOW error\n");
}
/* set the parity */ if ((cflag ^ 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)
dev_err(&port->dev, "Set parity error\n");
}
/* set the number of data bits */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
urb_value = BELKIN_SA_DATA_BITS(tty_get_char_size(cflag)); if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0)
dev_err(&port->dev, "Set data bits error\n");
}
/* 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)
dev_err(&port->dev, "Set stop bits error\n");
}
if (bad_flow_control)
urb_value &= ~(BELKIN_SA_FLOW_IRTS);
if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0)
dev_err(&port->dev, "Set flow control error\n");
}
/* save off the modified port settings */
spin_lock_irqsave(&priv->lock, flags);
priv->control_state = control_state;
spin_unlock_irqrestore(&priv->lock, flags);
}
staticint belkin_sa_break_ctl(struct tty_struct *tty, int break_state)
{ struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; int ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.