patch-2.4.0-test3 linux/drivers/usb/serial/whiteheat.c
Next file: linux/drivers/usb/storage/Makefile
Previous file: linux/drivers/usb/serial/visor.c
Back to the patch index
Back to the overall index
- Lines: 365
- Date:
Wed Jul 5 11:16:41 2000
- Orig file:
v2.4.0-test2/linux/drivers/usb/serial/whiteheat.c
- Orig date:
Tue May 23 15:31:35 2000
diff -u --recursive --new-file v2.4.0-test2/linux/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c
@@ -11,6 +11,11 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * (07/04/2000) gkh
+ * Added support for port settings. Baud rate can now be changed. Line signals
+ * are not transferred to and from the tty layer yet, but things seem to be
+ * working well now.
+ *
* (05/04/2000) gkh
* First cut at open and close commands. Data can flow through the ports at
* default speeds now.
@@ -55,6 +60,7 @@
/* function prototypes for the Connect Tech WhiteHEAT serial converter */
static int whiteheat_open (struct usb_serial_port *port, struct file *filp);
static void whiteheat_close (struct usb_serial_port *port, struct file *filp);
+static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
static void whiteheat_set_termios (struct usb_serial_port *port, struct termios * old);
static void whiteheat_throttle (struct usb_serial_port *port);
static void whiteheat_unthrottle (struct usb_serial_port *port);
@@ -93,6 +99,7 @@
close: whiteheat_close,
throttle: whiteheat_throttle,
unthrottle: whiteheat_unthrottle,
+ ioctl: whiteheat_ioctl,
set_termios: whiteheat_set_termios,
shutdown: whiteheat_shutdown,
};
@@ -103,6 +110,13 @@
};
+/* local function prototypes */
+static inline void set_rts (struct usb_serial_port *port, unsigned char rts);
+static inline void set_dtr (struct usb_serial_port *port, unsigned char dtr);
+static inline void set_break (struct usb_serial_port *port, unsigned char brk);
+
+
+
#define COMMAND_PORT 4
#define COMMAND_TIMEOUT (2*HZ) /* 2 second timeout for a command */
@@ -116,7 +130,7 @@
int i;
#endif
- dbg ("command_port_write_callback");
+ dbg (__FUNCTION__);
if (urb->status) {
dbg ("nonzero urb status: %d", urb->status);
@@ -125,7 +139,7 @@
#ifdef DEBUG
if (urb->actual_length) {
- printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length);
+ printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", urb->actual_length);
for (i = 0; i < urb->actual_length; ++i) {
printk ("%.2x ", data[i]);
}
@@ -145,16 +159,16 @@
int i;
#endif
- dbg ("command_port_write_callback");
+ dbg (__FUNCTION__);
if (urb->status) {
- dbg ("nonzero urb status: %d", urb->status);
+ dbg (__FUNCTION__ " - nonzero urb status: %d", urb->status);
return;
}
#ifdef DEBUG
if (urb->actual_length) {
- printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length);
+ printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", urb->actual_length);
for (i = 0; i < urb->actual_length; ++i) {
printk ("%.2x ", data[i]);
}
@@ -179,7 +193,7 @@
int timeout;
__u8 *transfer_buffer;
- dbg("whiteheat_send_cmd: %d", command);
+ dbg(__FUNCTION__" - command %d", command);
port = &serial->port[COMMAND_PORT];
info = (struct whiteheat_private *)port->private;
@@ -189,8 +203,10 @@
transfer_buffer[0] = command;
memcpy (&transfer_buffer[1], data, datasize);
port->write_urb->transfer_buffer_length = datasize + 1;
- if (usb_submit_urb (port->write_urb))
- dbg ("submit urb failed");
+ if (usb_submit_urb (port->write_urb)) {
+ dbg (__FUNCTION__" - submit urb failed");
+ return -1;
+ }
/* wait for the command to complete */
timeout = COMMAND_TIMEOUT;
@@ -199,6 +215,7 @@
}
if (info->command_finished == FALSE) {
+ dbg (__FUNCTION__ " - command timed out.");
return -1;
}
@@ -212,10 +229,10 @@
struct usb_serial_port *command_port;
struct whiteheat_private *info;
- dbg("whiteheat_open port %d", port->number);
+ dbg(__FUNCTION__" - port %d", port->number);
if (port->active) {
- dbg ("device already open");
+ dbg (__FUNCTION__ " - device already open");
return -EINVAL;
}
port->active = 1;
@@ -225,7 +242,7 @@
if (command_port->private == NULL) {
info = (struct whiteheat_private *)kmalloc (sizeof(struct whiteheat_private), GFP_KERNEL);
if (info == NULL) {
- err("out of memory");
+ err(__FUNCTION__ " - out of memory");
return -ENOMEM;
}
@@ -238,7 +255,7 @@
/* Start reading from the device */
if (usb_submit_urb(port->read_urb))
- dbg("usb_submit_urb(read bulk) failed");
+ dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed");
/* send an open port command */
open_command.port = port->number - port->minor;
@@ -247,9 +264,9 @@
/* Need to do device specific setup here (control lines, baud rate, etc.) */
/* FIXME!!! */
- dbg("whiteheat_open exit");
+ dbg(__FUNCTION__ " - exit");
- return (0);
+ return 0;
}
@@ -257,7 +274,7 @@
{
struct whiteheat_min_set close_command;
- dbg("whiteheat_close port %d", port->number);
+ dbg(__FUNCTION__ " - port %d", port->number);
/* send a close command to the port */
close_command.port = port->number - port->minor;
@@ -273,30 +290,102 @@
}
+static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+{
+ dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd);
+
+ return -ENOIOCTLCMD;
+}
+
+
static void whiteheat_set_termios (struct usb_serial_port *port, struct termios *old_termios)
{
unsigned int cflag = port->tty->termios->c_cflag;
+ struct whiteheat_port_settings port_settings;
- dbg("whiteheat_set_termios port %d", port->number);
+ dbg(__FUNCTION__ " -port %d", port->number);
/* 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("nothing to change...");
+ dbg(__FUNCTION__ " - nothing to change...");
return;
}
}
- /* do the parsing of the cflag to see what to set the line to */
- /* FIXME!! */
+ if ((!port->tty) || (!port->tty->termios)) {
+ dbg(__FUNCTION__" - no tty structures");
+ return;
+ }
+
+ /* get the byte size */
+ switch (cflag & CSIZE) {
+ case CS5: port_settings.bits = 5; break;
+ case CS6: port_settings.bits = 6; break;
+ case CS7: port_settings.bits = 7; break;
+ default:
+ case CS8: port_settings.bits = 8; break;
+ }
+ dbg(__FUNCTION__ " - data bits = %d", port_settings.bits);
+
+ /* determine the parity */
+ if (cflag & PARENB)
+ if (cflag & PARODD)
+ port_settings.parity = 'o';
+ else
+ port_settings.parity = 'e';
+ else
+ port_settings.parity = 'n';
+ dbg(__FUNCTION__ " - parity = %c", port_settings.parity);
+
+ /* figure out the stop bits requested */
+ if (cflag & CSTOPB)
+ port_settings.stop = 2;
+ else
+ port_settings.stop = 1;
+ dbg(__FUNCTION__ " - stop bits = %d", port_settings.stop);
+
+ /* figure out the flow control settings */
+ if (cflag & CRTSCTS)
+ port_settings.hflow = (WHITEHEAT_CTS_FLOW | WHITEHEAT_RTS_FLOW);
+ else
+ port_settings.hflow = 0;
+ dbg(__FUNCTION__ " - hardware flow control = %s %s %s %s",
+ (port_settings.hflow | WHITEHEAT_CTS_FLOW) ? "CTS" : "",
+ (port_settings.hflow | WHITEHEAT_RTS_FLOW) ? "RTS" : "",
+ (port_settings.hflow | WHITEHEAT_DSR_FLOW) ? "DSR" : "",
+ (port_settings.hflow | WHITEHEAT_DTR_FLOW) ? "DTR" : "");
+
+ /* determine software flow control */
+ if (I_IXOFF(port->tty))
+ port_settings.sflow = 'b';
+ else
+ port_settings.sflow = 'n';
+ dbg(__FUNCTION__ " - software flow control = %c", port_settings.sflow);
+
+ port_settings.xon = START_CHAR(port->tty);
+ port_settings.xoff = STOP_CHAR(port->tty);
+ dbg(__FUNCTION__ " - XON = %2x, XOFF = %2x", port_settings.xon, port_settings.xoff);
+
+ /* get the baud rate wanted */
+ port_settings.baud = tty_get_baud_rate(port->tty);
+ dbg(__FUNCTION__ " - baud rate = %d", port_settings.baud);
+
+ /* handle any settings that aren't specified in the tty structure */
+ port_settings.lloop = 0;
+
+ /* now send the message to the device */
+ whiteheat_send_cmd (port->serial, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
+
return;
}
+
static void whiteheat_throttle (struct usb_serial_port *port)
{
- dbg("whiteheat_throttle port %d", port->number);
+ dbg(__FUNCTION__" - port %d", port->number);
/* Change the control signals */
/* FIXME!!! */
@@ -307,7 +396,7 @@
static void whiteheat_unthrottle (struct usb_serial_port *port)
{
- dbg("whiteheat_unthrottle port %d", port->number);
+ dbg(__FUNCTION__" - port %d", port->number);
/* Change the control signals */
/* FIXME!!! */
@@ -334,7 +423,7 @@
int response;
const struct whiteheat_hex_record *record;
- dbg("whiteheat_startup");
+ dbg(__FUNCTION__);
response = ezusb_set_reset (serial, 1);
@@ -343,7 +432,7 @@
response = ezusb_writememory (serial, record->address,
(unsigned char *)record->data, record->data_size, 0xa0);
if (response < 0) {
- err("ezusb_writememory failed for loader (%d %04X %p %d)",
+ err(__FUNCTION__ " - ezusb_writememory failed for loader (%d %04X %p %d)",
response, record->address, record->data, record->data_size);
break;
}
@@ -360,7 +449,7 @@
response = ezusb_writememory (serial, record->address,
(unsigned char *)record->data, record->data_size, 0xa3);
if (response < 0) {
- err("ezusb_writememory failed for first firmware step (%d %04X %p %d)",
+ err(__FUNCTION__ " - ezusb_writememory failed for first firmware step (%d %04X %p %d)",
response, record->address, record->data, record->data_size);
break;
}
@@ -374,7 +463,7 @@
response = ezusb_writememory (serial, record->address,
(unsigned char *)record->data, record->data_size, 0xa0);
if (response < 0) {
- err("ezusb_writememory failed for second firmware step (%d %04X %p %d)",
+ err(__FUNCTION__" - ezusb_writememory failed for second firmware step (%d %04X %p %d)",
response, record->address, record->data, record->data_size);
break;
}
@@ -392,9 +481,9 @@
{
struct usb_serial_port *command_port;
- dbg("whiteheat_shutdown");
+ dbg(__FUNCTION__);
- /* set up some stuff for our command port */
+ /* free up our private data for our command port */
command_port = &serial->port[COMMAND_PORT];
if (command_port->private != NULL) {
kfree (command_port->private);
@@ -402,5 +491,37 @@
}
return;
+}
+
+
+
+
+static void set_command (struct usb_serial_port *port, unsigned char state, unsigned char command)
+{
+ struct whiteheat_rdb_set rdb_command;
+
+ /* send a set rts command to the port */
+ rdb_command.port = port->number - port->minor;
+ rdb_command.state = state;
+
+ whiteheat_send_cmd (port->serial, command, (__u8 *)&rdb_command, sizeof(rdb_command));
+}
+
+
+static inline void set_rts (struct usb_serial_port *port, unsigned char rts)
+{
+ set_command (port, rts, WHITEHEAT_SET_RTS);
+}
+
+
+static inline void set_dtr (struct usb_serial_port *port, unsigned char dtr)
+{
+ set_command (port, dtr, WHITEHEAT_SET_DTR);
+}
+
+
+static inline void set_break (struct usb_serial_port *port, unsigned char brk)
+{
+ set_command (port, brk, WHITEHEAT_SET_BREAK);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)