Commit d72cd3a9 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:
  USB: pwc : do not pass stack allocated buffers to USB core.
  USB: otg: Fix bug on remove path without transceiver
  USB: correct error handling in cdc-wdm
  USB: removal of tty->low_latency hack dating back to the old serial code
  USB: serial: sierra driver bug fix for composite interface
  USB: gadget: omap_udc uses platform_driver_probe()
  USB: ci13xxx_udc: fix build error
  USB: musb: Prevent multiple includes of musb.h
  USB: pass mem_flags to dma_alloc_coherent
  USB: g_file_storage: fix use-after-free bug when closing files
  USB: ehci-sched.c: EHCI SITD scheduling bugfix
  USB: fix mos7840 problem with minor numbers
  USB: mos7840: add new device id
  USB: musb: fix build when !CONFIG_PM
  USB: musb: Remove my email address from few musb related drivers
  USB: Gadget: MIPS CI13xxx UDC bugfixes
  USB: Unusual Device support for Gold MP3 Player Energy
  USB: serial: fix lifetime and locking problems
parents ff91fad2 6b35ca0d
This diff is collapsed.
......@@ -3,7 +3,7 @@
*
* This driver supports USB CDC WCM Device Management.
*
* Copyright (c) 2007-2008 Oliver Neukum
* Copyright (c) 2007-2009 Oliver Neukum
*
* Some code taken from cdc-acm.c
*
......@@ -610,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (!buffer)
goto out;
while (buflen > 0) {
while (buflen > 2) {
if (buffer [1] != USB_DT_CS_INTERFACE) {
dev_err(&intf->dev, "skipping garbage\n");
goto next_desc;
......@@ -646,16 +646,18 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
spin_lock_init(&desc->iuspin);
init_waitqueue_head(&desc->wait);
desc->wMaxCommand = maxcom;
/* this will be expanded and needed in hardware endianness */
desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
desc->intf = intf;
INIT_WORK(&desc->rxwork, wdm_rxwork);
iface = &intf->altsetting[0];
ep = &iface->endpoint[0].desc;
if (!ep || !usb_endpoint_is_int_in(ep)) {
rv = -EINVAL;
iface = intf->cur_altsetting;
if (iface->desc.bNumEndpoints != 1)
goto err;
ep = &iface->endpoint[0].desc;
if (!ep || !usb_endpoint_is_int_in(ep))
goto err;
}
desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
......@@ -711,12 +713,19 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_set_intfdata(intf, desc);
rv = usb_register_dev(intf, &wdm_class);
if (rv < 0)
goto err3;
else
dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
intf->minor - WDM_MINOR_BASE);
if (rv < 0)
goto err;
out:
return rv;
err3:
usb_set_intfdata(intf, NULL);
usb_buffer_free(interface_to_usbdev(desc->intf),
desc->bMaxPacketSize0,
desc->inbuf,
desc->response->transfer_dma);
err2:
usb_buffer_free(interface_to_usbdev(desc->intf),
desc->wMaxPacketSize,
......
......@@ -119,7 +119,7 @@ void *hcd_buffer_alloc(
if (size <= pool_max [i])
return dma_pool_alloc(hcd->pool [i], mem_flags, dma);
}
return dma_alloc_coherent(hcd->self.controller, size, dma, 0);
return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
}
void hcd_buffer_free(
......
......@@ -51,6 +51,7 @@
* - Gadget API (majority of optional features)
* - Suspend & Remote Wakeup
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
......@@ -142,7 +143,7 @@ static struct {
#define CAP_DEVICEADDR (0x014UL)
#define CAP_ENDPTLISTADDR (0x018UL)
#define CAP_PORTSC (0x044UL)
#define CAP_DEVLC (0x0B4UL)
#define CAP_DEVLC (0x084UL)
#define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL)
#define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
#define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL)
......@@ -1986,6 +1987,8 @@ static int ep_enable(struct usb_ep *ep,
do {
dbg_event(_usb_addr(mEp), "ENABLE", 0);
mEp->qh[mEp->dir].ptr->cap = 0;
if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
mEp->qh[mEp->dir].ptr->cap |= QH_IOS;
else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
......
......@@ -738,7 +738,6 @@ static struct fsg_dev *the_fsg;
static struct usb_gadget_driver fsg_driver;
static void close_backing_file(struct lun *curlun);
static void close_all_backing_files(struct fsg_dev *fsg);
/*-------------------------------------------------------------------------*/
......@@ -3593,12 +3592,10 @@ static int fsg_main_thread(void *fsg_)
fsg->thread_task = NULL;
spin_unlock_irq(&fsg->lock);
/* In case we are exiting because of a signal, unregister the
* gadget driver and close the backing file. */
if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) {
/* If we are exiting because of a signal, unregister the
* gadget driver. */
if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
usb_gadget_unregister_driver(&fsg_driver);
close_all_backing_files(fsg);
}
/* Let the unbind and cleanup routines know the thread has exited */
complete_and_exit(&fsg->thread_notifier, 0);
......@@ -3703,14 +3700,6 @@ static void close_backing_file(struct lun *curlun)
}
}
static void close_all_backing_files(struct fsg_dev *fsg)
{
int i;
for (i = 0; i < fsg->nluns; ++i)
close_backing_file(&fsg->luns[i]);
}
static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
{
......@@ -3845,6 +3834,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
if (curlun->registered) {
device_remove_file(&curlun->dev, &dev_attr_ro);
device_remove_file(&curlun->dev, &dev_attr_file);
close_backing_file(curlun);
device_unregister(&curlun->dev);
curlun->registered = 0;
}
......@@ -4190,7 +4180,6 @@ static int __init fsg_bind(struct usb_gadget *gadget)
out:
fsg->state = FSG_STATE_TERMINATED; // The thread is dead
fsg_unbind(gadget);
close_all_backing_files(fsg);
complete(&fsg->thread_notifier);
return rc;
}
......@@ -4284,7 +4273,6 @@ static void __exit fsg_cleanup(void)
/* Wait for the thread to finish up */
wait_for_completion(&fsg->thread_notifier);
close_all_backing_files(fsg);
kref_put(&fsg->ref, fsg_release);
}
module_exit(fsg_cleanup);
......@@ -3104,7 +3104,6 @@ static int omap_udc_resume(struct platform_device *dev)
/*-------------------------------------------------------------------------*/
static struct platform_driver udc_driver = {
.probe = omap_udc_probe,
.remove = __exit_p(omap_udc_remove),
.suspend = omap_udc_suspend,
.resume = omap_udc_resume,
......@@ -3122,7 +3121,7 @@ static int __init udc_init(void)
#endif
"%s\n", driver_desc,
use_dma ? " (dma)" : "");
return platform_driver_register(&udc_driver);
return platform_driver_probe(&udc_driver, omap_udc_probe);
}
module_init(udc_init);
......
......@@ -323,7 +323,7 @@ static int tt_available (
* already scheduled transactions
*/
if (125 < usecs) {
int ufs = (usecs / 125) - 1;
int ufs = (usecs / 125);
int i;
for (i = uframe; i < (uframe + ufs) && i < 8; i++)
if (0 < tt_usecs[i]) {
......
......@@ -2191,7 +2191,7 @@ static int musb_resume_early(struct platform_device *pdev)
#else
#define musb_suspend NULL
#define musb_resume NULL
#define musb_resume_early NULL
#endif
static struct platform_driver musb_driver = {
......
......@@ -3,7 +3,6 @@
* Some code has been taken from tusb6010.c
* Copyrights for that are attributable to:
* Copyright (C) 2006 Nokia Corporation
* Jarkko Nikula <jarkko.nikula@nokia.com>
* Tony Lindgren <tony@atomide.com>
*
* This file is part of the Inventra Controller Driver for Linux.
......
......@@ -2,7 +2,6 @@
* TUSB6010 USB 2.0 OTG Dual Role controller
*
* Copyright (C) 2006 Nokia Corporation
* Jarkko Nikula <jarkko.nikula@nokia.com>
* Tony Lindgren <tony@atomide.com>
*
* This program is free software; you can redistribute it and/or modify
......
......@@ -2,7 +2,6 @@
* Definitions for TUSB6010 USB 2.0 OTG Dual Role controller
*
* Copyright (C) 2006 Nokia Corporation
* Jarkko Nikula <jarkko.nikula@nokia.com>
* Tony Lindgren <tony@atomide.com>
*
* This program is free software; you can redistribute it and/or modify
......
......@@ -43,6 +43,7 @@ EXPORT_SYMBOL(otg_get_transceiver);
*/
void otg_put_transceiver(struct otg_transceiver *x)
{
if (x)
put_device(x->dev);
}
EXPORT_SYMBOL(otg_put_transceiver);
......
......@@ -175,13 +175,6 @@ static int cyberjack_open(struct tty_struct *tty,
dbg("%s - usb_clear_halt", __func__);
usb_clear_halt(port->serial->dev, port->write_urb->pipe);
/* force low_latency on so that our tty_push actually forces
* the data through, otherwise it is scheduled, and with high
* data rates (like with OHCI) data can get lost.
*/
if (tty)
tty->low_latency = 1;
priv = usb_get_serial_port_data(port);
spin_lock_irqsave(&priv->lock, flags);
priv->rdtodo = 0;
......
......@@ -656,10 +656,6 @@ static int cypress_open(struct tty_struct *tty,
priv->rx_flags = 0;
spin_unlock_irqrestore(&priv->lock, flags);
/* setting to zero could cause data loss */
if (tty)
tty->low_latency = 1;
/* raise both lines and set termios */
spin_lock_irqsave(&priv->lock, flags);
priv->line_control = CONTROL_DTR | CONTROL_RTS;
......
......@@ -478,12 +478,6 @@ static void empeg_set_termios(struct tty_struct *tty,
termios->c_cflag
|= CS8; /* character size 8 bits */
/*
* Force low_latency on; otherwise the pushes are scheduled;
* this is bad as it opens up the possibility of dropping bytes
* on the floor. We don't want to drop bytes on the floor. :)
*/
tty->low_latency = 1;
tty_encode_baud_rate(tty, 115200, 115200);
}
......
......@@ -973,14 +973,6 @@ static int garmin_open(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);
/*
* Force low_latency on so that our tty_push actually forces the data
* through, otherwise it is scheduled, and with high data rates (like
* with OHCI) data can get lost.
*/
if (tty)
tty->low_latency = 1;
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->mode = initial_mode;
garmin_data_p->count = 0;
......
......@@ -122,12 +122,6 @@ int usb_serial_generic_open(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);
/* force low_latency on so that our tty_push actually forces the data
through, otherwise it is scheduled, and with high data rates (like
with OHCI) data can get lost. */
if (tty)
tty->low_latency = 1;
/* clear the throttle flags */
spin_lock_irqsave(&port->lock, flags);
port->throttled = 0;
......
......@@ -193,8 +193,6 @@ static const struct divisor_table_entry divisor_table[] = {
/* local variables */
static int debug;
static int low_latency = 1; /* tty low latency flag, on by default */
static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */
......@@ -867,9 +865,6 @@ static int edge_open(struct tty_struct *tty,
if (edge_port == NULL)
return -ENODEV;
if (tty)
tty->low_latency = low_latency;
/* see if we've set up our endpoint info yet (can't set it up
in edge_startup as the structures were not set up at that time.) */
serial = port->serial;
......@@ -3299,6 +3294,3 @@ MODULE_FIRMWARE("edgeport/down2.fw");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(low_latency, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(low_latency, "Low latency enabled or not");
......@@ -76,7 +76,6 @@ struct edgeport_uart_buf_desc {
#define EDGE_READ_URB_STOPPING 1
#define EDGE_READ_URB_STOPPED 2
#define EDGE_LOW_LATENCY 1
#define EDGE_CLOSING_WAIT 4000 /* in .01 sec */
#define EDGE_OUT_BUF_SIZE 1024
......@@ -232,7 +231,6 @@ static unsigned short OperationalBuildNumber;
static int debug;
static int low_latency = EDGE_LOW_LATENCY;
static int closing_wait = EDGE_CLOSING_WAIT;
static int ignore_cpu_rev;
static int default_uart_mode; /* RS232 */
......@@ -1850,9 +1848,6 @@ static int edge_open(struct tty_struct *tty,
if (edge_port == NULL)
return -ENODEV;
if (tty)
tty->low_latency = low_latency;
port_number = port->number - port->serial->minor;
switch (port_number) {
case 0:
......@@ -3008,9 +3003,6 @@ MODULE_FIRMWARE("edgeport/down3.bin");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(low_latency, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(low_latency, "Low latency enabled or not");
module_param(closing_wait, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs");
......
......@@ -631,13 +631,7 @@ static int ipaq_open(struct tty_struct *tty,
priv->free_len += PACKET_SIZE;
}
/*
* Force low latency on. This will immediately push data to the line
* discipline instead of queueing.
*/
if (tty) {
tty->low_latency = 1;
/* FIXME: These two are bogus */
tty->raw = 1;
tty->real_raw = 1;
......
......@@ -207,9 +207,6 @@ static int ipw_open(struct tty_struct *tty,
if (!buf_flow_init)
return -ENOMEM;
if (tty)
tty->low_latency = 1;
/* --1: Tell the modem to initialize (we think) From sniffs this is
* always the first thing that gets sent to the modem during
* opening of the device */
......
......@@ -1051,7 +1051,6 @@ static int iuu_open(struct tty_struct *tty,
tty->termios->c_oflag = 0;
tty->termios->c_iflag = 0;
priv->termios_initialized = 1;
tty->low_latency = 1;
priv->poll = 0;
}
spin_unlock_irqrestore(&priv->lock, flags);
......
......@@ -231,13 +231,7 @@ static int kobil_open(struct tty_struct *tty,
/* someone sets the dev to 0 if the close method has been called */
port->interrupt_in_urb->dev = port->serial->dev;
/* force low_latency on so that our tty_push actually forces
* the data through, otherwise it is scheduled, and with high
* data rates (like with OHCI) data can get lost.
*/
if (tty) {
tty->low_latency = 1;
/* Default to echo off and other sane device settings */
tty->termios->c_lflag = 0;
......
......@@ -446,13 +446,6 @@ static int mos7720_open(struct tty_struct *tty,
data = 0x0c;
send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
/* force low_latency on so that our tty_push actually forces *
* the data through,otherwise it is scheduled, and with *
* high data rates (like with OHCI) data can get lost. */
if (tty)
tty->low_latency = 1;
/* see if we've set up our endpoint info yet *
* (can't set it up in mos7720_startup as the *
* structures were not set up at that time.) */
......
......@@ -38,7 +38,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "1.3.1"
#define DRIVER_VERSION "1.3.2"
#define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver"
/*
......@@ -123,6 +123,11 @@
#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
/* This driver also supports the ATEN UC2324 device since it is mos7840 based
* - if I knew the device id it would also support the ATEN UC2322 */
#define USB_VENDOR_ID_ATENINTL 0x0557
#define ATENINTL_DEVICE_ID_UC2324 0x2011
/* Interrupt Routine Defines */
#define SERIAL_IIR_RLS 0x06
......@@ -170,6 +175,7 @@ static struct usb_device_id moschip_port_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
{} /* terminating entry */
};
......@@ -178,6 +184,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
{} /* terminating entry */
};
......@@ -1000,12 +1007,6 @@ static int mos7840_open(struct tty_struct *tty,
status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
Data);
/* force low_latency on so that our tty_push actually forces *
* the data through,otherwise it is scheduled, and with *
* high data rates (like with OHCI) data can get lost. */
if (tty)
tty->low_latency = 1;
/* Check to see if we've set up our endpoint info yet *
* (can't set it up in mos7840_startup as the structures *
* were not set up at that time.) */
......@@ -2477,9 +2478,14 @@ static int mos7840_startup(struct usb_serial *serial)
mos7840_set_port_private(serial->port[i], mos7840_port);
spin_lock_init(&mos7840_port->pool_lock);
mos7840_port->port_num = ((serial->port[i]->number -
(serial->port[i]->serial->minor)) +
1);
/* minor is not initialised until later by
* usb-serial.c:get_free_serial() and cannot therefore be used
* to index device instances */
mos7840_port->port_num = i + 1;
dbg ("serial->port[i]->number = %d", serial->port[i]->number);
dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor);
dbg ("mos7840_port->port_num = %d", mos7840_port->port_num);
dbg ("serial->minor = %d", serial->minor);
if (mos7840_port->port_num == 1) {
mos7840_port->SpRegOffset = 0x0;
......@@ -2690,6 +2696,8 @@ static void mos7840_shutdown(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; ++i) {
mos7840_port = mos7840_get_port_private(serial->port[i]);
dbg ("mos7840_port %d = %p", i, mos7840_port);
if (mos7840_port) {
spin_lock_irqsave(&mos7840_port->pool_lock, flags);
mos7840_port->zombie = 1;
spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
......@@ -2697,6 +2705,7 @@ static void mos7840_shutdown(struct usb_serial *serial)
kfree(mos7840_port->ctrl_buf);
kfree(mos7840_port->dr);
kfree(mos7840_port);
}
mos7840_set_port_private(serial->port[i], NULL);
}
......
......@@ -159,14 +159,6 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port,
priv->port = port;
spin_unlock_irqrestore(&priv->lock, flags);
/*
* Force low_latency on so that our tty_push actually forces the data
* through, otherwise it is scheduled, and with high data rates (like
* with OHCI) data can get lost.
*/
if (tty)
tty->low_latency = 1;
/* Start reading from the device */
usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
usb_rcvbulkpipe(priv->udev,
......
......@@ -936,9 +936,6 @@ static int option_open(struct tty_struct *tty,
usb_pipeout(urb->pipe), 0); */
}
if (tty)
tty->low_latency = 1;
option_send_setup(tty, port);
return 0;
......
......@@ -14,7 +14,7 @@
Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
*/
#define DRIVER_VERSION "v.1.3.2"
#define DRIVER_VERSION "v.1.3.3"
#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
......@@ -259,9 +259,21 @@ static int sierra_send_setup(struct tty_struct *tty,
val |= 0x02;
/* If composite device then properly report interface */
if (serial->num_ports == 1)
if (serial->num_ports == 1) {
interface = sierra_calc_interface(serial);
/* Control message is sent only to interfaces with
* interrupt_in endpoints
*/
if (port->interrupt_in_urb) {
/* send control message */
return usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
0x22, 0x21, val, interface,
NULL, 0, USB_CTRL_SET_TIMEOUT);
}
}
/* Otherwise the need to do non-composite mapping */
else {
if (port->bulk_out_endpointAddress == 2)
......@@ -270,12 +282,13 @@ static int sierra_send_setup(struct tty_struct *tty,
interface = 1;
else if (port->bulk_out_endpointAddress == 5)
interface = 2;
}
return usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
0x22, 0x21, val, interface,
NULL, 0, USB_CTRL_SET_TIMEOUT);
}
}
return 0;
......@@ -585,9 +598,6 @@ static int sierra_open(struct tty_struct *tty,
}
}
if (tty)
tty->low_latency = 1;
sierra_send_setup(tty, port);
/* start up the interrupt endpoint if we have one */
......
......@@ -50,11 +50,10 @@
#define TI_TRANSFER_TIMEOUT 2
#define TI_DEFAULT_LOW_LATENCY 0
#define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */
/* supported setserial flags */
#define TI_SET_SERIAL_FLAGS (ASYNC_LOW_LATENCY)
#define TI_SET_SERIAL_FLAGS 0
/* read urb states */
#define TI_READ_URB_RUNNING 0
......@@ -161,7 +160,6 @@ static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
/* module parameters */
static int debug;
static int low_latency = TI_DEFAULT_LOW_LATENCY;
static int closing_wait = TI_DEFAULT_CLOSING_WAIT;
static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT];
static unsigned int vendor_3410_count;
......@@ -296,10 +294,6 @@ MODULE_FIRMWARE("mts_edge.fw");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
module_param(low_latency, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(low_latency,
"TTY low_latency flag, 0=off, 1=on, default is off");
module_param(closing_wait, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(closing_wait,
"Maximum wait for data to drain in close, in .01 secs, default is 4000");
......@@ -448,7 +442,6 @@ static int ti_startup(struct usb_serial *serial)
spin_lock_init(&tport->tp_lock);
tport->tp_uart_base_addr = (i == 0 ?
TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
tport->tp_closing_wait = closing_wait;
init_waitqueue_head(&tport->tp_msr_wait);
init_waitqueue_head(&tport->tp_write_wait);
......@@ -528,10 +521,6 @@ static int ti_open(struct tty_struct *tty,
if (mutex_lock_interruptible(&tdev->td_open_close_lock))
return -ERESTARTSYS;
if (tty)
tty->low_latency =
(tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
port_number = port->number - port->serial->minor;
memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount));
......@@ -1454,7 +1443,6 @@ static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
return -EFAULT;
tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
tport->tp_closing_wait = new_serial.closing_wait;
return 0;
......
......@@ -137,22 +137,10 @@ static void destroy_serial(struct kref *kref)
dbg("%s - %s", __func__, serial->type->description);
serial->type->shutdown(serial);
/* return the minor range that this device had */
if (serial->minor != SERIAL_TTY_NO_MINOR)
return_serial(serial);
for (i = 0; i < serial->num_ports; ++i)
serial->port[i]->port.count = 0;
/* the ports are cleaned up and released in port_release() */
for (i = 0; i < serial->num_ports; ++i)
if (serial->port[i]->dev.parent != NULL) {
device_unregister(&serial->port[i]->dev);
serial->port[i] = NULL;
}
/* If this is a "fake" port, we have to clean it up here, as it will
* not get cleaned up in port_release() as it was never registered with
* the driver core */
......@@ -187,7 +175,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
struct usb_serial *serial;
struct usb_serial_port *port;
unsigned int portNumber;
int retval;
int retval = 0;
dbg("%s", __func__);
......@@ -198,21 +186,24 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
return -ENODEV;
}
mutex_lock(&serial->disc_mutex);
portNumber = tty->index - serial->minor;
port = serial->port[portNumber];
if (!port) {
retval = -ENODEV;
goto bailout_kref_put;
}
if (port->serial->disconnected) {
if (!port || serial->disconnected)
retval = -ENODEV;
goto bailout_kref_put;
}
else
get_device(&port->dev);
/*
* Note: Our locking order requirement does not allow port->mutex
* to be acquired while serial->disc_mutex is held.
*/
mutex_unlock(&serial->disc_mutex);
if (retval)
goto bailout_serial_put;
if (mutex_lock_interruptible(&port->mutex)) {
retval = -ERESTARTSYS;
goto bailout_kref_put;
goto bailout_port_put;
}
++port->port.count;
......@@ -232,14 +223,20 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
goto bailout_mutex_unlock;
}
mutex_lock(&serial->disc_mutex);
if (serial->disconnected)
retval = -ENODEV;
else
retval = usb_autopm_get_interface(serial->interface);
if (retval)
goto bailout_module_put;
/* only call the device specific open if this
* is the first time the port is opened */
retval = serial->type->open(tty, port, filp);
if (retval)
goto bailout_interface_put;
mutex_unlock(&serial->disc_mutex);
}
mutex_unlock(&port->mutex);
......@@ -248,13 +245,16 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
bailout_interface_put:
usb_autopm_put_interface(serial->interface);
bailout_module_put:
mutex_unlock(&serial->disc_mutex);
module_put(serial->type->driver.owner);
bailout_mutex_unlock:
port->port.count = 0;
tty->driver_data = NULL;
tty_port_tty_set(&port->port, NULL);
mutex_unlock(&port->mutex);
bailout_kref_put:
bailout_port_put:
put_device(&port->dev);
bailout_serial_put:
usb_serial_put(serial);
return retval;
}
......@@ -262,6 +262,9 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
static void serial_close(struct tty_struct *tty, struct file *filp)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial;
struct module *owner;
int count;
if (!port)
return;
......@@ -269,6 +272,8 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
dbg("%s - port %d", __func__, port->number);
mutex_lock(&port->mutex);
serial = port->serial;
owner = serial->type->driver.owner;
if (port->port.count == 0) {
mutex_unlock(&port->mutex);
......@@ -281,7 +286,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
* this before we drop the port count. The call is protected
* by the port mutex
*/
port->serial->type->close(tty, port, filp);
serial->type->close(tty, port, filp);
if (port->port.count == (port->console ? 2 : 1)) {
struct tty_struct *tty = tty_port_tty_get(&port->port);
......@@ -295,17 +300,23 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
}
}
if (port->port.count == 1) {
mutex_lock(&port->serial->disc_mutex);
if (!port->serial->disconnected)
usb_autopm_put_interface(port->serial->interface);
mutex_unlock(&port->serial->disc_mutex);
module_put(port->serial->type->driver.owner);
}
--port->port.count;
count = port->port.count;
mutex_unlock(&port->mutex);
usb_serial_put(port->serial);
put_device(&port->dev);
/* Mustn't dereference port any more */
if (count == 0) {
mutex_lock(&serial->disc_mutex);
if (!serial->disconnected)
usb_autopm_put_interface(serial->interface);
mutex_unlock(&serial->disc_mutex);
}
usb_serial_put(serial);
/* Mustn't dereference serial any more */
if (count == 0)
module_put(owner);
}
static int serial_write(struct tty_struct *tty, const unsigned char *buf,
......@@ -549,7 +560,13 @@ static void kill_traffic(struct usb_serial_port *port)
static void port_free(struct usb_serial_port *port)
{
/*
* Stop all the traffic before cancelling the work, so that
* nobody will restart it by calling usb_serial_port_softint.
*/
kill_traffic(port);
cancel_work_sync(&port->work);
usb_free_urb(port->read_urb);
usb_free_urb(port->write_urb);
usb_free_urb(port->interrupt_in_urb);
......@@ -558,7 +575,6 @@ static void port_free(struct usb_serial_port *port)
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
kfree(port->interrupt_out_buffer);
flush_scheduled_work(); /* port->work */
kfree(port);
}
......@@ -1043,6 +1059,12 @@ void usb_serial_disconnect(struct usb_interface *interface)
usb_set_intfdata(interface, NULL);
/* must set a flag, to signal subdrivers */
serial->disconnected = 1;
mutex_unlock(&serial->disc_mutex);
/* Unfortunately, many of the sub-drivers expect the port structures
* to exist when their shutdown method is called, so we have to go
* through this awkward two-step unregistration procedure.
*/
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port) {
......@@ -1052,11 +1074,21 @@ void usb_serial_disconnect(struct usb_interface *interface)
tty_kref_put(tty);
}
kill_traffic(port);
cancel_work_sync(&port->work);
device_del(&port->dev);
}
}
serial->type->shutdown(serial);
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port) {
put_device(&port->dev);
serial->port[i] = NULL;
}
}
/* let the last holder of this object
* cause it to be cleaned up */
mutex_unlock(&serial->disc_mutex);
usb_serial_put(serial);
dev_info(dev, "device disconnected\n");
}
......
......@@ -296,14 +296,6 @@ static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
priv->throttled = 0;
spin_unlock_irqrestore(&priv->lock, flags);
/*
* Force low_latency on so that our tty_push actually forces the data
* through, otherwise it is scheduled, and with high data rates (like
* with OHCI) data can get lost.
*/
if (tty)
tty->low_latency = 1;
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev,
......
......@@ -1851,6 +1851,12 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_CAPACITY_HEURISTICS),
/* Reported by Alessio Treglia <quadrispro@ubuntu.com> */
UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001,
"TGE",
"Digital MP3 Audio Player",
US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
/* Control/Bulk transport for all SubClass values */
USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
......
......@@ -7,6 +7,9 @@
* key configuration differences between boards.
*/
#ifndef __LINUX_USB_MUSB_H
#define __LINUX_USB_MUSB_H
/* The USB role is defined by the connector used on the board, so long as
* standards are being followed. (Developer boards sometimes won't.)
*/
......@@ -101,3 +104,5 @@ extern int __init tusb6010_setup_interface(
extern int tusb6010_platform_retime(unsigned is_refclk);
#endif /* OMAP2 */
#endif /* __LINUX_USB_MUSB_H */
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