USB fixes for 3.9-rc3
Here are a number of USB fixes that resolve issues that have been reported against 3.9-rc3. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlFMnR0ACgkQMUfUDdst+yliJwCeNOJ0bz7Crzs3NepnRWHaHJ0Z OmQAnRvQMX1OpqDCsjnc7RW2gL/2TDNd =05gg -----END PGP SIGNATURE----- Merge tag 'usb-3.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg Kroah-Hartman: "Here are a number of USB fixes that resolve issues that have been reported against 3.9-rc3." * tag 'usb-3.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (37 commits) USB: ti_usb_3410_5052: fix use-after-free in TIOCMIWAIT USB: ssu100: fix use-after-free in TIOCMIWAIT USB: spcp8x5: fix use-after-free in TIOCMIWAIT USB: quatech2: fix use-after-free in TIOCMIWAIT USB: pl2303: fix use-after-free in TIOCMIWAIT USB: oti6858: fix use-after-free in TIOCMIWAIT USB: mos7840: fix use-after-free in TIOCMIWAIT USB: mos7840: fix broken TIOCMIWAIT USB: mct_u232: fix use-after-free in TIOCMIWAIT USB: io_ti: fix use-after-free in TIOCMIWAIT USB: io_edgeport: fix use-after-free in TIOCMIWAIT USB: ftdi_sio: fix use-after-free in TIOCMIWAIT USB: f81232: fix use-after-free in TIOCMIWAIT USB: cypress_m8: fix use-after-free in TIOCMIWAIT USB: ch341: fix use-after-free in TIOCMIWAIT USB: ark3116: fix use-after-free in TIOCMIWAIT USB: serial: add modem-status-change wait queue USB: serial: fix interface refcounting USB: io_ti: fix get_icount for two port adapters USB: garmin_gps: fix memory leak on disconnect ...
This commit is contained in:
commit
8f46c507a2
|
@ -593,7 +593,6 @@ static void acm_port_destruct(struct tty_port *port)
|
|||
|
||||
dev_dbg(&acm->control->dev, "%s\n", __func__);
|
||||
|
||||
tty_unregister_device(acm_tty_driver, acm->minor);
|
||||
acm_release_minor(acm);
|
||||
usb_put_intf(acm->control);
|
||||
kfree(acm->country_codes);
|
||||
|
@ -977,6 +976,8 @@ static int acm_probe(struct usb_interface *intf,
|
|||
int num_rx_buf;
|
||||
int i;
|
||||
int combined_interfaces = 0;
|
||||
struct device *tty_dev;
|
||||
int rv = -ENOMEM;
|
||||
|
||||
/* normal quirks */
|
||||
quirks = (unsigned long)id->driver_info;
|
||||
|
@ -1339,11 +1340,24 @@ skip_countries:
|
|||
usb_set_intfdata(data_interface, acm);
|
||||
|
||||
usb_get_intf(control_interface);
|
||||
tty_port_register_device(&acm->port, acm_tty_driver, minor,
|
||||
tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
|
||||
&control_interface->dev);
|
||||
if (IS_ERR(tty_dev)) {
|
||||
rv = PTR_ERR(tty_dev);
|
||||
goto alloc_fail8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
alloc_fail8:
|
||||
if (acm->country_codes) {
|
||||
device_remove_file(&acm->control->dev,
|
||||
&dev_attr_wCountryCodes);
|
||||
device_remove_file(&acm->control->dev,
|
||||
&dev_attr_iCountryCodeRelDate);
|
||||
}
|
||||
device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
|
||||
alloc_fail7:
|
||||
usb_set_intfdata(intf, NULL);
|
||||
for (i = 0; i < ACM_NW; i++)
|
||||
usb_free_urb(acm->wb[i].urb);
|
||||
alloc_fail6:
|
||||
|
@ -1359,7 +1373,7 @@ alloc_fail2:
|
|||
acm_release_minor(acm);
|
||||
kfree(acm);
|
||||
alloc_fail:
|
||||
return -ENOMEM;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void stop_data_traffic(struct acm *acm)
|
||||
|
@ -1411,6 +1425,8 @@ static void acm_disconnect(struct usb_interface *intf)
|
|||
|
||||
stop_data_traffic(acm);
|
||||
|
||||
tty_unregister_device(acm_tty_driver, acm->minor);
|
||||
|
||||
usb_free_urb(acm->ctrlurb);
|
||||
for (i = 0; i < ACM_NW; i++)
|
||||
usb_free_urb(acm->wb[i].urb);
|
||||
|
|
|
@ -173,6 +173,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
struct hc_driver *driver;
|
||||
struct usb_hcd *hcd;
|
||||
int retval;
|
||||
int hcd_irq = 0;
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
@ -187,15 +188,19 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
return -ENODEV;
|
||||
dev->current_state = PCI_D0;
|
||||
|
||||
/* The xHCI driver supports MSI and MSI-X,
|
||||
* so don't fail if the BIOS doesn't provide a legacy IRQ.
|
||||
/*
|
||||
* The xHCI driver has its own irq management
|
||||
* make sure irq setup is not touched for xhci in generic hcd code
|
||||
*/
|
||||
if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
|
||||
dev_err(&dev->dev,
|
||||
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
|
||||
pci_name(dev));
|
||||
retval = -ENODEV;
|
||||
goto disable_pci;
|
||||
if ((driver->flags & HCD_MASK) != HCD_USB3) {
|
||||
if (!dev->irq) {
|
||||
dev_err(&dev->dev,
|
||||
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
|
||||
pci_name(dev));
|
||||
retval = -ENODEV;
|
||||
goto disable_pci;
|
||||
}
|
||||
hcd_irq = dev->irq;
|
||||
}
|
||||
|
||||
hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
|
||||
|
@ -245,7 +250,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
|
||||
pci_set_master(dev);
|
||||
|
||||
retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
|
||||
retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED);
|
||||
if (retval != 0)
|
||||
goto unmap_registers;
|
||||
set_hs_companion(dev, hcd);
|
||||
|
|
|
@ -447,14 +447,13 @@ static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)
|
|||
static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
struct f_rndis *rndis = req->context;
|
||||
struct usb_composite_dev *cdev = rndis->port.func.config->cdev;
|
||||
int status;
|
||||
|
||||
/* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
|
||||
// spin_lock(&dev->lock);
|
||||
status = rndis_msg_parser(rndis->config, (u8 *) req->buf);
|
||||
if (status < 0)
|
||||
ERROR(cdev, "RNDIS command error %d, %d/%d\n",
|
||||
pr_err("RNDIS command error %d, %d/%d\n",
|
||||
status, req->actual, req->length);
|
||||
// spin_unlock(&dev->lock);
|
||||
}
|
||||
|
|
|
@ -357,7 +357,7 @@ static int gfs_bind(struct usb_composite_dev *cdev)
|
|||
goto error;
|
||||
gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
|
||||
|
||||
for (i = func_num; --i; ) {
|
||||
for (i = func_num; i--; ) {
|
||||
ret = functionfs_bind(ffs_tab[i].ffs_data, cdev);
|
||||
if (unlikely(ret < 0)) {
|
||||
while (++i < func_num)
|
||||
|
@ -413,7 +413,7 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
|
|||
gether_cleanup();
|
||||
gfs_ether_setup = false;
|
||||
|
||||
for (i = func_num; --i; )
|
||||
for (i = func_num; i--; )
|
||||
if (ffs_tab[i].ffs_data)
|
||||
functionfs_unbind(ffs_tab[i].ffs_data);
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ static const char * const ep_name[] = {
|
|||
};
|
||||
|
||||
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
|
||||
#ifdef CONFIG_USB_GADGET_NET2272_DMA
|
||||
#ifdef CONFIG_USB_NET2272_DMA
|
||||
/*
|
||||
* use_dma: the NET2272 can use an external DMA controller.
|
||||
* Note that since there is no generic DMA api, some functions,
|
||||
|
@ -1495,6 +1495,13 @@ stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver)
|
|||
for (i = 0; i < 4; ++i)
|
||||
net2272_dequeue_all(&dev->ep[i]);
|
||||
|
||||
/* report disconnect; the driver is already quiesced */
|
||||
if (driver) {
|
||||
spin_unlock(&dev->lock);
|
||||
driver->disconnect(&dev->gadget);
|
||||
spin_lock(&dev->lock);
|
||||
}
|
||||
|
||||
net2272_usb_reinit(dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -1924,7 +1924,6 @@ static int net2280_start(struct usb_gadget *_gadget,
|
|||
err_func:
|
||||
device_remove_file (&dev->pdev->dev, &dev_attr_function);
|
||||
err_unbind:
|
||||
driver->unbind (&dev->gadget);
|
||||
dev->gadget.dev.driver = NULL;
|
||||
dev->driver = NULL;
|
||||
return retval;
|
||||
|
@ -1946,6 +1945,13 @@ stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
|
|||
for (i = 0; i < 7; i++)
|
||||
nuke (&dev->ep [i]);
|
||||
|
||||
/* report disconnect; the driver is already quiesced */
|
||||
if (driver) {
|
||||
spin_unlock(&dev->lock);
|
||||
driver->disconnect(&dev->gadget);
|
||||
spin_lock(&dev->lock);
|
||||
}
|
||||
|
||||
usb_reinit (dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ static struct portmaster {
|
|||
pr_debug(fmt, ##arg)
|
||||
#endif /* pr_vdebug */
|
||||
#else
|
||||
#ifndef pr_vdebig
|
||||
#ifndef pr_vdebug
|
||||
#define pr_vdebug(fmt, arg...) \
|
||||
({ if (0) pr_debug(fmt, ##arg); })
|
||||
#endif /* pr_vdebug */
|
||||
|
|
|
@ -216,7 +216,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
|
|||
usb_gadget_disconnect(udc->gadget);
|
||||
udc->driver->disconnect(udc->gadget);
|
||||
udc->driver->unbind(udc->gadget);
|
||||
usb_gadget_udc_stop(udc->gadget, udc->driver);
|
||||
usb_gadget_udc_stop(udc->gadget, NULL);
|
||||
|
||||
udc->driver = NULL;
|
||||
udc->dev.driver = NULL;
|
||||
|
|
|
@ -302,6 +302,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
|
|||
|
||||
static void end_unlink_async(struct ehci_hcd *ehci);
|
||||
static void unlink_empty_async(struct ehci_hcd *ehci);
|
||||
static void unlink_empty_async_suspended(struct ehci_hcd *ehci);
|
||||
static void ehci_work(struct ehci_hcd *ehci);
|
||||
static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
|
||||
static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
|
||||
|
|
|
@ -328,7 +328,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|||
ehci->rh_state = EHCI_RH_SUSPENDED;
|
||||
|
||||
end_unlink_async(ehci);
|
||||
unlink_empty_async(ehci);
|
||||
unlink_empty_async_suspended(ehci);
|
||||
ehci_handle_intr_unlinks(ehci);
|
||||
end_free_itds(ehci);
|
||||
|
||||
|
|
|
@ -1316,6 +1316,19 @@ static void unlink_empty_async(struct ehci_hcd *ehci)
|
|||
}
|
||||
}
|
||||
|
||||
/* The root hub is suspended; unlink all the async QHs */
|
||||
static void unlink_empty_async_suspended(struct ehci_hcd *ehci)
|
||||
{
|
||||
struct ehci_qh *qh;
|
||||
|
||||
while (ehci->async->qh_next.qh) {
|
||||
qh = ehci->async->qh_next.qh;
|
||||
WARN_ON(!list_empty(&qh->qtd_list));
|
||||
single_unlink_async(ehci, qh);
|
||||
}
|
||||
start_iaa_cycle(ehci, false);
|
||||
}
|
||||
|
||||
/* makes sure the async qh will become idle */
|
||||
/* caller must own ehci->lock */
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci)
|
|||
* (a) SMP races against real IAA firing and retriggering, and
|
||||
* (b) clean HC shutdown, when IAA watchdog was pending.
|
||||
*/
|
||||
if (ehci->async_iaa) {
|
||||
if (1) {
|
||||
u32 cmd, status;
|
||||
|
||||
/* If we get here, IAA is *REALLY* late. It's barely
|
||||
|
|
|
@ -350,7 +350,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
|
|||
* generate interrupts. Don't even try to enable MSI.
|
||||
*/
|
||||
if (xhci->quirks & XHCI_BROKEN_MSI)
|
||||
return 0;
|
||||
goto legacy_irq;
|
||||
|
||||
/* unregister the legacy interrupt */
|
||||
if (hcd->irq)
|
||||
|
@ -371,6 +371,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
legacy_irq:
|
||||
/* fall back to legacy interrupt*/
|
||||
ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
|
||||
hcd->irq_descr, hcd);
|
||||
|
|
|
@ -206,8 +206,8 @@ struct xhci_op_regs {
|
|||
/* bits 12:31 are reserved (and should be preserved on writes). */
|
||||
|
||||
/* IMAN - Interrupt Management Register */
|
||||
#define IMAN_IP (1 << 1)
|
||||
#define IMAN_IE (1 << 0)
|
||||
#define IMAN_IE (1 << 1)
|
||||
#define IMAN_IP (1 << 0)
|
||||
|
||||
/* USBSTS - USB status - status bitmasks */
|
||||
/* HC not running - set to 1 when run/stop bit is cleared. */
|
||||
|
|
|
@ -327,7 +327,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
|
|||
u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
|
||||
int err;
|
||||
|
||||
err = musb->int_usb & USB_INTR_VBUSERROR;
|
||||
err = musb->int_usb & MUSB_INTR_VBUSERROR;
|
||||
if (err) {
|
||||
/*
|
||||
* The Mentor core doesn't debounce VBUS as needed
|
||||
|
|
|
@ -141,7 +141,9 @@ static inline void map_dma_buffer(struct musb_request *request,
|
|||
static inline void unmap_dma_buffer(struct musb_request *request,
|
||||
struct musb *musb)
|
||||
{
|
||||
if (!is_buffer_mapped(request))
|
||||
struct musb_ep *musb_ep = request->ep;
|
||||
|
||||
if (!is_buffer_mapped(request) || !musb_ep->dma)
|
||||
return;
|
||||
|
||||
if (request->request.dma == DMA_ADDR_INVALID) {
|
||||
|
@ -195,7 +197,10 @@ __acquires(ep->musb->lock)
|
|||
|
||||
ep->busy = 1;
|
||||
spin_unlock(&musb->lock);
|
||||
unmap_dma_buffer(req, musb);
|
||||
|
||||
if (!dma_mapping_error(&musb->g.dev, request->dma))
|
||||
unmap_dma_buffer(req, musb);
|
||||
|
||||
if (request->status == 0)
|
||||
dev_dbg(musb->controller, "%s done request %p, %d/%d\n",
|
||||
ep->end_point.name, request,
|
||||
|
|
|
@ -62,7 +62,6 @@ static int is_irda(struct usb_serial *serial)
|
|||
}
|
||||
|
||||
struct ark3116_private {
|
||||
wait_queue_head_t delta_msr_wait;
|
||||
struct async_icount icount;
|
||||
int irda; /* 1 for irda device */
|
||||
|
||||
|
@ -146,7 +145,6 @@ static int ark3116_port_probe(struct usb_serial_port *port)
|
|||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
mutex_init(&priv->hw_lock);
|
||||
spin_lock_init(&priv->status_lock);
|
||||
|
||||
|
@ -456,10 +454,14 @@ static int ark3116_ioctl(struct tty_struct *tty,
|
|||
case TIOCMIWAIT:
|
||||
for (;;) {
|
||||
struct async_icount prev = priv->icount;
|
||||
interruptible_sleep_on(&priv->delta_msr_wait);
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
if ((prev.rng == priv->icount.rng) &&
|
||||
(prev.dsr == priv->icount.dsr) &&
|
||||
(prev.dcd == priv->icount.dcd) &&
|
||||
|
@ -580,7 +582,7 @@ static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr)
|
|||
priv->icount.dcd++;
|
||||
if (msr & UART_MSR_TERI)
|
||||
priv->icount.rng++;
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
|
|||
|
||||
struct ch341_private {
|
||||
spinlock_t lock; /* access lock */
|
||||
wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
|
||||
unsigned baud_rate; /* set baud rate */
|
||||
u8 line_control; /* set line control value RTS/DTR */
|
||||
u8 line_status; /* active status of modem control inputs */
|
||||
|
@ -252,7 +251,6 @@ static int ch341_port_probe(struct usb_serial_port *port)
|
|||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
priv->baud_rate = DEFAULT_BAUD_RATE;
|
||||
priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
|
||||
|
||||
|
@ -298,7 +296,7 @@ static void ch341_dtr_rts(struct usb_serial_port *port, int on)
|
|||
priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
ch341_set_handshake(port->serial->dev, priv->line_control);
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
}
|
||||
|
||||
static void ch341_close(struct usb_serial_port *port)
|
||||
|
@ -491,7 +489,7 @@ static void ch341_read_int_callback(struct urb *urb)
|
|||
tty_kref_put(tty);
|
||||
}
|
||||
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
@ -517,11 +515,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
|
|||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
while (!multi_change) {
|
||||
interruptible_sleep_on(&priv->delta_msr_wait);
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
status = priv->line_status;
|
||||
multi_change = priv->multi_status_change;
|
||||
|
|
|
@ -111,7 +111,6 @@ struct cypress_private {
|
|||
int baud_rate; /* stores current baud rate in
|
||||
integer form */
|
||||
int isthrottled; /* if throttled, discard reads */
|
||||
wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
|
||||
char prev_status, diff_status; /* used for TIOCMIWAIT */
|
||||
/* we pass a pointer to this as the argument sent to
|
||||
cypress_set_termios old_termios */
|
||||
|
@ -449,7 +448,6 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
|
|||
kfree(priv);
|
||||
return -ENOMEM;
|
||||
}
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
|
||||
usb_reset_configuration(serial->dev);
|
||||
|
||||
|
@ -868,12 +866,16 @@ static int cypress_ioctl(struct tty_struct *tty,
|
|||
switch (cmd) {
|
||||
/* This code comes from drivers/char/serial.c and ftdi_sio.c */
|
||||
case TIOCMIWAIT:
|
||||
while (priv != NULL) {
|
||||
interruptible_sleep_on(&priv->delta_msr_wait);
|
||||
for (;;) {
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
else {
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
{
|
||||
char diff = priv->diff_status;
|
||||
if (diff == 0)
|
||||
return -EIO; /* no change => error */
|
||||
|
@ -1187,7 +1189,7 @@ static void cypress_read_int_callback(struct urb *urb)
|
|||
if (priv->current_status != priv->prev_status) {
|
||||
priv->diff_status |= priv->current_status ^
|
||||
priv->prev_status;
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
priv->prev_status = priv->current_status;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
|
|
@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
|
|||
|
||||
struct f81232_private {
|
||||
spinlock_t lock;
|
||||
wait_queue_head_t delta_msr_wait;
|
||||
u8 line_control;
|
||||
u8 line_status;
|
||||
};
|
||||
|
@ -111,7 +110,7 @@ static void f81232_process_read_urb(struct urb *urb)
|
|||
line_status = priv->line_status;
|
||||
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
|
||||
if (!urb->actual_length)
|
||||
return;
|
||||
|
@ -256,11 +255,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
|
|||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
while (1) {
|
||||
interruptible_sleep_on(&priv->delta_msr_wait);
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
status = priv->line_status;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
@ -322,7 +324,6 @@ static int f81232_port_probe(struct usb_serial_port *port)
|
|||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
|
|
|
@ -69,9 +69,7 @@ struct ftdi_private {
|
|||
int flags; /* some ASYNC_xxxx flags are supported */
|
||||
unsigned long last_dtr_rts; /* saved modem control outputs */
|
||||
struct async_icount icount;
|
||||
wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
|
||||
char prev_status; /* Used for TIOCMIWAIT */
|
||||
bool dev_gone; /* Used to abort TIOCMIWAIT */
|
||||
char transmit_empty; /* If transmitter is empty or not */
|
||||
__u16 interface; /* FT2232C, FT2232H or FT4232H port interface
|
||||
(0 for FT232/245) */
|
||||
|
@ -1691,10 +1689,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
|
|||
|
||||
kref_init(&priv->kref);
|
||||
mutex_init(&priv->cfg_lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
|
||||
priv->flags = ASYNC_LOW_LATENCY;
|
||||
priv->dev_gone = false;
|
||||
|
||||
if (quirk && quirk->port_probe)
|
||||
quirk->port_probe(priv);
|
||||
|
@ -1840,8 +1836,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
|
|||
{
|
||||
struct ftdi_private *priv = usb_get_serial_port_data(port);
|
||||
|
||||
priv->dev_gone = true;
|
||||
wake_up_interruptible_all(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
|
||||
remove_sysfs_attrs(port);
|
||||
|
||||
|
@ -1989,7 +1984,7 @@ static int ftdi_process_packet(struct usb_serial_port *port,
|
|||
if (diff_status & FTDI_RS0_RLSD)
|
||||
priv->icount.dcd++;
|
||||
|
||||
wake_up_interruptible_all(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
priv->prev_status = status;
|
||||
}
|
||||
|
||||
|
@ -2440,11 +2435,15 @@ static int ftdi_ioctl(struct tty_struct *tty,
|
|||
*/
|
||||
case TIOCMIWAIT:
|
||||
cprev = priv->icount;
|
||||
while (!priv->dev_gone) {
|
||||
interruptible_sleep_on(&priv->delta_msr_wait);
|
||||
for (;;) {
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
cnow = priv->icount;
|
||||
if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
|
||||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
|
||||
|
@ -2454,8 +2453,6 @@ static int ftdi_ioctl(struct tty_struct *tty,
|
|||
}
|
||||
cprev = cnow;
|
||||
}
|
||||
return -EIO;
|
||||
break;
|
||||
case TIOCSERGETLSR:
|
||||
return get_lsr_info(port, (struct serial_struct __user *)arg);
|
||||
break;
|
||||
|
|
|
@ -956,10 +956,7 @@ static void garmin_close(struct usb_serial_port *port)
|
|||
if (!serial)
|
||||
return;
|
||||
|
||||
mutex_lock(&port->serial->disc_mutex);
|
||||
|
||||
if (!port->serial->disconnected)
|
||||
garmin_clear(garmin_data_p);
|
||||
garmin_clear(garmin_data_p);
|
||||
|
||||
/* shutdown our urbs */
|
||||
usb_kill_urb(port->read_urb);
|
||||
|
@ -968,8 +965,6 @@ static void garmin_close(struct usb_serial_port *port)
|
|||
/* keep reset state so we know that we must start a new session */
|
||||
if (garmin_data_p->state != STATE_RESET)
|
||||
garmin_data_p->state = STATE_DISCONNECTED;
|
||||
|
||||
mutex_unlock(&port->serial->disc_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -110,7 +110,6 @@ struct edgeport_port {
|
|||
wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
|
||||
wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */
|
||||
wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */
|
||||
wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
|
||||
|
||||
struct async_icount icount;
|
||||
struct usb_serial_port *port; /* loop back to the owner of this object */
|
||||
|
@ -884,7 +883,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
/* initialize our wait queues */
|
||||
init_waitqueue_head(&edge_port->wait_open);
|
||||
init_waitqueue_head(&edge_port->wait_chase);
|
||||
init_waitqueue_head(&edge_port->delta_msr_wait);
|
||||
init_waitqueue_head(&edge_port->wait_command);
|
||||
|
||||
/* initialize our icount structure */
|
||||
|
@ -1669,13 +1667,17 @@ static int edge_ioctl(struct tty_struct *tty,
|
|||
dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__, port->number);
|
||||
cprev = edge_port->icount;
|
||||
while (1) {
|
||||
prepare_to_wait(&edge_port->delta_msr_wait,
|
||||
prepare_to_wait(&port->delta_msr_wait,
|
||||
&wait, TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
finish_wait(&edge_port->delta_msr_wait, &wait);
|
||||
finish_wait(&port->delta_msr_wait, &wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
cnow = edge_port->icount;
|
||||
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
|
||||
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
|
||||
|
@ -2051,7 +2053,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr)
|
|||
icount->dcd++;
|
||||
if (newMsr & EDGEPORT_MSR_DELTA_RI)
|
||||
icount->rng++;
|
||||
wake_up_interruptible(&edge_port->delta_msr_wait);
|
||||
wake_up_interruptible(&edge_port->port->delta_msr_wait);
|
||||
}
|
||||
|
||||
/* Save the new modem status */
|
||||
|
|
|
@ -87,9 +87,6 @@ struct edgeport_port {
|
|||
int close_pending;
|
||||
int lsr_event;
|
||||
struct async_icount icount;
|
||||
wait_queue_head_t delta_msr_wait; /* for handling sleeping while
|
||||
waiting for msr change to
|
||||
happen */
|
||||
struct edgeport_serial *edge_serial;
|
||||
struct usb_serial_port *port;
|
||||
__u8 bUartMode; /* Port type, 0: RS232, etc. */
|
||||
|
@ -1459,7 +1456,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
|
|||
icount->dcd++;
|
||||
if (msr & EDGEPORT_MSR_DELTA_RI)
|
||||
icount->rng++;
|
||||
wake_up_interruptible(&edge_port->delta_msr_wait);
|
||||
wake_up_interruptible(&edge_port->port->delta_msr_wait);
|
||||
}
|
||||
|
||||
/* Save the new modem status */
|
||||
|
@ -1754,7 +1751,6 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
dev = port->serial->dev;
|
||||
|
||||
memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
|
||||
init_waitqueue_head(&edge_port->delta_msr_wait);
|
||||
|
||||
/* turn off loopback */
|
||||
status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
|
||||
|
@ -2434,10 +2430,14 @@ static int edge_ioctl(struct tty_struct *tty,
|
|||
dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
|
||||
cprev = edge_port->icount;
|
||||
while (1) {
|
||||
interruptible_sleep_on(&edge_port->delta_msr_wait);
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
cnow = edge_port->icount;
|
||||
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
|
||||
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
|
||||
|
@ -2649,6 +2649,7 @@ static struct usb_serial_driver edgeport_2port_device = {
|
|||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
.tiocmset = edge_tiocmset,
|
||||
.get_icount = edge_get_icount,
|
||||
.write = edge_write,
|
||||
.write_room = edge_write_room,
|
||||
.chars_in_buffer = edge_chars_in_buffer,
|
||||
|
|
|
@ -114,8 +114,6 @@ struct mct_u232_private {
|
|||
unsigned char last_msr; /* Modem Status Register */
|
||||
unsigned int rx_flags; /* Throttling flags */
|
||||
struct async_icount icount;
|
||||
wait_queue_head_t msr_wait; /* for handling sleeping while waiting
|
||||
for msr change to happen */
|
||||
};
|
||||
|
||||
#define THROTTLED 0x01
|
||||
|
@ -409,7 +407,6 @@ static int mct_u232_port_probe(struct usb_serial_port *port)
|
|||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->msr_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
|
@ -601,7 +598,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
|
|||
tty_kref_put(tty);
|
||||
}
|
||||
#endif
|
||||
wake_up_interruptible(&priv->msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
exit:
|
||||
retval = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
|
@ -810,13 +807,17 @@ static int mct_u232_ioctl(struct tty_struct *tty,
|
|||
cprev = mct_u232_port->icount;
|
||||
spin_unlock_irqrestore(&mct_u232_port->lock, flags);
|
||||
for ( ; ; ) {
|
||||
prepare_to_wait(&mct_u232_port->msr_wait,
|
||||
prepare_to_wait(&port->delta_msr_wait,
|
||||
&wait, TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
finish_wait(&mct_u232_port->msr_wait, &wait);
|
||||
finish_wait(&port->delta_msr_wait, &wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&mct_u232_port->lock, flags);
|
||||
cnow = mct_u232_port->icount;
|
||||
spin_unlock_irqrestore(&mct_u232_port->lock, flags);
|
||||
|
|
|
@ -219,7 +219,6 @@ struct moschip_port {
|
|||
char open;
|
||||
char open_ports;
|
||||
wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
|
||||
wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
|
||||
int delta_msr_cond;
|
||||
struct async_icount icount;
|
||||
struct usb_serial_port *port; /* loop back to the owner of this object */
|
||||
|
@ -423,6 +422,9 @@ static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
|
|||
icount->rng++;
|
||||
smp_wmb();
|
||||
}
|
||||
|
||||
mos7840_port->delta_msr_cond = 1;
|
||||
wake_up_interruptible(&port->port->delta_msr_wait);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1127,7 +1129,6 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
|
||||
/* initialize our wait queues */
|
||||
init_waitqueue_head(&mos7840_port->wait_chase);
|
||||
init_waitqueue_head(&mos7840_port->delta_msr_wait);
|
||||
|
||||
/* initialize our icount structure */
|
||||
memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
|
||||
|
@ -2017,8 +2018,6 @@ static void mos7840_change_port_settings(struct tty_struct *tty,
|
|||
mos7840_port->read_urb_busy = false;
|
||||
}
|
||||
}
|
||||
wake_up(&mos7840_port->delta_msr_wait);
|
||||
mos7840_port->delta_msr_cond = 1;
|
||||
dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__,
|
||||
mos7840_port->shadowLCR);
|
||||
}
|
||||
|
@ -2219,13 +2218,18 @@ static int mos7840_ioctl(struct tty_struct *tty,
|
|||
while (1) {
|
||||
/* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
|
||||
mos7840_port->delta_msr_cond = 0;
|
||||
wait_event_interruptible(mos7840_port->delta_msr_wait,
|
||||
(mos7840_port->
|
||||
wait_event_interruptible(port->delta_msr_wait,
|
||||
(port->serial->disconnected ||
|
||||
mos7840_port->
|
||||
delta_msr_cond == 1));
|
||||
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
cnow = mos7840_port->icount;
|
||||
smp_rmb();
|
||||
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
|
||||
|
|
|
@ -188,7 +188,6 @@ struct oti6858_private {
|
|||
u8 setup_done;
|
||||
struct delayed_work delayed_setup_work;
|
||||
|
||||
wait_queue_head_t intr_wait;
|
||||
struct usb_serial_port *port; /* USB port with which associated */
|
||||
};
|
||||
|
||||
|
@ -339,7 +338,6 @@ static int oti6858_port_probe(struct usb_serial_port *port)
|
|||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->intr_wait);
|
||||
priv->port = port;
|
||||
INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
|
||||
INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
|
||||
|
@ -664,11 +662,15 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
|
|||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
while (1) {
|
||||
wait_event_interruptible(priv->intr_wait,
|
||||
wait_event_interruptible(port->delta_msr_wait,
|
||||
port->serial->disconnected ||
|
||||
priv->status.pin_state != prev);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
status = priv->status.pin_state & PIN_MASK;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
@ -763,7 +765,7 @@ static void oti6858_read_int_callback(struct urb *urb)
|
|||
|
||||
if (!priv->transient) {
|
||||
if (xs->pin_state != priv->status.pin_state)
|
||||
wake_up_interruptible(&priv->intr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,6 @@ struct pl2303_serial_private {
|
|||
|
||||
struct pl2303_private {
|
||||
spinlock_t lock;
|
||||
wait_queue_head_t delta_msr_wait;
|
||||
u8 line_control;
|
||||
u8 line_status;
|
||||
};
|
||||
|
@ -233,7 +232,6 @@ static int pl2303_port_probe(struct usb_serial_port *port)
|
|||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
|
@ -607,11 +605,14 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
|
|||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
while (1) {
|
||||
interruptible_sleep_on(&priv->delta_msr_wait);
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
status = priv->line_status;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
@ -719,7 +720,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
|
|||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
if (priv->line_status & UART_BREAK_ERROR)
|
||||
usb_serial_handle_break(port);
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
|
||||
tty = tty_port_tty_get(&port->port);
|
||||
if (!tty)
|
||||
|
@ -783,7 +784,7 @@ static void pl2303_process_read_urb(struct urb *urb)
|
|||
line_status = priv->line_status;
|
||||
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
|
||||
if (!urb->actual_length)
|
||||
return;
|
||||
|
|
|
@ -128,7 +128,6 @@ struct qt2_port_private {
|
|||
u8 shadowLSR;
|
||||
u8 shadowMSR;
|
||||
|
||||
wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
|
||||
struct async_icount icount;
|
||||
|
||||
struct usb_serial_port *port;
|
||||
|
@ -506,8 +505,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
|
|||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
while (1) {
|
||||
wait_event_interruptible(priv->delta_msr_wait,
|
||||
((priv->icount.rng != prev.rng) ||
|
||||
wait_event_interruptible(port->delta_msr_wait,
|
||||
(port->serial->disconnected ||
|
||||
(priv->icount.rng != prev.rng) ||
|
||||
(priv->icount.dsr != prev.dsr) ||
|
||||
(priv->icount.dcd != prev.dcd) ||
|
||||
(priv->icount.cts != prev.cts)));
|
||||
|
@ -515,6 +515,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
|
|||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
cur = priv->icount;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
@ -827,7 +830,6 @@ static int qt2_port_probe(struct usb_serial_port *port)
|
|||
|
||||
spin_lock_init(&port_priv->lock);
|
||||
spin_lock_init(&port_priv->urb_lock);
|
||||
init_waitqueue_head(&port_priv->delta_msr_wait);
|
||||
port_priv->port = port;
|
||||
|
||||
port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
|
@ -970,7 +972,7 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch)
|
|||
if (newMSR & UART_MSR_TERI)
|
||||
port_priv->icount.rng++;
|
||||
|
||||
wake_up_interruptible(&port_priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -149,7 +149,6 @@ enum spcp8x5_type {
|
|||
struct spcp8x5_private {
|
||||
spinlock_t lock;
|
||||
enum spcp8x5_type type;
|
||||
wait_queue_head_t delta_msr_wait;
|
||||
u8 line_control;
|
||||
u8 line_status;
|
||||
};
|
||||
|
@ -179,7 +178,6 @@ static int spcp8x5_port_probe(struct usb_serial_port *port)
|
|||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
priv->type = type;
|
||||
|
||||
usb_set_serial_port_data(port , priv);
|
||||
|
@ -475,7 +473,7 @@ static void spcp8x5_process_read_urb(struct urb *urb)
|
|||
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
/* wake up the wait for termios */
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
|
||||
if (!urb->actual_length)
|
||||
return;
|
||||
|
@ -526,12 +524,15 @@ static int spcp8x5_wait_modem_info(struct usb_serial_port *port,
|
|||
|
||||
while (1) {
|
||||
/* wake up in bulk read */
|
||||
interruptible_sleep_on(&priv->delta_msr_wait);
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
|
||||
/* see if a signal did it */
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
status = priv->line_status;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
|
|
@ -61,7 +61,6 @@ struct ssu100_port_private {
|
|||
spinlock_t status_lock;
|
||||
u8 shadowLSR;
|
||||
u8 shadowMSR;
|
||||
wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
|
||||
struct async_icount icount;
|
||||
};
|
||||
|
||||
|
@ -355,8 +354,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
|
|||
spin_unlock_irqrestore(&priv->status_lock, flags);
|
||||
|
||||
while (1) {
|
||||
wait_event_interruptible(priv->delta_msr_wait,
|
||||
((priv->icount.rng != prev.rng) ||
|
||||
wait_event_interruptible(port->delta_msr_wait,
|
||||
(port->serial->disconnected ||
|
||||
(priv->icount.rng != prev.rng) ||
|
||||
(priv->icount.dsr != prev.dsr) ||
|
||||
(priv->icount.dcd != prev.dcd) ||
|
||||
(priv->icount.cts != prev.cts)));
|
||||
|
@ -364,6 +364,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
|
|||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irqsave(&priv->status_lock, flags);
|
||||
cur = priv->icount;
|
||||
spin_unlock_irqrestore(&priv->status_lock, flags);
|
||||
|
@ -445,7 +448,6 @@ static int ssu100_port_probe(struct usb_serial_port *port)
|
|||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->status_lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
|
@ -537,7 +539,7 @@ static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
|
|||
priv->icount.dcd++;
|
||||
if (msr & UART_MSR_TERI)
|
||||
priv->icount.rng++;
|
||||
wake_up_interruptible(&priv->delta_msr_wait);
|
||||
wake_up_interruptible(&port->delta_msr_wait);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@ struct ti_port {
|
|||
int tp_flags;
|
||||
int tp_closing_wait;/* in .01 secs */
|
||||
struct async_icount tp_icount;
|
||||
wait_queue_head_t tp_msr_wait; /* wait for msr change */
|
||||
wait_queue_head_t tp_write_wait;
|
||||
struct ti_device *tp_tdev;
|
||||
struct usb_serial_port *tp_port;
|
||||
|
@ -432,7 +431,6 @@ static int ti_port_probe(struct usb_serial_port *port)
|
|||
else
|
||||
tport->tp_uart_base_addr = TI_UART2_BASE_ADDR;
|
||||
tport->tp_closing_wait = closing_wait;
|
||||
init_waitqueue_head(&tport->tp_msr_wait);
|
||||
init_waitqueue_head(&tport->tp_write_wait);
|
||||
if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) {
|
||||
kfree(tport);
|
||||
|
@ -784,9 +782,13 @@ static int ti_ioctl(struct tty_struct *tty,
|
|||
dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
|
||||
cprev = tport->tp_icount;
|
||||
while (1) {
|
||||
interruptible_sleep_on(&tport->tp_msr_wait);
|
||||
interruptible_sleep_on(&port->delta_msr_wait);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (port->serial->disconnected)
|
||||
return -EIO;
|
||||
|
||||
cnow = tport->tp_icount;
|
||||
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
|
||||
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
|
||||
|
@ -1392,7 +1394,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
|
|||
icount->dcd++;
|
||||
if (msr & TI_MSR_DELTA_RI)
|
||||
icount->rng++;
|
||||
wake_up_interruptible(&tport->tp_msr_wait);
|
||||
wake_up_interruptible(&tport->tp_port->delta_msr_wait);
|
||||
spin_unlock_irqrestore(&tport->tp_lock, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,7 @@ static void destroy_serial(struct kref *kref)
|
|||
}
|
||||
}
|
||||
|
||||
usb_put_intf(serial->interface);
|
||||
usb_put_dev(serial->dev);
|
||||
kfree(serial);
|
||||
}
|
||||
|
@ -620,7 +621,7 @@ static struct usb_serial *create_serial(struct usb_device *dev,
|
|||
}
|
||||
serial->dev = usb_get_dev(dev);
|
||||
serial->type = driver;
|
||||
serial->interface = interface;
|
||||
serial->interface = usb_get_intf(interface);
|
||||
kref_init(&serial->kref);
|
||||
mutex_init(&serial->disc_mutex);
|
||||
serial->minor = SERIAL_TTY_NO_MINOR;
|
||||
|
|
|
@ -496,6 +496,13 @@ UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999,
|
|||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG),
|
||||
|
||||
/* Added by Dmitry Artamonow <mad_soft@inbox.ru> */
|
||||
UNUSUAL_DEV( 0x04e8, 0x5136, 0x0000, 0x9999,
|
||||
"Samsung",
|
||||
"YP-Z3",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_MAX_SECTORS_64),
|
||||
|
||||
/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
|
||||
* Device uses standards-violating 32-byte Bulk Command Block Wrappers and
|
||||
* reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
* port.
|
||||
* @flags: usb serial port flags
|
||||
* @write_wait: a wait_queue_head_t used by the port.
|
||||
* @delta_msr_wait: modem-status-change wait queue
|
||||
* @work: work queue entry for the line discipline waking up.
|
||||
* @throttled: nonzero if the read urb is inactive to throttle the device
|
||||
* @throttle_req: nonzero if the tty wants to throttle us
|
||||
|
@ -112,6 +113,7 @@ struct usb_serial_port {
|
|||
|
||||
unsigned long flags;
|
||||
wait_queue_head_t write_wait;
|
||||
wait_queue_head_t delta_msr_wait;
|
||||
struct work_struct work;
|
||||
char throttled;
|
||||
char throttle_req;
|
||||
|
|
|
@ -181,8 +181,16 @@
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_ULPI)
|
||||
struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops,
|
||||
unsigned int flags);
|
||||
#else
|
||||
static inline struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops,
|
||||
unsigned int flags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_ULPI_VIEWPORT
|
||||
/* access ops for controllers with a viewport register */
|
||||
|
|
Loading…
Reference in New Issue