diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-02 02:36:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-02 02:36:47 +0000 |
commit | 8624512aa908741ba2795200133eae0d7f4557ea (patch) | |
tree | d5d3036fccf2604f4c98dedc11e8adb929d6b52e /drivers/usb/usb-serial.c | |
parent | 7b8f5d6f1d45d9f9de1d26e7d3c32aa5af11b488 (diff) |
Merge with 2.3.48.
Diffstat (limited to 'drivers/usb/usb-serial.c')
-rw-r--r-- | drivers/usb/usb-serial.c | 590 |
1 files changed, 554 insertions, 36 deletions
diff --git a/drivers/usb/usb-serial.c b/drivers/usb/usb-serial.c index f87600e83..6b9615e72 100644 --- a/drivers/usb/usb-serial.c +++ b/drivers/usb/usb-serial.c @@ -14,6 +14,17 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (02/21/2000) gkh + * Made it so that any serial devices only have to specify which functions + * they want to overload from the generic function calls (great, + * inheritance in C, in a driver, just what I wanted...) + * Added support for set_termios and ioctl function calls. No drivers take + * advantage of this yet. + * Removed the #ifdef MODULE, now there is no module specific code. + * Cleaned up a few comments in usb-serial.h that were wrong (thanks again + * to Miles Lott). + * Small fix to get_free_serial. + * * (02/14/2000) gkh * Removed the Belkin and Peracom functionality from the driver due to * the lack of support from the vendor, and me not wanting people to @@ -169,6 +180,19 @@ #include "usb-serial.h" +/* parity check flag */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + +/* local function prototypes */ +static int serial_open (struct tty_struct *tty, struct file * filp); +static void serial_close (struct tty_struct *tty, struct file * filp); +static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count); +static int serial_write_room (struct tty_struct *tty); +static int serial_chars_in_buffer (struct tty_struct *tty); +static void serial_throttle (struct tty_struct * tty); +static void serial_unthrottle (struct tty_struct * tty); +static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg); +static void serial_set_termios (struct tty_struct *tty, struct termios * old); static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum); static void usb_serial_disconnect(struct usb_device *dev, void *ptr); @@ -224,7 +248,7 @@ static struct usb_serial *get_free_serial (int num_ports, int *minor) continue; good_spot = 1; - for (j = 0; j < num_ports-1; ++j) + for (j = 1; j <= num_ports-1; ++j) if (serial_table[i+j]) good_spot = 0; if (good_spot == 0) @@ -328,12 +352,12 @@ static int serial_open (struct tty_struct *tty, struct file * filp) tty->driver_data = serial; serial->tty = tty; - /* pass on to the driver specific version of this function */ + /* pass on to the driver specific version of this function if it is available */ if (serial->type->open) { return (serial->type->open(tty, filp)); + } else { + return (generic_serial_open(tty, filp)); } - - return (0); } @@ -363,9 +387,11 @@ static void serial_close(struct tty_struct *tty, struct file * filp) return; } - /* pass on to the driver specific version of this function */ + /* pass on to the driver specific version of this function if it is available */ if (serial->type->close) { serial->type->close(tty, filp); + } else { + generic_serial_close(tty, filp); } } @@ -391,13 +417,12 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned return (-EINVAL); } - /* pass on to the driver specific version of this function */ + /* pass on to the driver specific version of this function if it is available */ if (serial->type->write) { return (serial->type->write(tty, from_user, buf, count)); + } else { + return (generic_serial_write(tty, from_user, buf, count)); } - - /* no specific driver, so return that we didn't write anything */ - return (0); } @@ -422,12 +447,12 @@ static int serial_write_room (struct tty_struct *tty) return (-EINVAL); } - /* pass on to the driver specific version of this function */ + /* pass on to the driver specific version of this function if it is available */ if (serial->type->write_room) { return (serial->type->write_room(tty)); + } else { + return (generic_write_room(tty)); } - - return (0); } @@ -452,12 +477,12 @@ static int serial_chars_in_buffer (struct tty_struct *tty) return (-EINVAL); } - /* pass on to the driver specific version of this function */ + /* pass on to the driver specific version of this function if it is available */ if (serial->type->chars_in_buffer) { return (serial->type->chars_in_buffer(tty)); + } else { + return (generic_chars_in_buffer(tty)); } - - return (0); } @@ -485,6 +510,8 @@ static void serial_throttle (struct tty_struct * tty) /* pass on to the driver specific version of this function */ if (serial->type->throttle) { serial->type->throttle(tty); + } else { + generic_throttle(tty); } return; @@ -515,12 +542,86 @@ static void serial_unthrottle (struct tty_struct * tty) /* pass on to the driver specific version of this function */ if (serial->type->unthrottle) { serial->type->unthrottle(tty); + } else { + generic_unthrottle(tty); } return; } +static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) +{ + struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + int port; + + dbg("serial_ioctl"); + + if (!serial) { + dbg("serial == NULL!"); + return -ENODEV; + } + + port = MINOR(tty->device) - serial->minor; + + dbg("serial_ioctl port %d", port); + + /* do some sanity checking that we really have a device present */ + if (!serial->type) { + dbg("serial->type == NULL!"); + return -ENODEV; + } + if (!serial->active[port]) { + dbg ("device not open"); + return -ENODEV; + } + + /* pass on to the driver specific version of this function if it is available */ + if (serial->type->ioctl) { + return (serial->type->ioctl(tty, file, cmd, arg)); + } else { + return (generic_ioctl (tty, file, cmd, arg)); + } +} + + +static void serial_set_termios (struct tty_struct *tty, struct termios * old) +{ + struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + int port; + + dbg("serial_set_termios"); + + if (!serial) { + dbg("serial == NULL!"); + return; + } + + port = MINOR(tty->device) - serial->minor; + + dbg("serial_set_termios port %d", port); + + /* do some sanity checking that we really have a device present */ + if (!serial->type) { + dbg("serial->type == NULL!"); + return; + } + if (!serial->active[port]) { + dbg ("device not open"); + return; + } + + /* pass on to the driver specific version of this function if it is available */ + if (serial->type->set_termios) { + serial->type->set_termios(tty, old); + } else { + generic_set_termios (tty, old); + } + + return; +} + + #ifdef CONFIG_USB_SERIAL_WHITEHEAT /***************************************************************************** * Connect Tech's White Heat specific driver functions @@ -566,6 +667,29 @@ static void whiteheat_serial_close(struct tty_struct *tty, struct file * filp) } +static void whiteheat_set_termios (struct tty_struct *tty, struct termios *old_termios) +{ + struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + int port = MINOR(tty->device) - serial->minor; + unsigned int cflag = tty->termios->c_cflag; + + dbg("whiteheat_set_termios port %d", port); + + /* check that they really want us to change something */ + if (old_termios) { + if ((cflag == old_termios->c_cflag) && + (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { + dbg("nothing to change..."); + return; + } + } + + /* do the parsing of the cflag to see what to set the line to */ + /* FIXME!! */ + + return; +} + static void whiteheat_throttle (struct tty_struct * tty) { struct usb_serial *serial = (struct usb_serial *) tty->driver_data; @@ -813,25 +937,96 @@ static int visor_startup (struct usb_serial *serial) /****************************************************************************** * FTDI SIO Serial Converter specific driver functions ******************************************************************************/ + +/* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */ +/* Thanx to FTDI for so kindly providing details of the protocol required */ +/* to talk to the device */ + +#include "ftdi_sio.h" + static int ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp) { struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + char buf[1]; /* Needed for the usb_control_msg I think */ int port = MINOR(tty->device) - serial->minor; - dbg("ftdi_serial_open port %d", port); + dbg("ftdi_sio_serial_open port %d", port); if (serial->active[port]) { dbg ("device already open"); return -EINVAL; } serial->active[port] = 1; - + + usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, + FTDI_SIO_RESET_SIO, + 0, buf, 0, HZ * 5); + + /* FIXME - Should I really purge the buffers? */ + usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, + FTDI_SIO_RESET_PURGE_RX, + 0, buf, 0, HZ * 5); + + usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, + FTDI_SIO_RESET_PURGE_TX, + 0, buf, 0, HZ * 5); + + + /* As per usb_serial_init s/be CS8, B9600, 1 STOP BIT */ + if ( usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_BAUDRATE_REQUEST, + FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, + ftdi_sio_b9600, 0, + buf, 0, HZ * 5) < 0){ + dbg("Error from baudrate urb"); + return(-EINVAL); + } + + if ( usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_DATA_REQUEST, + FTDI_SIO_SET_DATA_REQUEST_TYPE, + 8 | FTDI_SIO_SET_DATA_PARITY_NONE | + FTDI_SIO_SET_DATA_STOP_BITS_1, 0, + buf, 0, HZ * 5) < 0){ + dbg("Error from cs8/noparity/1 stopbit urb"); + return(-EINVAL); + } + + /* Disable flow control */ + if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_FLOW_CTRL_REQUEST, + FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, + 0, 0, + buf, 0, HZ * 5) < 0) { + dbg("error from flowcontrol urb"); + return(-EINVAL); + } + + /* Turn on RTS and DTR since we are not flow controlling*/ + /* FIXME - check for correct behaviour clocal vs non clocal */ + /* FIXME - might be able to do both simultaneously */ + if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_MODEM_CTRL_REQUEST, + FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, + (unsigned)FTDI_SIO_SET_DTR_HIGH, 0, + buf, 0, HZ * 5) < 0) { + dbg("Error from DTR HIGH urb"); + } + if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_MODEM_CTRL_REQUEST, + FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, + (unsigned)FTDI_SIO_SET_RTS_HIGH, 0, + buf, 0, HZ * 5) < 0) { + dbg("Error from RTS HIGH urb"); + } + /*Start reading from the device*/ if (usb_submit_urb(&serial->read_urb[port])) dbg("usb_submit_urb(read bulk) failed"); - /* Need to do device specific setup here (control lines, baud rate, etc.) */ - /* FIXME!!! */ return (0); } @@ -840,13 +1035,29 @@ static int ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp) static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp) { struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + char buf[1]; int port = MINOR(tty->device) - serial->minor; - dbg("ftdi_serial_close port %d", port); - - /* Need to change the control lines here */ - /* FIXME */ + dbg("ftdi_sio_serial_close port %d", port); + /* FIXME - might be able to do both simultaneously */ + if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_MODEM_CTRL_REQUEST, + FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, + (unsigned)FTDI_SIO_SET_DTR_LOW, 0, + buf, 0, HZ * 5) < 0) { + dbg("Error from DTR LOW urb"); + } + if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_MODEM_CTRL_REQUEST, + FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, + (unsigned)FTDI_SIO_SET_RTS_LOW, 0, + buf, 0, HZ * 5) < 0) { + dbg("Error from RTS LOW urb"); + } + + /* FIXME Should I flush the device here? - not doing it for now */ + /* shutdown our bulk reads and writes */ usb_unlink_urb (&serial->write_urb[port]); usb_unlink_urb (&serial->read_urb[port]); @@ -854,6 +1065,290 @@ static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp) } + +/* The ftdi_sio requires the first byte to have: + B0 1 + B1 0 + B2..7 length of message excluding byte 0 +*/ +static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + int port = MINOR(tty->device) - serial->minor; + const int data_offset = 1; + + dbg("ftdi_sio_serial_write port %d, %d bytes", port, count); + + if (count == 0) { + dbg("write request of 0 bytes"); + return (0); + } + + /* only do something if we have a bulk out endpoint */ + if (serial->num_bulk_out) { + unsigned char *first_byte = serial->write_urb[port].transfer_buffer; + + if (serial->write_urb[port].status == -EINPROGRESS) { + dbg ("already writing"); + return (0); + } + + count += data_offset; + count = (count > serial->bulk_out_size[port]) ? + serial->bulk_out_size[port] : count; + + + /* Copy in the data to send */ + if (from_user) { + copy_from_user(serial->write_urb[port].transfer_buffer + data_offset , + buf, count - data_offset ); + } + else { + memcpy(serial->write_urb[port].transfer_buffer + data_offset, + buf, count - data_offset ); + } + + /* Write the control byte at the front of the packet*/ + first_byte = serial->write_urb[port].transfer_buffer; + *first_byte = 1 | ((count-data_offset) << 2) ; + +#ifdef DEBUG + dbg("Bytes: %d, Control Byte: 0o%03o",count, first_byte[0]); + + if (count) { + int i; + printk (KERN_DEBUG __FILE__ ": data written - length = %d, data = ", count); + for (i = 0; i < count; ++i) { + printk ("0x%02x ", first_byte[i]); + if (first_byte[i] > ' ' && first_byte[i] < '~') { + printk("%c ", first_byte[i]); + } else { + printk(" "); + } + } + + + printk ("\n"); + } + +#endif + + + /* send the data out the bulk port */ + serial->write_urb[port].transfer_buffer_length = count; + + if (usb_submit_urb(&serial->write_urb[port])) + dbg("usb_submit_urb(write bulk) failed"); + + dbg("write returning: %d",count - data_offset); + return (count - data_offset); + } + + /* no bulk out, so return 0 bytes written */ + return (0); +} + + +static void ftdi_sio_read_bulk_callback (struct urb *urb) +{ /* ftdi_sio_serial_buld_callback */ + struct usb_serial *serial = (struct usb_serial *)urb->context; + struct tty_struct *tty = serial->tty; + unsigned char *data = urb->transfer_buffer; + const int data_offset = 2; + int i; + + dbg("ftdi_sio_read_bulk_callback"); + + if (urb->status) { + dbg("nonzero read bulk status received: %d", urb->status); + return; + } + +#ifdef DEBUG + if (urb->actual_length > 2) { + printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length); + for (i = 0; i < urb->actual_length; ++i) { + printk ("0x%.2x ", data[i]); + if (data[i] > ' ' && data[i] < '~') { + printk("%c ", data[i]); + } else { + printk(" "); + } + } + printk ("\n"); + } +#endif + + + if (urb->actual_length > data_offset) { + for (i = data_offset ; i < urb->actual_length ; ++i) { + tty_insert_flip_char(tty, data[i], 0); + } + tty_flip_buffer_push(tty); + } + + /* Continue trying to always read */ + if (usb_submit_urb(urb)) + dbg("failed resubmitting read urb"); + + return; +} /* ftdi_sio_serial_read_bulk_callback */ + +static void ftdi_sio_set_termios (struct tty_struct *tty, struct termios *old_termios) +{ + struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + int port = MINOR(tty->device) - serial->minor; + unsigned int cflag = tty->termios->c_cflag; + __u16 urb_value; /* Will hold the new flags */ + char buf[1]; /* Perhaps I should dynamically alloc this? */ + dbg("ftdi_sio_set_termios port %d", port); + + /* FIXME - we should keep the old termios really */ + /* FIXME -For this cut I don't care if the line is really changing or + not - so just do the change regardless */ + + /* Set number of data bits, parity, stop bits */ + + urb_value = 0; + urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : + FTDI_SIO_SET_DATA_STOP_BITS_1); + urb_value |= (cflag & PARENB ? + (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : + FTDI_SIO_SET_DATA_PARITY_EVEN) : + FTDI_SIO_SET_DATA_PARITY_NONE); + if (cflag & CSIZE) { + switch (cflag & CSIZE) { + case CS5: urb_value |= 5; dbg("Setting CS5"); break; + case CS6: urb_value |= 6; dbg("Setting CS6"); break; + case CS7: urb_value |= 7; dbg("Setting CS7"); break; + case CS8: urb_value |= 8; dbg("Setting CS8"); break; + default: + dbg("CSIZE was set but not CS5-CS8"); + } + } + if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_DATA_REQUEST, + FTDI_SIO_SET_DATA_REQUEST_TYPE, + urb_value , 0, + buf, 0, 100) < 0) { + dbg("FAILED to set databits/stopbits/parity"); + } + + /* Now do the baudrate */ + /* FIXME - should drop lines on B0 */ + /* FIXME Should also handle CLOCAL here */ + + switch(cflag & CBAUD){ + case B300: urb_value = ftdi_sio_b300; dbg("Set to 300"); break; + case B600: urb_value = ftdi_sio_b600; dbg("Set to 600") ; break; + case B1200: urb_value = ftdi_sio_b1200; dbg("Set to 1200") ; break; + case B2400: urb_value = ftdi_sio_b2400; dbg("Set to 2400") ; break; + case B4800: urb_value = ftdi_sio_b4800; dbg("Set to 4800") ; break; + case B9600: urb_value = ftdi_sio_b9600; dbg("Set to 9600") ; break; + case B19200: urb_value = ftdi_sio_b19200; dbg("Set to 19200") ; break; + case B38400: urb_value = ftdi_sio_b38400; dbg("Set to 38400") ; break; + case B57600: urb_value = ftdi_sio_b57600; dbg("Set to 57600") ; break; + case B115200: urb_value = ftdi_sio_b115200; dbg("Set to 115200") ; break; + default: dbg("FTDI_SIO does not support the baudrate requested"); + /* FIXME - how to return an error for this? */ break; + } + /* Send the URB */ + if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_BAUDRATE_REQUEST, + FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, + urb_value, 0, + buf, 0, 100) < 0) { + dbg("urb failed to set baurdrate"); + } + return; +} + +/*FIXME - the beginnings of this implementation - not even hooked into the driver yet */ +static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) +{ + struct usb_serial *serial = (struct usb_serial *) tty->driver_data; + int port = MINOR(tty->device) - serial->minor; + __u16 urb_value=0; /* Will hold the new flags */ + char buf[1]; + int ret, mask; + dbg("ftdi_sio_ioctl port %d", port); + + /* Based on code from acm.c */ + switch (cmd) { + + case TIOCMGET: + /* Request the status from the device */ + if ((ret = usb_control_msg(serial->dev, + usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_GET_MODEM_STATUS_REQUEST, + FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, + 0, 0, + buf, 1, HZ * 5)) < 0 ) { + dbg("Get not get modem status of device"); + return(ret); + } + + return put_user((buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | + (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | + (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | + (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0), + (unsigned long *) arg); + break; + + case TIOCMSET: + case TIOCMBIS: + case TIOCMBIC: + if ((ret = get_user(mask, (unsigned long *) arg))) return ret; + + /* FIXME Need to remember if we have set DTR or RTS since we + can't ask the device */ + /* FIXME - also need to find the meaning of TIOCMBIS/BIC/SET */ + if (mask & TIOCM_DTR) { + switch(cmd) { + case TIOCMSET: + urb_value = FTDI_SIO_SET_DTR_HIGH | FTDI_SIO_SET_RTS_LOW; + break; + + case TIOCMBIS: + /* Will leave RTS alone and set DTR */ + urb_value = FTDI_SIO_SET_DTR_HIGH; + break; + + case TIOCMBIC: + urb_value = FTDI_SIO_SET_DTR_LOW; + break; + } + } + + if (mask & TIOCM_RTS) { + switch(cmd) { + case TIOCMSET: + urb_value = FTDI_SIO_SET_DTR_LOW | FTDI_SIO_SET_RTS_HIGH; + break; + + case TIOCMBIS: + /* Will leave DTR and set RTS */ + urb_value = FTDI_SIO_SET_RTS_HIGH; + break; + + case TIOCMBIC: + /* Will unset RTS */ + urb_value = FTDI_SIO_SET_RTS_LOW; + break; + } + } + + + return(usb_control_msg(serial->dev, + usb_sndctrlpipe(serial->dev, 0), + FTDI_SIO_SET_MODEM_CTRL_REQUEST, + FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, + urb_value , 0, + buf, 0, HZ * 5)); + } +} + #endif /* CONFIG_USB_SERIAL_FTDI_SIO */ @@ -1041,6 +1536,34 @@ static int generic_chars_in_buffer (struct tty_struct *tty) } +static void generic_throttle (struct tty_struct *tty) +{ + /* do nothing for the generic device */ + return; +} + + +static void generic_unthrottle (struct tty_struct *tty) +{ + /* do nothing for the generic device */ + return; +} + + +static int generic_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) +{ + /* generic driver doesn't support any ioctls yet */ + return -ENOIOCTLCMD; +} + + +static void generic_set_termios (struct tty_struct *tty, struct termios * old) +{ + /* generic driver doesn't really care about setting any line settings */ + return; +} + + static void generic_read_bulk_callback (struct urb *urb) { struct usb_serial *serial = (struct usb_serial *)urb->context; @@ -1059,7 +1582,7 @@ static void generic_read_bulk_callback (struct urb *urb) if (urb->actual_length) { printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length); for (i = 0; i < urb->actual_length; ++i) { - printk ("0x%.2x ", data[i]); + printk ("%.2x ", data[i]); } printk ("\n"); } @@ -1352,8 +1875,8 @@ static struct tty_driver serial_tty_driver = { put_char: NULL, flush_chars: NULL, write_room: serial_write_room, - ioctl: NULL, - set_termios: NULL, + ioctl: serial_ioctl, + set_termios: serial_set_termios, set_ldisc: NULL, throttle: serial_throttle, unthrottle: serial_unthrottle, @@ -1397,19 +1920,14 @@ int usb_serial_init(void) } -#ifdef MODULE -int init_module(void) -{ - return usb_serial_init(); -} - -void cleanup_module(void) +void usb_serial_exit(void) { tty_unregister_driver(&serial_tty_driver); usb_deregister(&usb_serial_driver); } -#else -__initcall(usb_serial_init); -#endif + +module_init(usb_serial_init); +module_exit(usb_serial_exit); + |