Commit a60387ba authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (40 commits)
  USB: open disconnect race in usblcd
  USB: disconnect open race in legousbtower
  USB: open disconnect race in iowarrior
  USB: missing error check in emi62
  USB: missing error check in emi26
  USB: usb_serial_resume bug fix
  USB: remove new OHCI build warnings
  USB: amd5536udc - remove set_mwi() compiler warning
  USB: usbserial - fix potential deadlock between write() and IRQ
  usb: serial/pl2303: support for IO Data Device RSAQ5
  USB: fix read vs. disconnect race in cytherm driver
  USB: fix locking in idmouse
  USB: fix interface sysfs file-creation bug
  USB: fix ssb_ohci_probe() build bug
  USB: pl2303: remove can't happen checks, set speed properly and report baud rate
  USB: mos7840: Clean up old checks and stuff
  USB rio500.c: fix check-after-use
  USB iowarrior.c: fix check-after-use
  USB: add URB_FREE_BUFFER to permissible flags
  USB: isd200: sort out USB/IDE dependancy mess
  ...
parents 0e81bef0 d5d1ceac
...@@ -1875,6 +1875,7 @@ uart_set_options(struct uart_port *port, struct console *co, ...@@ -1875,6 +1875,7 @@ uart_set_options(struct uart_port *port, struct console *co,
int baud, int parity, int bits, int flow) int baud, int parity, int bits, int flow)
{ {
struct ktermios termios; struct ktermios termios;
static struct ktermios dummy;
int i; int i;
/* /*
...@@ -1920,7 +1921,7 @@ uart_set_options(struct uart_port *port, struct console *co, ...@@ -1920,7 +1921,7 @@ uart_set_options(struct uart_port *port, struct console *co,
*/ */
port->mctrl |= TIOCM_DTR; port->mctrl |= TIOCM_DTR;
port->ops->set_termios(port, &termios, NULL); port->ops->set_termios(port, &termios, &dummy);
co->cflag = termios.c_cflag; co->cflag = termios.c_cflag;
return 0; return 0;
......
...@@ -1641,7 +1641,13 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1641,7 +1641,13 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
intf->dev.bus_id, ret); intf->dev.bus_id, ret);
continue; continue;
} }
usb_create_sysfs_intf_files (intf);
/* The driver's probe method can call usb_set_interface(),
* which would mean the interface's sysfs files are already
* created. Just in case, we'll remove them first.
*/
usb_remove_sysfs_intf_files(intf);
usb_create_sysfs_intf_files(intf);
} }
usb_autosuspend_device(dev); usb_autosuspend_device(dev);
......
...@@ -372,7 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) ...@@ -372,7 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
/* enforce simple/standard policy */ /* enforce simple/standard policy */
allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
URB_NO_INTERRUPT | URB_DIR_MASK); URB_NO_INTERRUPT | URB_DIR_MASK | URB_FREE_BUFFER);
switch (xfertype) { switch (xfertype) {
case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_BULK:
if (is_out) if (is_out)
......
...@@ -3289,7 +3289,7 @@ static int udc_pci_probe( ...@@ -3289,7 +3289,7 @@ static int udc_pci_probe(
dev->chiprev = pdev->revision; dev->chiprev = pdev->revision;
pci_set_master(pdev); pci_set_master(pdev);
pci_set_mwi(pdev); pci_try_set_mwi(pdev);
/* init dma pools */ /* init dma pools */
if (use_dma) { if (use_dma) {
......
...@@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI ...@@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI
config USB_OHCI_HCD_SSB config USB_OHCI_HCD_SSB
bool "OHCI support for Broadcom SSB OHCI core" bool "OHCI support for Broadcom SSB OHCI core"
depends on USB_OHCI_HCD && SSB && EXPERIMENTAL depends on USB_OHCI_HCD && (SSB = y || SSB = CONFIG_USB_OHCI_HCD) && EXPERIMENTAL
default n default n
---help--- ---help---
Support for the Sonics Silicon Backplane (SSB) attached Support for the Sonics Silicon Backplane (SSB) attached
......
...@@ -80,7 +80,10 @@ static const char hcd_name [] = "ohci_hcd"; ...@@ -80,7 +80,10 @@ static const char hcd_name [] = "ohci_hcd";
static void ohci_dump (struct ohci_hcd *ohci, int verbose); static void ohci_dump (struct ohci_hcd *ohci, int verbose);
static int ohci_init (struct ohci_hcd *ohci); static int ohci_init (struct ohci_hcd *ohci);
static void ohci_stop (struct usb_hcd *hcd); static void ohci_stop (struct usb_hcd *hcd);
#if defined(CONFIG_PM) || defined(CONFIG_PCI)
static int ohci_restart (struct ohci_hcd *ohci); static int ohci_restart (struct ohci_hcd *ohci);
#endif
#include "ohci-hub.c" #include "ohci-hub.c"
#include "ohci-dbg.c" #include "ohci-dbg.c"
...@@ -396,7 +399,7 @@ static int check_ed(struct ohci_hcd *ohci, struct ed *ed) ...@@ -396,7 +399,7 @@ static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
*/ */
static void unlink_watchdog_func(unsigned long _ohci) static void unlink_watchdog_func(unsigned long _ohci)
{ {
long flags; unsigned long flags;
unsigned max; unsigned max;
unsigned seen_count = 0; unsigned seen_count = 0;
unsigned i; unsigned i;
...@@ -893,6 +896,8 @@ static void ohci_stop (struct usb_hcd *hcd) ...@@ -893,6 +896,8 @@ static void ohci_stop (struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#if defined(CONFIG_PM) || defined(CONFIG_PCI)
/* must not be called from interrupt context */ /* must not be called from interrupt context */
static int ohci_restart (struct ohci_hcd *ohci) static int ohci_restart (struct ohci_hcd *ohci)
{ {
...@@ -954,6 +959,8 @@ static int ohci_restart (struct ohci_hcd *ohci) ...@@ -954,6 +959,8 @@ static int ohci_restart (struct ohci_hcd *ohci)
return 0; return 0;
} }
#endif
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
......
...@@ -1271,7 +1271,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, ...@@ -1271,7 +1271,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
} else if (qh->period != urb->interval) { } else if (qh->period != urb->interval) {
return -EINVAL; /* Can't change the period */ return -EINVAL; /* Can't change the period */
} else { /* Pick up where the last URB leaves off */ } else {
/* Find the next unused frame */
if (list_empty(&qh->queue)) { if (list_empty(&qh->queue)) {
frame = qh->iso_frame; frame = qh->iso_frame;
} else { } else {
...@@ -1283,10 +1284,18 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, ...@@ -1283,10 +1284,18 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
lurb->number_of_packets * lurb->number_of_packets *
lurb->interval; lurb->interval;
} }
if (urb->transfer_flags & URB_ISO_ASAP) if (urb->transfer_flags & URB_ISO_ASAP) {
urb->start_frame = frame; /* Skip some frames if necessary to insure
else if (urb->start_frame != frame) * the start frame is in the future.
return -EINVAL; */
uhci_get_current_frame_number(uhci);
if (uhci_frame_before_eq(frame, uhci->frame_number)) {
frame = uhci->frame_number + 1;
frame += ((qh->phase - frame) &
(qh->period - 1));
}
} /* Otherwise pick up where the last URB leaves off */
urb->start_frame = frame;
} }
/* Make sure we won't have to go too far into the future */ /* Make sure we won't have to go too far into the future */
......
...@@ -399,7 +399,6 @@ static void cytherm_disconnect(struct usb_interface *interface) ...@@ -399,7 +399,6 @@ static void cytherm_disconnect(struct usb_interface *interface)
struct usb_cytherm *dev; struct usb_cytherm *dev;
dev = usb_get_intfdata (interface); dev = usb_get_intfdata (interface);
usb_set_intfdata (interface, NULL);
device_remove_file(&interface->dev, &dev_attr_brightness); device_remove_file(&interface->dev, &dev_attr_brightness);
device_remove_file(&interface->dev, &dev_attr_temp); device_remove_file(&interface->dev, &dev_attr_temp);
...@@ -407,6 +406,9 @@ static void cytherm_disconnect(struct usb_interface *interface) ...@@ -407,6 +406,9 @@ static void cytherm_disconnect(struct usb_interface *interface)
device_remove_file(&interface->dev, &dev_attr_port0); device_remove_file(&interface->dev, &dev_attr_port0);
device_remove_file(&interface->dev, &dev_attr_port1); device_remove_file(&interface->dev, &dev_attr_port1);
/* first remove the files, then NULL the pointer */
usb_set_intfdata (interface, NULL);
usb_put_dev(dev->udev); usb_put_dev(dev->udev);
kfree(dev); kfree(dev);
......
...@@ -114,6 +114,10 @@ static int emi26_load_firmware (struct usb_device *dev) ...@@ -114,6 +114,10 @@ static int emi26_load_firmware (struct usb_device *dev)
/* De-assert reset (let the CPU run) */ /* De-assert reset (let the CPU run) */
err = emi26_set_reset(dev,0); err = emi26_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
goto wraperr;
}
msleep(250); /* let device settle */ msleep(250); /* let device settle */
/* 2. We upload the FPGA firmware into the EMI /* 2. We upload the FPGA firmware into the EMI
......
...@@ -123,6 +123,10 @@ static int emi62_load_firmware (struct usb_device *dev) ...@@ -123,6 +123,10 @@ static int emi62_load_firmware (struct usb_device *dev)
/* De-assert reset (let the CPU run) */ /* De-assert reset (let the CPU run) */
err = emi62_set_reset(dev,0); err = emi62_set_reset(dev,0);
if (err < 0) {
err("%s - error loading firmware: error = %d", __FUNCTION__, err);
goto wraperr;
}
msleep(250); /* let device settle */ msleep(250); /* let device settle */
/* 2. We upload the FPGA firmware into the EMI /* 2. We upload the FPGA firmware into the EMI
......
This diff is collapsed.
...@@ -66,6 +66,7 @@ static struct usb_device_id idmouse_table[] = { ...@@ -66,6 +66,7 @@ static struct usb_device_id idmouse_table[] = {
USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000) USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
MODULE_DEVICE_TABLE(usb, idmouse_table); MODULE_DEVICE_TABLE(usb, idmouse_table);
static DEFINE_MUTEX(open_disc_mutex);
/* structure to hold all of our device specific stuff */ /* structure to hold all of our device specific stuff */
struct usb_idmouse { struct usb_idmouse {
...@@ -80,7 +81,7 @@ struct usb_idmouse { ...@@ -80,7 +81,7 @@ struct usb_idmouse {
int open; /* if the port is open or not */ int open; /* if the port is open or not */
int present; /* if the device is not disconnected */ int present; /* if the device is not disconnected */
struct semaphore sem; /* locks this structure */ struct mutex lock; /* locks this structure */
}; };
...@@ -213,13 +214,17 @@ static int idmouse_open(struct inode *inode, struct file *file) ...@@ -213,13 +214,17 @@ static int idmouse_open(struct inode *inode, struct file *file)
if (!interface) if (!interface)
return -ENODEV; return -ENODEV;
mutex_lock(&open_disc_mutex);
/* get the device information block from the interface */ /* get the device information block from the interface */
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
if (!dev) if (!dev) {
mutex_unlock(&open_disc_mutex);
return -ENODEV; return -ENODEV;
}
/* lock this device */ /* lock this device */
down(&dev->sem); mutex_lock(&dev->lock);
mutex_unlock(&open_disc_mutex);
/* check if already open */ /* check if already open */
if (dev->open) { if (dev->open) {
...@@ -245,7 +250,7 @@ static int idmouse_open(struct inode *inode, struct file *file) ...@@ -245,7 +250,7 @@ static int idmouse_open(struct inode *inode, struct file *file)
error: error:
/* unlock this device */ /* unlock this device */
up(&dev->sem); mutex_unlock(&dev->lock);
return result; return result;
} }
...@@ -258,12 +263,14 @@ static int idmouse_release(struct inode *inode, struct file *file) ...@@ -258,12 +263,14 @@ static int idmouse_release(struct inode *inode, struct file *file)
if (dev == NULL) if (dev == NULL)
return -ENODEV; return -ENODEV;
mutex_lock(&open_disc_mutex);
/* lock our device */ /* lock our device */
down(&dev->sem); mutex_lock(&dev->lock);
/* are we really open? */ /* are we really open? */
if (dev->open <= 0) { if (dev->open <= 0) {
up(&dev->sem); mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
return -ENODEV; return -ENODEV;
} }
...@@ -271,10 +278,12 @@ static int idmouse_release(struct inode *inode, struct file *file) ...@@ -271,10 +278,12 @@ static int idmouse_release(struct inode *inode, struct file *file)
if (!dev->present) { if (!dev->present) {
/* the device was unplugged before the file was released */ /* the device was unplugged before the file was released */
up(&dev->sem); mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
idmouse_delete(dev); idmouse_delete(dev);
} else { } else {
up(&dev->sem); mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
} }
return 0; return 0;
} }
...@@ -286,18 +295,18 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count ...@@ -286,18 +295,18 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count
int result; int result;
/* lock this object */ /* lock this object */
down(&dev->sem); mutex_lock(&dev->lock);
/* verify that the device wasn't unplugged */ /* verify that the device wasn't unplugged */
if (!dev->present) { if (!dev->present) {
up(&dev->sem); mutex_unlock(&dev->lock);
return -ENODEV; return -ENODEV;
} }
result = simple_read_from_buffer(buffer, count, ppos, result = simple_read_from_buffer(buffer, count, ppos,
dev->bulk_in_buffer, IMGSIZE); dev->bulk_in_buffer, IMGSIZE);
/* unlock the device */ /* unlock the device */
up(&dev->sem); mutex_unlock(&dev->lock);
return result; return result;
} }
...@@ -320,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface, ...@@ -320,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface,
if (dev == NULL) if (dev == NULL)
return -ENOMEM; return -ENOMEM;
init_MUTEX(&dev->sem); mutex_init(&dev->lock);
dev->udev = udev; dev->udev = udev;
dev->interface = interface; dev->interface = interface;
...@@ -372,24 +381,26 @@ static void idmouse_disconnect(struct usb_interface *interface) ...@@ -372,24 +381,26 @@ static void idmouse_disconnect(struct usb_interface *interface)
/* get device structure */ /* get device structure */
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
/* give back our minor */ /* give back our minor */
usb_deregister_dev(interface, &idmouse_class); usb_deregister_dev(interface, &idmouse_class);
/* lock it */ mutex_lock(&open_disc_mutex);
down(&dev->sem); usb_set_intfdata(interface, NULL);
/* lock the device */
mutex_lock(&dev->lock);
mutex_unlock(&open_disc_mutex);
/* prevent device read, write and ioctl */ /* prevent device read, write and ioctl */
dev->present = 0; dev->present = 0;
/* if the device is opened, idmouse_release will clean this up */ /* if the device is opened, idmouse_release will clean this up */
if (!dev->open) { if (!dev->open) {
up(&dev->sem); mutex_unlock(&dev->lock);
idmouse_delete(dev); idmouse_delete(dev);
} else { } else {
/* unlock */ /* unlock */
up(&dev->sem); mutex_unlock(&dev->lock);
} }
info("%s disconnected", DRIVER_DESC); info("%s disconnected", DRIVER_DESC);
......
...@@ -66,6 +66,7 @@ module_param(debug, bool, 0644); ...@@ -66,6 +66,7 @@ module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "debug=1 enables debugging messages"); MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
static struct usb_driver iowarrior_driver; static struct usb_driver iowarrior_driver;
static DEFINE_MUTEX(iowarrior_open_disc_lock);
/*--------------*/ /*--------------*/
/* data */ /* data */
...@@ -351,7 +352,7 @@ static ssize_t iowarrior_write(struct file *file, ...@@ -351,7 +352,7 @@ static ssize_t iowarrior_write(struct file *file,
mutex_lock(&dev->mutex); mutex_lock(&dev->mutex);
/* verify that the device wasn't unplugged */ /* verify that the device wasn't unplugged */
if (dev == NULL || !dev->present) { if (!dev->present) {
retval = -ENODEV; retval = -ENODEV;
goto exit; goto exit;
} }
...@@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file) ...@@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file)
return -ENODEV; return -ENODEV;
} }
mutex_lock(&iowarrior_open_disc_lock);
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
if (!dev) if (!dev) {
mutex_unlock(&iowarrior_open_disc_lock);
return -ENODEV; return -ENODEV;
}
mutex_lock(&dev->mutex); mutex_lock(&dev->mutex);
mutex_unlock(&iowarrior_open_disc_lock);
/* Only one process can open each device, no sharing. */ /* Only one process can open each device, no sharing. */
if (dev->opened) { if (dev->opened) {
...@@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface) ...@@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
int minor; int minor;
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
mutex_lock(&iowarrior_open_disc_lock);
usb_set_intfdata(interface, NULL); usb_set_intfdata(interface, NULL);
minor = dev->minor; minor = dev->minor;
...@@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface) ...@@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
dev->present = 0; dev->present = 0;
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
mutex_unlock(&iowarrior_open_disc_lock);
if (dev->opened) { if (dev->opened) {
/* There is a process that holds a filedescriptor to the device , /* There is a process that holds a filedescriptor to the device ,
......
...@@ -198,6 +198,7 @@ static struct usb_device_id tower_table [] = { ...@@ -198,6 +198,7 @@ static struct usb_device_id tower_table [] = {
}; };
MODULE_DEVICE_TABLE (usb, tower_table); MODULE_DEVICE_TABLE (usb, tower_table);
static DEFINE_MUTEX(open_disc_mutex);
#define LEGO_USB_TOWER_MINOR_BASE 160 #define LEGO_USB_TOWER_MINOR_BASE 160
...@@ -350,25 +351,31 @@ static int tower_open (struct inode *inode, struct file *file) ...@@ -350,25 +351,31 @@ static int tower_open (struct inode *inode, struct file *file)
goto exit; goto exit;
} }
mutex_lock(&open_disc_mutex);
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
if (!dev) { if (!dev) {
mutex_unlock(&open_disc_mutex);
retval = -ENODEV; retval = -ENODEV;
goto exit; goto exit;
} }
/* lock this device */ /* lock this device */
if (down_interruptible (&dev->sem)) { if (down_interruptible (&dev->sem)) {
mutex_unlock(&open_disc_mutex);
retval = -ERESTARTSYS; retval = -ERESTARTSYS;
goto exit; goto exit;
} }
/* allow opening only once */ /* allow opening only once */
if (dev->open_count) { if (dev->open_count) {
mutex_unlock(&open_disc_mutex);
retval = -EBUSY; retval = -EBUSY;
goto unlock_exit; goto unlock_exit;
} }
dev->open_count = 1; dev->open_count = 1;
mutex_unlock(&open_disc_mutex);
/* reset the tower */ /* reset the tower */
result = usb_control_msg (dev->udev, result = usb_control_msg (dev->udev,
...@@ -437,9 +444,10 @@ static int tower_release (struct inode *inode, struct file *file) ...@@ -437,9 +444,10 @@ static int tower_release (struct inode *inode, struct file *file)
if (dev == NULL) { if (dev == NULL) {
dbg(1, "%s: object is NULL", __FUNCTION__); dbg(1, "%s: object is NULL", __FUNCTION__);
retval = -ENODEV; retval = -ENODEV;
goto exit; goto exit_nolock;
} }
mutex_lock(&open_disc_mutex);
if (down_interruptible (&dev->sem)) { if (down_interruptible (&dev->sem)) {
retval = -ERESTARTSYS; retval = -ERESTARTSYS;
goto exit; goto exit;
...@@ -468,6 +476,8 @@ static int tower_release (struct inode *inode, struct file *file) ...@@ -468,6 +476,8 @@ static int tower_release (struct inode *inode, struct file *file)
up (&dev->sem); up (&dev->sem);
exit: exit:
mutex_unlock(&open_disc_mutex);
exit_nolock:
dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
return retval; return retval;
} }
...@@ -989,6 +999,7 @@ static void tower_disconnect (struct usb_interface *interface) ...@@ -989,6 +999,7 @@ static void tower_disconnect (struct usb_interface *interface)
dbg(2, "%s: enter", __FUNCTION__); dbg(2, "%s: enter", __FUNCTION__);
dev = usb_get_intfdata (interface); dev = usb_get_intfdata (interface);
mutex_lock(&open_disc_mutex);
usb_set_intfdata (interface, NULL); usb_set_intfdata (interface, NULL);
minor = dev->minor; minor = dev->minor;
...@@ -997,6 +1008,7 @@ static void tower_disconnect (struct usb_interface *interface) ...@@ -997,6 +1008,7 @@ static void tower_disconnect (struct usb_interface *interface)
usb_deregister_dev (interface, &tower_class); usb_deregister_dev (interface, &tower_class);
down (&dev->sem); down (&dev->sem);
mutex_unlock(&open_disc_mutex);
/* if the device is not opened, then we clean up right now */ /* if the device is not opened, then we clean up right now */
if (!dev->open_count) { if (!dev->open_count) {
......
...@@ -118,10 +118,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -118,10 +118,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
mutex_lock(&(rio->lock)); mutex_lock(&(rio->lock));
/* Sanity check to make sure rio is connected, powered, etc */ /* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL || if (rio->present == 0 || rio->rio_dev == NULL) {
rio->present == 0 ||
rio->rio_dev == NULL )
{
retval = -ENODEV; retval = -ENODEV;
goto err_out; goto err_out;
} }
...@@ -280,10 +277,7 @@ write_rio(struct file *file, const char __user *buffer, ...@@ -280,10 +277,7 @@ write_rio(struct file *file, const char __user *buffer,
if (intr) if (intr)
return -EINTR; return -EINTR;
/* Sanity check to make sure rio is connected, powered, etc */ /* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL || if (rio->present == 0 || rio->rio_dev == NULL) {
rio->present == 0 ||
rio->rio_dev == NULL )
{
mutex_unlock(&(rio->lock)); mutex_unlock(&(rio->lock));
return -ENODEV; return -ENODEV;
} }
...@@ -369,10 +363,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) ...@@ -369,10 +363,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
if (intr) if (intr)
return -EINTR; return -EINTR;
/* Sanity check to make sure rio is connected, powered, etc */ /* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL || if (rio->present == 0 || rio->rio_dev == NULL) {
rio->present == 0 ||
rio->rio_dev == NULL )
{
mutex_unlock(&(rio->lock)); mutex_unlock(&(rio->lock));
return -ENODEV; return -ENODEV;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mutex.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/usb.h> #include <linux/usb.h>
...@@ -34,6 +35,8 @@ static struct usb_device_id id_table [] = { ...@@ -34,6 +35,8 @@ static struct usb_device_id id_table [] = {
}; };
MODULE_DEVICE_TABLE (usb, id_table); MODULE_DEVICE_TABLE (usb, id_table);
static DEFINE_MUTEX(open_disc_mutex);
struct usb_lcd { struct usb_lcd {
struct usb_device * udev; /* init: probe_lcd */ struct usb_device * udev; /* init: probe_lcd */
...@@ -79,12 +82,16 @@ static int lcd_open(struct inode *inode, struct file *file) ...@@ -79,12 +82,16 @@ static int lcd_open(struct inode *inode, struct file *file)
return -ENODEV; return -ENODEV;
} }
mutex_lock(&open_disc_mutex);
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
if (!dev) if (!dev) {
mutex_unlock(&open_disc_mutex);
return -ENODEV; return -ENODEV;
}
/* increment our usage count for the device */ /* increment our usage count for the device */
kref_get(&dev->kref); kref_get(&dev->kref);
mutex_unlock(&open_disc_mutex);
/* grab a power reference */ /* grab a power reference */
r = usb_autopm_get_interface(interface); r = usb_autopm_get_interface(interface);
...@@ -393,8 +400,10 @@ static void lcd_disconnect(struct usb_interface *interface) ...@@ -393,8 +400,10 @@ static void lcd_disconnect(struct usb_interface *interface)
struct usb_lcd *dev; struct usb_lcd *dev;
int minor = interface->minor; int minor = interface->minor;
mutex_lock(&open_disc_mutex);
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL); usb_set_intfdata(interface, NULL);
mutex_unlock(&open_disc_mutex);
/* give back our minor */ /* give back our minor */
usb_deregister_dev(interface, &lcd_class); usb_deregister_dev(interface, &lcd_class);
......
...@@ -161,7 +161,8 @@ static void ark3116_set_termios(struct usb_serial_port *port, ...@@ -161,7 +161,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
{ {
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
struct ark3116_private *priv = usb_get_serial_port_data(port); struct ark3116_private *priv = usb_get_serial_port_data(port);
unsigned int cflag = port->tty->termios->c_cflag; struct ktermios *termios = port->tty->termios;
unsigned int cflag = termios->c_cflag;
unsigned long flags; unsigned long flags;
int baud; int baud;
int ark3116_baud; int ark3116_baud;
...@@ -177,11 +178,14 @@ static void ark3116_set_termios(struct usb_serial_port *port, ...@@ -177,11 +178,14 @@ static void ark3116_set_termios(struct usb_serial_port *port,
*(port->tty->termios) = tty_std_termios; *(port->tty->termios) = tty_std_termios;
port->tty->termios->c_cflag = B9600 | CS8 port->tty->termios->c_cflag = B9600 | CS8
| CREAD | HUPCL | CLOCAL; | CREAD | HUPCL | CLOCAL;
termios->c_ispeed = 9600;
termios->c_ospeed = 9600;
priv->termios_initialized = 1; priv->termios_initialized = 1;
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
cflag = port->tty->termios->c_cflag; cflag = termios->c_cflag;
termios->c_cflag &= ~(CMSPAR|CRTSCTS);
buf = kmalloc(1, GFP_KERNEL); buf = kmalloc(1, GFP_KERNEL);
if (!buf) { if (!buf) {
...@@ -254,9 +258,13 @@ static void ark3116_set_termios(struct usb_serial_port *port, ...@@ -254,9 +258,13 @@ static void ark3116_set_termios(struct usb_serial_port *port,
case 115200: case 115200:
case 230400: case 230400:
case 460800: case 460800:
/* Report the resulting rate back to the caller */
tty_encode_baud_rate(port->tty, baud, baud);
break; break;
/* set 9600 as default (if given baudrate is invalid for example) */ /* set 9600 as default (if given baudrate is invalid for example) */
default: default:
tty_encode_baud_rate(port->tty, 9600, 9600);
case 0:
baud = 9600; baud = 9600;
} }
...@@ -302,6 +310,7 @@ static void ark3116_set_termios(struct usb_serial_port *port, ...@@ -302,6 +310,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
/* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */ /* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */
kfree(buf); kfree(buf);
return; return;
} }
......
...@@ -272,9 +272,6 @@ static void ch341_set_termios(struct usb_serial_port *port, ...@@ -272,9 +272,6 @@ static void ch341_set_termios(struct usb_serial_port *port,
dbg("ch341_set_termios()"); dbg("ch341_set_termios()");
if (!tty || !tty->termios)
return;
baud_rate = tty_get_baud_rate(tty); baud_rate = tty_get_baud_rate(tty);
switch (baud_rate) { switch (baud_rate) {
...@@ -299,6 +296,11 @@ static void ch341_set_termios(struct usb_serial_port *port, ...@@ -299,6 +296,11 @@ static void ch341_set_termios(struct usb_serial_port *port,
* (cflag & PARENB) : parity {NONE, EVEN, ODD} * (cflag & PARENB) : parity {NONE, EVEN, ODD}
* (cflag & CSTOPB) : stop bits [1, 2] * (cflag & CSTOPB) : stop bits [1, 2]
*/ */
/* Copy back the old hardware settings */
tty_termios_copy_hw(tty->termios, old_termios);
/* And re-encode with the new baud */
tty_encode_baud_rate(tty, baud_rate, baud_rate);
} }
static struct usb_driver ch341_driver = { static struct usb_driver ch341_driver = {
......
...@@ -164,6 +164,7 @@ static int usb_console_setup(struct console *co, char *options) ...@@ -164,6 +164,7 @@ static int usb_console_setup(struct console *co, char *options)
} }
if (serial->type->set_termios) { if (serial->type->set_termios) {
struct ktermios dummy;
/* build up a fake tty structure so that the open call has something /* build up a fake tty structure so that the open call has something
* to look at to get the cflag value */ * to look at to get the cflag value */
tty = kzalloc(sizeof(*tty), GFP_KERNEL); tty = kzalloc(sizeof(*tty), GFP_KERNEL);
...@@ -177,12 +178,13 @@ static int usb_console_setup(struct console *co, char *options) ...@@ -177,12 +178,13 @@ static int usb_console_setup(struct console *co, char *options)
kfree (tty); kfree (tty);
return -ENOMEM; return -ENOMEM;
} }
memset(&dummy, 0, sizeof(struct ktermios));
termios->c_cflag = cflag; termios->c_cflag = cflag;
tty->termios = termios; tty->termios = termios;
port->tty = tty; port->tty = tty;
/* set up the initial termios settings */ /* set up the initial termios settings */
serial->type->set_termios(port, NULL); serial->type->set_termios(port, &dummy);
port->tty = NULL; port->tty = NULL;
kfree (termios); kfree (termios);
kfree (tty); kfree (tty);
......
...@@ -361,7 +361,6 @@ static void cp2101_get_termios (struct usb_serial_port *port) ...@@ -361,7 +361,6 @@ static void cp2101_get_termios (struct usb_serial_port *port)
dbg("%s - no tty structures", __FUNCTION__); dbg("%s - no tty structures", __FUNCTION__);
return; return;
} }
cflag = port->tty->termios->c_cflag;
cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
/* Convert to baudrate */ /* Convert to baudrate */
...@@ -369,40 +368,9 @@ static void cp2101_get_termios (struct usb_serial_port *port) ...@@ -369,40 +368,9 @@ static void cp2101_get_termios (struct usb_serial_port *port)
baud = BAUD_RATE_GEN_FREQ / baud; baud = BAUD_RATE_GEN_FREQ / baud;
dbg("%s - baud rate = %d", __FUNCTION__, baud); dbg("%s - baud rate = %d", __FUNCTION__, baud);
cflag &= ~CBAUD;
switch (baud) { tty_encode_baud_rate(port->tty, baud, baud);
/* cflag = port->tty->termios->c_cflag;
* The baud rates which are commented out below
* appear to be supported by the device
* but are non-standard
*/
case 600: cflag |= B600; break;
case 1200: cflag |= B1200; break;
case 1800: cflag |= B1800; break;
case 2400: cflag |= B2400; break;
case 4800: cflag |= B4800; break;
/*case 7200: cflag |= B7200; break;*/
case 9600: cflag |= B9600; break;
/*case 14400: cflag |= B14400; break;*/
case 19200: cflag |= B19200; break;
/*case 28800: cflag |= B28800; break;*/
case 38400: cflag |= B38400; break;
/*case 55854: cflag |= B55054; break;*/
case 57600: cflag |= B57600; break;
case 115200: cflag |= B115200; break;
/*case 127117: cflag |= B127117; break;*/
case 230400: cflag |= B230400; break;
case 460800: cflag |= B460800; break;
case 921600: cflag |= B921600; break;
/*case 3686400: cflag |= B3686400; break;*/
default:
dbg("%s - Baud rate is not supported, "
"using 9600 baud", __FUNCTION__);
cflag |= B9600;
cp2101_set_config_single(port, CP2101_BAUDRATE,
(BAUD_RATE_GEN_FREQ/9600));
break;
}
cp2101_get_config(port, CP2101_BITS, &bits, 2); cp2101_get_config(port, CP2101_BITS, &bits, 2);
cflag &= ~CSIZE; cflag &= ~CSIZE;
...@@ -516,7 +484,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) ...@@ -516,7 +484,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
static void cp2101_set_termios (struct usb_serial_port *port, static void cp2101_set_termios (struct usb_serial_port *port,
struct ktermios *old_termios) struct ktermios *old_termios)
{ {
unsigned int cflag, old_cflag=0; unsigned int cflag, old_cflag;
int baud=0, bits; int baud=0, bits;
unsigned int modem_ctl[4]; unsigned int modem_ctl[4];
...@@ -526,6 +494,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, ...@@ -526,6 +494,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
dbg("%s - no tty structures", __FUNCTION__); dbg("%s - no tty structures", __FUNCTION__);
return; return;
} }
port->tty->termios->c_cflag &= ~CMSPAR;
cflag = port->tty->termios->c_cflag; cflag = port->tty->termios->c_cflag;
old_cflag = old_termios->c_cflag; old_cflag = old_termios->c_cflag;
baud = tty_get_baud_rate(port->tty); baud = tty_get_baud_rate(port->tty);
...@@ -563,11 +533,15 @@ static void cp2101_set_termios (struct usb_serial_port *port, ...@@ -563,11 +533,15 @@ static void cp2101_set_termios (struct usb_serial_port *port,
dbg("%s - Setting baud rate to %d baud", __FUNCTION__, dbg("%s - Setting baud rate to %d baud", __FUNCTION__,
baud); baud);
if (cp2101_set_config_single(port, CP2101_BAUDRATE, if (cp2101_set_config_single(port, CP2101_BAUDRATE,
(BAUD_RATE_GEN_FREQ / baud))) (BAUD_RATE_GEN_FREQ / baud))) {
dev_err(&port->dev, "Baud rate requested not " dev_err(&port->dev, "Baud rate requested not "
"supported by device\n"); "supported by device\n");
baud = tty_termios_baud_rate(old_termios);
}
} }
} }
/* Report back the resulting baud rate */
tty_encode_baud_rate(port->tty, baud, baud);
/* If the number of data bits is to be updated */ /* If the number of data bits is to be updated */
if ((cflag & CSIZE) != (old_cflag & CSIZE)) { if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
......
...@@ -973,6 +973,8 @@ static void digi_set_termios(struct usb_serial_port *port, ...@@ -973,6 +973,8 @@ static void digi_set_termios(struct usb_serial_port *port,
} }
} }
/* set parity */ /* set parity */
tty->termios->c_cflag &= ~CMSPAR;
if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) {
if (cflag&PARENB) { if (cflag&PARENB) {
if (cflag&PARODD) if (cflag&PARODD)
...@@ -1054,15 +1056,15 @@ static void digi_set_termios(struct usb_serial_port *port, ...@@ -1054,15 +1056,15 @@ static void digi_set_termios(struct usb_serial_port *port,
} }
/* set output flow control */ /* set output flow control */
if ((iflag&IXON) != (old_iflag&IXON) if ((iflag & IXON) != (old_iflag & IXON)
|| (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
arg = 0; arg = 0;
if (iflag&IXON) if (iflag & IXON)
arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
else else
arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
if (cflag&CRTSCTS) { if (cflag & CRTSCTS) {
arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS;
} else { } else {
arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS;
...@@ -1076,8 +1078,8 @@ static void digi_set_termios(struct usb_serial_port *port, ...@@ -1076,8 +1078,8 @@ static void digi_set_termios(struct usb_serial_port *port,
} }
/* set receive enable/disable */ /* set receive enable/disable */
if ((cflag&CREAD) != (old_cflag&CREAD)) { if ((cflag & CREAD) != (old_cflag & CREAD)) {
if (cflag&CREAD) if (cflag & CREAD)
arg = DIGI_ENABLE; arg = DIGI_ENABLE;
else else
arg = DIGI_DISABLE; arg = DIGI_DISABLE;
...@@ -1089,7 +1091,7 @@ static void digi_set_termios(struct usb_serial_port *port, ...@@ -1089,7 +1091,7 @@ static void digi_set_termios(struct usb_serial_port *port,
} }
if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0) if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0)
dbg("digi_set_termios: write oob failed, ret=%d", ret); dbg("digi_set_termios: write oob failed, ret=%d", ret);
tty_encode_baud_rate(tty, baud, baud);
} }
......
...@@ -449,14 +449,9 @@ static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsign ...@@ -449,14 +449,9 @@ static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsign
static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
{ {
struct ktermios *termios = port->tty->termios;
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if ((!port->tty) || (!port->tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
return;
}
/* /*
* The empeg-car player wants these particular tty settings. * The empeg-car player wants these particular tty settings.
* You could, for example, change the baud rate, however the * You could, for example, change the baud rate, however the
...@@ -466,7 +461,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol ...@@ -466,7 +461,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
* *
* The default requirements for this device are: * The default requirements for this device are:
*/ */
port->tty->termios->c_iflag termios->c_iflag
&= ~(IGNBRK /* disable ignore break */ &= ~(IGNBRK /* disable ignore break */
| BRKINT /* disable break causes interrupt */ | BRKINT /* disable break causes interrupt */
| PARMRK /* disable mark parity errors */ | PARMRK /* disable mark parity errors */
...@@ -476,24 +471,23 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol ...@@ -476,24 +471,23 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
| ICRNL /* disable translate CR to NL */ | ICRNL /* disable translate CR to NL */
| IXON); /* disable enable XON/XOFF flow control */ | IXON); /* disable enable XON/XOFF flow control */
port->tty->termios->c_oflag termios->c_oflag
&= ~OPOST; /* disable postprocess output characters */ &= ~OPOST; /* disable postprocess output characters */
port->tty->termios->c_lflag termios->c_lflag
&= ~(ECHO /* disable echo input characters */ &= ~(ECHO /* disable echo input characters */
| ECHONL /* disable echo new line */ | ECHONL /* disable echo new line */
| ICANON /* disable erase, kill, werase, and rprnt special characters */ | ICANON /* disable erase, kill, werase, and rprnt special characters */
| ISIG /* disable interrupt, quit, and suspend special characters */ | ISIG /* disable interrupt, quit, and suspend special characters */
| IEXTEN); /* disable non-POSIX special characters */ | IEXTEN); /* disable non-POSIX special characters */
port->tty->termios->c_cflag termios->c_cflag
&= ~(CSIZE /* no size */ &= ~(CSIZE /* no size */
| PARENB /* disable parity bit */ | PARENB /* disable parity bit */
| CBAUD); /* clear current baud rate */ | CBAUD); /* clear current baud rate */
port->tty->termios->c_cflag termios->c_cflag
|= (CS8 /* character size 8 bits */ |= CS8; /* character size 8 bits */
| B115200); /* baud rate 115200 */
/* /*
* Force low_latency on; otherwise the pushes are scheduled; * Force low_latency on; otherwise the pushes are scheduled;
...@@ -501,8 +495,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol ...@@ -501,8 +495,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
* on the floor. We don't want to drop bytes on the floor. :) * on the floor. We don't want to drop bytes on the floor. :)
*/ */
port->tty->low_latency = 1; port->tty->low_latency = 1;
tty_encode_baud_rate(port->tty, 115200, 115200);
return;
} }
......
...@@ -294,7 +294,7 @@ struct ftdi_private { ...@@ -294,7 +294,7 @@ struct ftdi_private {
__u16 interface; /* FT2232C port interface (0 for FT232/245) */ __u16 interface; /* FT2232C port interface (0 for FT232/245) */
int force_baud; /* if non-zero, force the baud rate to this value */ speed_t force_baud; /* if non-zero, force the baud rate to this value */
int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
spinlock_t tx_lock; /* spinlock for transmit state */ spinlock_t tx_lock; /* spinlock for transmit state */
...@@ -878,6 +878,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) ...@@ -878,6 +878,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
if (div_value == 0) { if (div_value == 0) {
dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud); dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud);
div_value = ftdi_sio_b9600; div_value = ftdi_sio_b9600;
baud = 9600;
div_okay = 0; div_okay = 0;
} }
break; break;
...@@ -886,6 +887,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) ...@@ -886,6 +887,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
div_value = ftdi_232am_baud_to_divisor(baud); div_value = ftdi_232am_baud_to_divisor(baud);
} else { } else {
dbg("%s - Baud rate too high!", __FUNCTION__); dbg("%s - Baud rate too high!", __FUNCTION__);
baud = 9600;
div_value = ftdi_232am_baud_to_divisor(9600); div_value = ftdi_232am_baud_to_divisor(9600);
div_okay = 0; div_okay = 0;
} }
...@@ -899,6 +901,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) ...@@ -899,6 +901,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
dbg("%s - Baud rate too high!", __FUNCTION__); dbg("%s - Baud rate too high!", __FUNCTION__);
div_value = ftdi_232bm_baud_to_divisor(9600); div_value = ftdi_232bm_baud_to_divisor(9600);
div_okay = 0; div_okay = 0;
baud = 9600;
} }
break; break;
} /* priv->chip_type */ } /* priv->chip_type */
...@@ -909,6 +912,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) ...@@ -909,6 +912,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
ftdi_chip_name[priv->chip_type]); ftdi_chip_name[priv->chip_type]);
} }
tty_encode_baud_rate(port->tty, baud, baud);
return(div_value); return(div_value);
} }
...@@ -1263,7 +1267,7 @@ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv) ...@@ -1263,7 +1267,7 @@ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
priv->flags |= ASYNC_SPD_CUST; priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 77; priv->custom_divisor = 77;
priv->force_baud = B38400; priv->force_baud = 38400;
} /* ftdi_USB_UIRT_setup */ } /* ftdi_USB_UIRT_setup */
/* Setup for the HE-TIRA1 device, which requires hardwired /* Setup for the HE-TIRA1 device, which requires hardwired
...@@ -1274,7 +1278,7 @@ static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv) ...@@ -1274,7 +1278,7 @@ static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
priv->flags |= ASYNC_SPD_CUST; priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 240; priv->custom_divisor = 240;
priv->force_baud = B38400; priv->force_baud = 38400;
priv->force_rtscts = 1; priv->force_rtscts = 1;
} /* ftdi_HE_TIRA1_setup */ } /* ftdi_HE_TIRA1_setup */
...@@ -1363,7 +1367,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) ...@@ -1363,7 +1367,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
/* ftdi_set_termios will send usb control messages */ /* ftdi_set_termios will send usb control messages */
if (port->tty) if (port->tty)
ftdi_set_termios(port, NULL); ftdi_set_termios(port, port->tty->termios);
/* FIXME: Flow control might be enabled, so it should be checked - /* FIXME: Flow control might be enabled, so it should be checked -
we have no control of defaults! */ we have no control of defaults! */
...@@ -1933,32 +1937,33 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) ...@@ -1933,32 +1937,33 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
{ /* ftdi_termios */ { /* ftdi_termios */
struct usb_device *dev = port->serial->dev; struct usb_device *dev = port->serial->dev;
unsigned int cflag = port->tty->termios->c_cflag;
struct ftdi_private *priv = usb_get_serial_port_data(port); struct ftdi_private *priv = usb_get_serial_port_data(port);
struct ktermios *termios = port->tty->termios;
unsigned int cflag = termios->c_cflag;
__u16 urb_value; /* will hold the new flags */ __u16 urb_value; /* will hold the new flags */
char buf[1]; /* Perhaps I should dynamically alloc this? */ char buf[1]; /* Perhaps I should dynamically alloc this? */
// Added for xon/xoff support // Added for xon/xoff support
unsigned int iflag = port->tty->termios->c_iflag; unsigned int iflag = termios->c_iflag;
unsigned char vstop; unsigned char vstop;
unsigned char vstart; unsigned char vstart;
dbg("%s", __FUNCTION__); dbg("%s", __FUNCTION__);
/* Force baud rate if this device requires it, unless it is set to B0. */ /* Force baud rate if this device requires it, unless it is set to B0. */
if (priv->force_baud && ((port->tty->termios->c_cflag & CBAUD) != B0)) { if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) {
dbg("%s: forcing baud rate for this device", __FUNCTION__); dbg("%s: forcing baud rate for this device", __FUNCTION__);
port->tty->termios->c_cflag &= ~CBAUD; tty_encode_baud_rate(port->tty, priv->force_baud,
port->tty->termios->c_cflag |= priv->force_baud; priv->force_baud);
} }
/* Force RTS-CTS if this device requires it. */ /* Force RTS-CTS if this device requires it. */
if (priv->force_rtscts) { if (priv->force_rtscts) {
dbg("%s: forcing rtscts for this device", __FUNCTION__); dbg("%s: forcing rtscts for this device", __FUNCTION__);
port->tty->termios->c_cflag |= CRTSCTS; termios->c_cflag |= CRTSCTS;
} }
cflag = port->tty->termios->c_cflag; cflag = termios->c_cflag;
/* FIXME -For this cut I don't care if the line is really changing or /* FIXME -For this cut I don't care if the line is really changing or
not - so just do the change regardless - should be able to not - so just do the change regardless - should be able to
...@@ -1969,6 +1974,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old ...@@ -1969,6 +1974,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
/* Set number of data bits, parity, stop bits */ /* Set number of data bits, parity, stop bits */
termios->c_cflag &= ~CMSPAR;
urb_value = 0; urb_value = 0;
urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
FTDI_SIO_SET_DATA_STOP_BITS_1); FTDI_SIO_SET_DATA_STOP_BITS_1);
...@@ -2048,8 +2055,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old ...@@ -2048,8 +2055,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
// Set the vstart and vstop -- could have been done up above where // Set the vstart and vstop -- could have been done up above where
// a lot of other dereferencing is done but that would be very // a lot of other dereferencing is done but that would be very
// inefficient as vstart and vstop are not always needed // inefficient as vstart and vstop are not always needed
vstart=port->tty->termios->c_cc[VSTART]; vstart = termios->c_cc[VSTART];
vstop=port->tty->termios->c_cc[VSTOP]; vstop = termios->c_cc[VSTOP];
urb_value=(vstop << 8) | (vstart); urb_value=(vstop << 8) | (vstart);
if (usb_control_msg(dev, if (usb_control_msg(dev,
......
...@@ -208,14 +208,15 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * ...@@ -208,14 +208,15 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
/* only do something if we have a bulk out endpoint */ /* only do something if we have a bulk out endpoint */
if (serial->num_bulk_out) { if (serial->num_bulk_out) {
spin_lock_bh(&port->lock); unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
if (port->write_urb_busy) { if (port->write_urb_busy) {
spin_unlock_bh(&port->lock); spin_unlock_irqrestore(&port->lock, flags);
dbg("%s - already writing", __FUNCTION__); dbg("%s - already writing", __FUNCTION__);
return 0; return 0;
} }
port->write_urb_busy = 1; port->write_urb_busy = 1;
spin_unlock_bh(&port->lock); spin_unlock_irqrestore(&port->lock, flags);
count = (count > port->bulk_out_size) ? port->bulk_out_size : count; count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
......
...@@ -1503,22 +1503,16 @@ static void edge_unthrottle (struct usb_serial_port *port) ...@@ -1503,22 +1503,16 @@ static void edge_unthrottle (struct usb_serial_port *port)
*****************************************************************************/ *****************************************************************************/
static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
{ {
/* FIXME: This function appears unused ?? */
struct edgeport_port *edge_port = usb_get_serial_port_data(port); struct edgeport_port *edge_port = usb_get_serial_port_data(port);
struct tty_struct *tty = port->tty; struct tty_struct *tty = port->tty;
unsigned int cflag; unsigned int cflag;
if (!port->tty || !port->tty->termios) {
dbg ("%s - no tty or termios", __FUNCTION__);
return;
}
cflag = tty->termios->c_cflag; cflag = tty->termios->c_cflag;
dbg("%s - clfag %08x iflag %08x", __FUNCTION__, dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
tty->termios->c_cflag, tty->termios->c_iflag); tty->termios->c_cflag, tty->termios->c_iflag);
if (old_termios) { dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, old_termios->c_cflag, old_termios->c_iflag);
old_termios->c_cflag, old_termios->c_iflag);
}
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
...@@ -2653,7 +2647,11 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi ...@@ -2653,7 +2647,11 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
dbg("%s - baud rate = %d", __FUNCTION__, baud); dbg("%s - baud rate = %d", __FUNCTION__, baud);
status = send_cmd_write_baud_rate (edge_port, baud); status = send_cmd_write_baud_rate (edge_port, baud);
if (status == -1) {
/* Speed change was not possible - put back the old speed */
baud = tty_termios_baud_rate(old_termios);
tty_encode_baud_rate(tty, baud, baud);
}
return; return;
} }
......
...@@ -504,11 +504,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t ...@@ -504,11 +504,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if ((!port->tty) || (!port->tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
return;
}
baud = tty_get_baud_rate(port->tty); baud = tty_get_baud_rate(port->tty);
/* /*
...@@ -531,8 +526,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t ...@@ -531,8 +526,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
default: default:
ir_baud = SPEED_9600; ir_baud = SPEED_9600;
baud = 9600; baud = 9600;
/* And once the new tty stuff is all done we need to
call back to correct the baud bits */
} }
if (xbof == -1) if (xbof == -1)
...@@ -562,6 +555,10 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t ...@@ -562,6 +555,10 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
result = usb_submit_urb (port->write_urb, GFP_KERNEL); result = usb_submit_urb (port->write_urb, GFP_KERNEL);
if (result) if (result)
dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
/* Only speed changes are supported */
tty_termios_copy_hw(port->tty->termios, old_termios);
tty_encode_baud_rate(port->tty, baud, baud);
} }
......
...@@ -278,29 +278,35 @@ static void keyspan_set_termios (struct usb_serial_port *port, ...@@ -278,29 +278,35 @@ static void keyspan_set_termios (struct usb_serial_port *port,
struct keyspan_port_private *p_priv; struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details; const struct keyspan_device_details *d_details;
unsigned int cflag; unsigned int cflag;
struct tty_struct *tty = port->tty;
dbg("%s", __FUNCTION__); dbg("%s", __FUNCTION__);
p_priv = usb_get_serial_port_data(port); p_priv = usb_get_serial_port_data(port);
d_details = p_priv->device_details; d_details = p_priv->device_details;
cflag = port->tty->termios->c_cflag; cflag = tty->termios->c_cflag;
device_port = port->number - port->serial->minor; device_port = port->number - port->serial->minor;
/* Baud rate calculation takes baud rate as an integer /* Baud rate calculation takes baud rate as an integer
so other rates can be generated if desired. */ so other rates can be generated if desired. */
baud_rate = tty_get_baud_rate(port->tty); baud_rate = tty_get_baud_rate(tty);
/* If no match or invalid, don't change */ /* If no match or invalid, don't change */
if (baud_rate >= 0 if (d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
&& d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) { NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
/* FIXME - more to do here to ensure rate changes cleanly */ /* FIXME - more to do here to ensure rate changes cleanly */
/* FIXME - calcuate exact rate from divisor ? */
p_priv->baud = baud_rate; p_priv->baud = baud_rate;
} } else
baud_rate = tty_termios_baud_rate(old_termios);
tty_encode_baud_rate(tty, baud_rate, baud_rate);
/* set CTS/RTS handshake etc. */ /* set CTS/RTS handshake etc. */
p_priv->cflag = cflag; p_priv->cflag = cflag;
p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none; p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
/* Mark/Space not supported */
tty->termios->c_cflag &= ~CMSPAR;
keyspan_send_setup(port, 0); keyspan_send_setup(port, 0);
} }
......
...@@ -616,8 +616,9 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old ...@@ -616,8 +616,9 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
case 1200: case 1200:
urb_val = SUSBCR_SBR_1200; urb_val = SUSBCR_SBR_1200;
break; break;
case 9600:
default: default:
speed = 9600;
case 9600:
urb_val = SUSBCR_SBR_9600; urb_val = SUSBCR_SBR_9600;
break; break;
} }
...@@ -641,6 +642,8 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old ...@@ -641,6 +642,8 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
urb_val |= SUSBCR_SPASB_NoParity; urb_val |= SUSBCR_SPASB_NoParity;
strcat(settings, "No Parity"); strcat(settings, "No Parity");
} }
port->tty->termios->c_cflag &= ~CMSPAR;
tty_encode_baud_rate(port->tty, speed, speed);
result = usb_control_msg( port->serial->dev, result = usb_control_msg( port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0 ), usb_rcvctrlpipe(port->serial->dev, 0 ),
......
...@@ -1977,11 +1977,6 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port, ...@@ -1977,11 +1977,6 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
tty = mos7840_port->port->tty; tty = mos7840_port->port->tty;
if ((!tty) || (!tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
return;
}
dbg("%s", "Entering .......... \n"); dbg("%s", "Entering .......... \n");
lData = LCR_BITS_8; lData = LCR_BITS_8;
...@@ -2151,11 +2146,6 @@ static void mos7840_set_termios(struct usb_serial_port *port, ...@@ -2151,11 +2146,6 @@ static void mos7840_set_termios(struct usb_serial_port *port,
tty = port->tty; tty = port->tty;
if (!port->tty || !port->tty->termios) {
dbg("%s - no tty or termios", __FUNCTION__);
return;
}
if (!mos7840_port->open) { if (!mos7840_port->open) {
dbg("%s - port not opened", __FUNCTION__); dbg("%s - port not opened", __FUNCTION__);
return; return;
...@@ -2165,19 +2155,10 @@ static void mos7840_set_termios(struct usb_serial_port *port, ...@@ -2165,19 +2155,10 @@ static void mos7840_set_termios(struct usb_serial_port *port,
cflag = tty->termios->c_cflag; cflag = tty->termios->c_cflag;
if (!cflag) {
dbg("%s %s\n", __FUNCTION__, "cflag is NULL");
return;
}
dbg("%s - clfag %08x iflag %08x", __FUNCTION__, dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
if (old_termios) { old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
}
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
/* change the port settings to the new ones specified */ /* change the port settings to the new ones specified */
......
...@@ -172,6 +172,8 @@ static struct usb_device_id option_ids[] = { ...@@ -172,6 +172,8 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
...@@ -311,7 +313,8 @@ static void option_set_termios(struct usb_serial_port *port, ...@@ -311,7 +313,8 @@ static void option_set_termios(struct usb_serial_port *port,
struct ktermios *old_termios) struct ktermios *old_termios)
{ {
dbg("%s", __FUNCTION__); dbg("%s", __FUNCTION__);
/* Doesn't support option setting */
tty_termios_copy_hw(port->tty->termios, old_termios);
option_send_setup(port); option_send_setup(port);
} }
......
...@@ -56,6 +56,7 @@ static struct usb_device_id id_table [] = { ...@@ -56,6 +56,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) }, { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
...@@ -470,16 +471,13 @@ static void pl2303_set_termios(struct usb_serial_port *port, ...@@ -470,16 +471,13 @@ static void pl2303_set_termios(struct usb_serial_port *port,
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
if ((!port->tty) || (!port->tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
return;
}
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) { if (!priv->termios_initialized) {
*(port->tty->termios) = tty_std_termios; *(port->tty->termios) = tty_std_termios;
port->tty->termios->c_cflag = B9600 | CS8 | CREAD | port->tty->termios->c_cflag = B9600 | CS8 | CREAD |
HUPCL | CLOCAL; HUPCL | CLOCAL;
port->tty->termios->c_ispeed = 9600;
port->tty->termios->c_ospeed = 9600;
priv->termios_initialized = 1; priv->termios_initialized = 1;
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
...@@ -596,6 +594,10 @@ static void pl2303_set_termios(struct usb_serial_port *port, ...@@ -596,6 +594,10 @@ static void pl2303_set_termios(struct usb_serial_port *port,
dbg ("0x40:0x1:0x0:0x0 %d", i); dbg ("0x40:0x1:0x0:0x0 %d", i);
} }
/* FIXME: Need to read back resulting baud rate */
if (baud)
tty_encode_baud_rate(port->tty, baud, baud);
kfree(buf); kfree(buf);
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define IODATA_VENDOR_ID 0x04bb #define IODATA_VENDOR_ID 0x04bb
#define IODATA_PRODUCT_ID 0x0a03 #define IODATA_PRODUCT_ID 0x0a03
#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e
#define ELCOM_VENDOR_ID 0x056e #define ELCOM_VENDOR_ID 0x056e
#define ELCOM_PRODUCT_ID 0x5003 #define ELCOM_PRODUCT_ID 0x5003
......
...@@ -224,7 +224,7 @@ static void sierra_set_termios(struct usb_serial_port *port, ...@@ -224,7 +224,7 @@ static void sierra_set_termios(struct usb_serial_port *port,
struct ktermios *old_termios) struct ktermios *old_termios)
{ {
dbg("%s", __FUNCTION__); dbg("%s", __FUNCTION__);
tty_termios_copy_hw(port->tty->termios, old_termios);
sierra_send_setup(port); sierra_send_setup(port);
} }
......
...@@ -429,6 +429,8 @@ static void serial_set_termios (struct tty_struct *tty, struct ktermios * old) ...@@ -429,6 +429,8 @@ static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
/* pass on to the driver specific version of this function if it is available */ /* pass on to the driver specific version of this function if it is available */
if (port->serial->type->set_termios) if (port->serial->type->set_termios)
port->serial->type->set_termios(port, old); port->serial->type->set_termios(port, old);
else
tty_termios_copy_hw(tty->termios, old);
} }
static void serial_break (struct tty_struct *tty, int break_state) static void serial_break (struct tty_struct *tty, int break_state)
...@@ -1121,7 +1123,9 @@ int usb_serial_resume(struct usb_interface *intf) ...@@ -1121,7 +1123,9 @@ int usb_serial_resume(struct usb_interface *intf)
{ {
struct usb_serial *serial = usb_get_intfdata(intf); struct usb_serial *serial = usb_get_intfdata(intf);
return serial->type->resume(serial); if (serial->type->resume)
return serial->type->resume(serial);
return 0;
} }
EXPORT_SYMBOL(usb_serial_resume); EXPORT_SYMBOL(usb_serial_resume);
......
...@@ -885,16 +885,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un ...@@ -885,16 +885,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
{ {
dbg("%s -port %d", __FUNCTION__, port->number); dbg("%s -port %d", __FUNCTION__, port->number);
if ((!port->tty) || (!port->tty->termios)) {
dbg("%s - no tty structures", __FUNCTION__);
goto exit;
}
firm_setup_port(port); firm_setup_port(port);
exit:
return;
} }
...@@ -1244,6 +1235,8 @@ static int firm_setup_port(struct usb_serial_port *port) { ...@@ -1244,6 +1235,8 @@ static int firm_setup_port(struct usb_serial_port *port) {
port_settings.baud = tty_get_baud_rate(port->tty); port_settings.baud = tty_get_baud_rate(port->tty);
dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud); dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud);
/* fixme: should set validated settings */
tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud);
/* handle any settings that aren't specified in the tty structure */ /* handle any settings that aren't specified in the tty structure */
port_settings.lloop = 0; port_settings.lloop = 0;
......
...@@ -48,7 +48,6 @@ config USB_STORAGE_FREECOM ...@@ -48,7 +48,6 @@ config USB_STORAGE_FREECOM
config USB_STORAGE_ISD200 config USB_STORAGE_ISD200
bool "ISD-200 USB/ATA Bridge support" bool "ISD-200 USB/ATA Bridge support"
depends on USB_STORAGE depends on USB_STORAGE
depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE
---help--- ---help---
Say Y here if you want to use USB Mass Store devices based Say Y here if you want to use USB Mass Store devices based
on the In-Systems Design ISD-200 USB/ATA bridge. on the In-Systems Design ISD-200 USB/ATA bridge.
......
...@@ -977,6 +977,109 @@ static int isd200_manual_enum(struct us_data *us) ...@@ -977,6 +977,109 @@ static int isd200_manual_enum(struct us_data *us)
return(retStatus); return(retStatus);
} }
/*
* We are the last non IDE user of the legacy IDE ident structures
* and we thus want to keep a private copy of this function so the
* driver can be used without the obsolete drivers/ide layer
*/
static void isd200_fix_driveid (struct hd_driveid *id)
{
#ifndef __LITTLE_ENDIAN
# ifdef __BIG_ENDIAN
int i;
u16 *stringcast;
id->config = __le16_to_cpu(id->config);
id->cyls = __le16_to_cpu(id->cyls);
id->reserved2 = __le16_to_cpu(id->reserved2);
id->heads = __le16_to_cpu(id->heads);
id->track_bytes = __le16_to_cpu(id->track_bytes);
id->sector_bytes = __le16_to_cpu(id->sector_bytes);
id->sectors = __le16_to_cpu(id->sectors);
id->vendor0 = __le16_to_cpu(id->vendor0);
id->vendor1 = __le16_to_cpu(id->vendor1);
id->vendor2 = __le16_to_cpu(id->vendor2);
stringcast = (u16 *)&id->serial_no[0];
for (i = 0; i < (20/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
id->buf_type = __le16_to_cpu(id->buf_type);
id->buf_size = __le16_to_cpu(id->buf_size);
id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
stringcast = (u16 *)&id->fw_rev[0];
for (i = 0; i < (8/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
stringcast = (u16 *)&id->model[0];
for (i = 0; i < (40/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
id->dword_io = __le16_to_cpu(id->dword_io);
id->reserved50 = __le16_to_cpu(id->reserved50);
id->field_valid = __le16_to_cpu(id->field_valid);
id->cur_cyls = __le16_to_cpu(id->cur_cyls);
id->cur_heads = __le16_to_cpu(id->cur_heads);
id->cur_sectors = __le16_to_cpu(id->cur_sectors);
id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
id->lba_capacity = __le32_to_cpu(id->lba_capacity);
id->dma_1word = __le16_to_cpu(id->dma_1word);
id->dma_mword = __le16_to_cpu(id->dma_mword);
id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
id->eide_pio = __le16_to_cpu(id->eide_pio);
id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
for (i = 0; i < 2; ++i)
id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
for (i = 0; i < 4; ++i)
id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
id->queue_depth = __le16_to_cpu(id->queue_depth);
for (i = 0; i < 4; ++i)
id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
id->major_rev_num = __le16_to_cpu(id->major_rev_num);
id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
id->command_set_1 = __le16_to_cpu(id->command_set_1);
id->command_set_2 = __le16_to_cpu(id->command_set_2);
id->cfsse = __le16_to_cpu(id->cfsse);
id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1);
id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2);
id->csf_default = __le16_to_cpu(id->csf_default);
id->dma_ultra = __le16_to_cpu(id->dma_ultra);
id->trseuc = __le16_to_cpu(id->trseuc);
id->trsEuc = __le16_to_cpu(id->trsEuc);
id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues);
id->mprc = __le16_to_cpu(id->mprc);
id->hw_config = __le16_to_cpu(id->hw_config);
id->acoustic = __le16_to_cpu(id->acoustic);
id->msrqs = __le16_to_cpu(id->msrqs);
id->sxfert = __le16_to_cpu(id->sxfert);
id->sal = __le16_to_cpu(id->sal);
id->spg = __le32_to_cpu(id->spg);
id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
for (i = 0; i < 22; i++)
id->words104_125[i] = __le16_to_cpu(id->words104_125[i]);
id->last_lun = __le16_to_cpu(id->last_lun);
id->word127 = __le16_to_cpu(id->word127);
id->dlf = __le16_to_cpu(id->dlf);
id->csfo = __le16_to_cpu(id->csfo);
for (i = 0; i < 26; i++)
id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
id->word156 = __le16_to_cpu(id->word156);
for (i = 0; i < 3; i++)
id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
id->cfa_power = __le16_to_cpu(id->cfa_power);
for (i = 0; i < 14; i++)
id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
for (i = 0; i < 31; i++)
id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
for (i = 0; i < 48; i++)
id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
id->integrity_word = __le16_to_cpu(id->integrity_word);
# else
# error "Please fix <asm/byteorder.h>"
# endif
#endif
}
/************************************************************************** /**************************************************************************
* isd200_get_inquiry_data * isd200_get_inquiry_data
...@@ -1018,7 +1121,7 @@ static int isd200_get_inquiry_data( struct us_data *us ) ...@@ -1018,7 +1121,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
int i; int i;
__be16 *src; __be16 *src;
__u16 *dest; __u16 *dest;
ide_fix_driveid(id); isd200_fix_driveid(id);
US_DEBUGP(" Identify Data Structure:\n"); US_DEBUGP(" Identify Data Structure:\n");
US_DEBUGP(" config = 0x%x\n", id->config); US_DEBUGP(" config = 0x%x\n", id->config);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment