USB fixes for 4.10-rc4
Here are a few small USB driver fixes for 4.10-rc4 to resolve some reported issues. The "largest" here is a number of bugs being fixed in the ch341 usb-serial driver, to hopefully resolve the mess of different devices floating around that use this driver that have been having problems with the 4.10-rc1 release. There's also a tiny musb fix that I missed in the last pull request, as well as the traditional xhci fix rounding out the batch. All have been in linux-next with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWHttLg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylfnQCguPTDSPkdU5vSsu8eCEplsql6izUAnjz5WAuI YDQBXrYkmQ5HRM4U2/8T =M2Eg -----END PGP SIGNATURE----- Merge tag 'usb-4.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg KH: "Here are a few small USB driver fixes for 4.10-rc4 to resolve some reported issues. The "largest" here is a number of bugs being fixed in the ch341 usb-serial driver, to hopefully resolve the mess of different devices floating around that use this driver that have been having problems with the 4.10-rc1 release. There's also a tiny musb fix that I missed in the last pull request, as well as the traditional xhci fix rounding out the batch. All have been in linux-next with no reported issues" * tag 'usb-4.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: xhci: fix deadlock at host remove by running watchdog correctly USB: serial: ch341: fix control-message error handling usb: musb: fix runtime PM in debugfs wusbcore: Fix one more crypto-on-the-stack bug USB: serial: kl5kusb105: fix line-state error handling USB: serial: ch341: fix baud rate and line-control handling USB: serial: ch341: fix line settings after reset-resume USB: serial: ch341: fix resume after reset USB: serial: ch341: fix open error handling USB: serial: ch341: fix modem-control and B0 handling USB: serial: ch341: fix open and resume after B0 USB: serial: ch341: fix initial modem-control state
This commit is contained in:
commit
793e039ea0
@ -913,17 +913,6 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
|
|||||||
spin_lock_irqsave(&xhci->lock, flags);
|
spin_lock_irqsave(&xhci->lock, flags);
|
||||||
|
|
||||||
ep->stop_cmds_pending--;
|
ep->stop_cmds_pending--;
|
||||||
if (xhci->xhc_state & XHCI_STATE_REMOVING) {
|
|
||||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (xhci->xhc_state & XHCI_STATE_DYING) {
|
|
||||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
||||||
"Stop EP timer ran, but another timer marked "
|
|
||||||
"xHCI as DYING, exiting.");
|
|
||||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
|
if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
|
||||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
||||||
"Stop EP timer ran, but no command pending, "
|
"Stop EP timer ran, but no command pending, "
|
||||||
|
@ -1534,19 +1534,6 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||||||
xhci_urb_free_priv(urb_priv);
|
xhci_urb_free_priv(urb_priv);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if ((xhci->xhc_state & XHCI_STATE_DYING) ||
|
|
||||||
(xhci->xhc_state & XHCI_STATE_HALTED)) {
|
|
||||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
||||||
"Ep 0x%x: URB %p to be canceled on "
|
|
||||||
"non-responsive xHCI host.",
|
|
||||||
urb->ep->desc.bEndpointAddress, urb);
|
|
||||||
/* Let the stop endpoint command watchdog timer (which set this
|
|
||||||
* state) finish cleaning up the endpoint TD lists. We must
|
|
||||||
* have caught it in the middle of dropping a lock and giving
|
|
||||||
* back an URB.
|
|
||||||
*/
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
|
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
|
||||||
ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
|
ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
|
||||||
|
@ -114,6 +114,7 @@ static int musb_regdump_show(struct seq_file *s, void *unused)
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
seq_printf(s, "MUSB (M)HDRC Register Dump\n");
|
seq_printf(s, "MUSB (M)HDRC Register Dump\n");
|
||||||
|
pm_runtime_get_sync(musb->controller);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(musb_regmap); i++) {
|
for (i = 0; i < ARRAY_SIZE(musb_regmap); i++) {
|
||||||
switch (musb_regmap[i].size) {
|
switch (musb_regmap[i].size) {
|
||||||
@ -132,6 +133,8 @@ static int musb_regdump_show(struct seq_file *s, void *unused)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(musb->controller);
|
||||||
|
pm_runtime_put_autosuspend(musb->controller);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +148,10 @@ static int musb_test_mode_show(struct seq_file *s, void *unused)
|
|||||||
struct musb *musb = s->private;
|
struct musb *musb = s->private;
|
||||||
unsigned test;
|
unsigned test;
|
||||||
|
|
||||||
|
pm_runtime_get_sync(musb->controller);
|
||||||
test = musb_readb(musb->mregs, MUSB_TESTMODE);
|
test = musb_readb(musb->mregs, MUSB_TESTMODE);
|
||||||
|
pm_runtime_mark_last_busy(musb->controller);
|
||||||
|
pm_runtime_put_autosuspend(musb->controller);
|
||||||
|
|
||||||
if (test & MUSB_TEST_FORCE_HOST)
|
if (test & MUSB_TEST_FORCE_HOST)
|
||||||
seq_printf(s, "force host\n");
|
seq_printf(s, "force host\n");
|
||||||
@ -194,11 +200,12 @@ static ssize_t musb_test_mode_write(struct file *file,
|
|||||||
u8 test;
|
u8 test;
|
||||||
char buf[18];
|
char buf[18];
|
||||||
|
|
||||||
|
pm_runtime_get_sync(musb->controller);
|
||||||
test = musb_readb(musb->mregs, MUSB_TESTMODE);
|
test = musb_readb(musb->mregs, MUSB_TESTMODE);
|
||||||
if (test) {
|
if (test) {
|
||||||
dev_err(musb->controller, "Error: test mode is already set. "
|
dev_err(musb->controller, "Error: test mode is already set. "
|
||||||
"Please do USB Bus Reset to start a new test.\n");
|
"Please do USB Bus Reset to start a new test.\n");
|
||||||
return count;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(buf, 0x00, sizeof(buf));
|
memset(buf, 0x00, sizeof(buf));
|
||||||
@ -234,6 +241,9 @@ static ssize_t musb_test_mode_write(struct file *file,
|
|||||||
|
|
||||||
musb_writeb(musb->mregs, MUSB_TESTMODE, test);
|
musb_writeb(musb->mregs, MUSB_TESTMODE, test);
|
||||||
|
|
||||||
|
ret:
|
||||||
|
pm_runtime_mark_last_busy(musb->controller);
|
||||||
|
pm_runtime_put_autosuspend(musb->controller);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,8 +264,13 @@ static int musb_softconnect_show(struct seq_file *s, void *unused)
|
|||||||
switch (musb->xceiv->otg->state) {
|
switch (musb->xceiv->otg->state) {
|
||||||
case OTG_STATE_A_HOST:
|
case OTG_STATE_A_HOST:
|
||||||
case OTG_STATE_A_WAIT_BCON:
|
case OTG_STATE_A_WAIT_BCON:
|
||||||
|
pm_runtime_get_sync(musb->controller);
|
||||||
|
|
||||||
reg = musb_readb(musb->mregs, MUSB_DEVCTL);
|
reg = musb_readb(musb->mregs, MUSB_DEVCTL);
|
||||||
connect = reg & MUSB_DEVCTL_SESSION ? 1 : 0;
|
connect = reg & MUSB_DEVCTL_SESSION ? 1 : 0;
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(musb->controller);
|
||||||
|
pm_runtime_put_autosuspend(musb->controller);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
connect = -1;
|
connect = -1;
|
||||||
@ -284,6 +299,7 @@ static ssize_t musb_softconnect_write(struct file *file,
|
|||||||
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
|
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
pm_runtime_get_sync(musb->controller);
|
||||||
if (!strncmp(buf, "0", 1)) {
|
if (!strncmp(buf, "0", 1)) {
|
||||||
switch (musb->xceiv->otg->state) {
|
switch (musb->xceiv->otg->state) {
|
||||||
case OTG_STATE_A_HOST:
|
case OTG_STATE_A_HOST:
|
||||||
@ -314,6 +330,8 @@ static ssize_t musb_softconnect_write(struct file *file,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(musb->controller);
|
||||||
|
pm_runtime_put_autosuspend(musb->controller);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ struct ch341_private {
|
|||||||
unsigned baud_rate; /* set baud rate */
|
unsigned baud_rate; /* set baud rate */
|
||||||
u8 line_control; /* set line control value RTS/DTR */
|
u8 line_control; /* set line control value RTS/DTR */
|
||||||
u8 line_status; /* active status of modem control inputs */
|
u8 line_status; /* active status of modem control inputs */
|
||||||
|
u8 lcr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ch341_set_termios(struct tty_struct *tty,
|
static void ch341_set_termios(struct tty_struct *tty,
|
||||||
@ -112,6 +113,8 @@ static int ch341_control_out(struct usb_device *dev, u8 request,
|
|||||||
r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,
|
r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
|
||||||
value, index, NULL, 0, DEFAULT_TIMEOUT);
|
value, index, NULL, 0, DEFAULT_TIMEOUT);
|
||||||
|
if (r < 0)
|
||||||
|
dev_err(&dev->dev, "failed to send control message: %d\n", r);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -129,11 +132,24 @@ static int ch341_control_in(struct usb_device *dev,
|
|||||||
r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
|
r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
value, index, buf, bufsize, DEFAULT_TIMEOUT);
|
value, index, buf, bufsize, DEFAULT_TIMEOUT);
|
||||||
return r;
|
if (r < bufsize) {
|
||||||
|
if (r >= 0) {
|
||||||
|
dev_err(&dev->dev,
|
||||||
|
"short control message received (%d < %u)\n",
|
||||||
|
r, bufsize);
|
||||||
|
r = -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_err(&dev->dev, "failed to receive control message: %d\n",
|
||||||
|
r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ch341_init_set_baudrate(struct usb_device *dev,
|
static int ch341_set_baudrate_lcr(struct usb_device *dev,
|
||||||
struct ch341_private *priv, unsigned ctrl)
|
struct ch341_private *priv, u8 lcr)
|
||||||
{
|
{
|
||||||
short a;
|
short a;
|
||||||
int r;
|
int r;
|
||||||
@ -156,9 +172,19 @@ static int ch341_init_set_baudrate(struct usb_device *dev,
|
|||||||
factor = 0x10000 - factor;
|
factor = 0x10000 - factor;
|
||||||
a = (factor & 0xff00) | divisor;
|
a = (factor & 0xff00) | divisor;
|
||||||
|
|
||||||
/* 0x9c is "enable SFR_UART Control register and timer" */
|
/*
|
||||||
r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT,
|
* CH341A buffers data until a full endpoint-size packet (32 bytes)
|
||||||
0x9c | (ctrl << 8), a | 0x80);
|
* has been received unless bit 7 is set.
|
||||||
|
*/
|
||||||
|
a |= BIT(7);
|
||||||
|
|
||||||
|
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -170,9 +196,9 @@ static int ch341_set_handshake(struct usb_device *dev, u8 control)
|
|||||||
|
|
||||||
static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
|
static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
|
||||||
{
|
{
|
||||||
|
const unsigned int size = 2;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int r;
|
int r;
|
||||||
const unsigned size = 8;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
buffer = kmalloc(size, GFP_KERNEL);
|
buffer = kmalloc(size, GFP_KERNEL);
|
||||||
@ -183,14 +209,9 @@ static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* setup the private status if available */
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
if (r == 2) {
|
priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT;
|
||||||
r = 0;
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
|
||||||
priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT;
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
} else
|
|
||||||
r = -EPROTO;
|
|
||||||
|
|
||||||
out: kfree(buffer);
|
out: kfree(buffer);
|
||||||
return r;
|
return r;
|
||||||
@ -200,9 +221,9 @@ out: kfree(buffer);
|
|||||||
|
|
||||||
static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
|
static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
|
||||||
{
|
{
|
||||||
|
const unsigned int size = 2;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int r;
|
int r;
|
||||||
const unsigned size = 8;
|
|
||||||
|
|
||||||
buffer = kmalloc(size, GFP_KERNEL);
|
buffer = kmalloc(size, GFP_KERNEL);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
@ -232,7 +253,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = ch341_init_set_baudrate(dev, priv, 0);
|
r = ch341_set_baudrate_lcr(dev, priv, priv->lcr);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -258,7 +279,6 @@ static int ch341_port_probe(struct usb_serial_port *port)
|
|||||||
|
|
||||||
spin_lock_init(&priv->lock);
|
spin_lock_init(&priv->lock);
|
||||||
priv->baud_rate = DEFAULT_BAUD_RATE;
|
priv->baud_rate = DEFAULT_BAUD_RATE;
|
||||||
priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
|
|
||||||
|
|
||||||
r = ch341_configure(port->serial->dev, priv);
|
r = ch341_configure(port->serial->dev, priv);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -320,7 +340,7 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||||||
|
|
||||||
r = ch341_configure(serial->dev, priv);
|
r = ch341_configure(serial->dev, priv);
|
||||||
if (r)
|
if (r)
|
||||||
goto out;
|
return r;
|
||||||
|
|
||||||
if (tty)
|
if (tty)
|
||||||
ch341_set_termios(tty, port, NULL);
|
ch341_set_termios(tty, port, NULL);
|
||||||
@ -330,12 +350,19 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||||||
if (r) {
|
if (r) {
|
||||||
dev_err(&port->dev, "%s - failed to submit interrupt urb: %d\n",
|
dev_err(&port->dev, "%s - failed to submit interrupt urb: %d\n",
|
||||||
__func__, r);
|
__func__, r);
|
||||||
goto out;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = usb_serial_generic_open(tty, port);
|
r = usb_serial_generic_open(tty, port);
|
||||||
|
if (r)
|
||||||
|
goto err_kill_interrupt_urb;
|
||||||
|
|
||||||
out: return r;
|
return 0;
|
||||||
|
|
||||||
|
err_kill_interrupt_urb:
|
||||||
|
usb_kill_urb(port->interrupt_in_urb);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Old_termios contains the original termios settings and
|
/* Old_termios contains the original termios settings and
|
||||||
@ -356,7 +383,6 @@ static void ch341_set_termios(struct tty_struct *tty,
|
|||||||
|
|
||||||
baud_rate = tty_get_baud_rate(tty);
|
baud_rate = tty_get_baud_rate(tty);
|
||||||
|
|
||||||
priv->baud_rate = baud_rate;
|
|
||||||
ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;
|
ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;
|
||||||
|
|
||||||
switch (C_CSIZE(tty)) {
|
switch (C_CSIZE(tty)) {
|
||||||
@ -386,22 +412,25 @@ static void ch341_set_termios(struct tty_struct *tty,
|
|||||||
ctrl |= CH341_LCR_STOP_BITS_2;
|
ctrl |= CH341_LCR_STOP_BITS_2;
|
||||||
|
|
||||||
if (baud_rate) {
|
if (baud_rate) {
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
priv->baud_rate = baud_rate;
|
||||||
priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
r = ch341_set_baudrate_lcr(port->serial->dev, priv, ctrl);
|
||||||
r = ch341_init_set_baudrate(port->serial->dev, priv, ctrl);
|
|
||||||
if (r < 0 && old_termios) {
|
if (r < 0 && old_termios) {
|
||||||
priv->baud_rate = tty_termios_baud_rate(old_termios);
|
priv->baud_rate = tty_termios_baud_rate(old_termios);
|
||||||
tty_termios_copy_hw(&tty->termios, old_termios);
|
tty_termios_copy_hw(&tty->termios, old_termios);
|
||||||
|
} else if (r == 0) {
|
||||||
|
priv->lcr = ctrl;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
|
||||||
priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ch341_set_handshake(port->serial->dev, priv->line_control);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
if (C_BAUD(tty) == B0)
|
||||||
|
priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
|
||||||
|
else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
|
||||||
|
priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
|
ch341_set_handshake(port->serial->dev, priv->line_control);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ch341_break_ctl(struct tty_struct *tty, int break_state)
|
static void ch341_break_ctl(struct tty_struct *tty, int break_state)
|
||||||
@ -576,14 +605,23 @@ static int ch341_tiocmget(struct tty_struct *tty)
|
|||||||
|
|
||||||
static int ch341_reset_resume(struct usb_serial *serial)
|
static int ch341_reset_resume(struct usb_serial *serial)
|
||||||
{
|
{
|
||||||
struct ch341_private *priv;
|
struct usb_serial_port *port = serial->port[0];
|
||||||
|
struct ch341_private *priv = usb_get_serial_port_data(port);
|
||||||
priv = usb_get_serial_port_data(serial->port[0]);
|
int ret;
|
||||||
|
|
||||||
/* reconfigure ch341 serial port after bus-reset */
|
/* reconfigure ch341 serial port after bus-reset */
|
||||||
ch341_configure(serial->dev, priv);
|
ch341_configure(serial->dev, priv);
|
||||||
|
|
||||||
return 0;
|
if (tty_port_initialized(&port->port)) {
|
||||||
|
ret = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&port->dev, "failed to submit interrupt urb: %d\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return usb_serial_generic_resume(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_serial_driver ch341_device = {
|
static struct usb_serial_driver ch341_device = {
|
||||||
|
@ -192,10 +192,11 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
|
|||||||
status_buf, KLSI_STATUSBUF_LEN,
|
status_buf, KLSI_STATUSBUF_LEN,
|
||||||
10000
|
10000
|
||||||
);
|
);
|
||||||
if (rc < 0)
|
if (rc != KLSI_STATUSBUF_LEN) {
|
||||||
dev_err(&port->dev, "Reading line status failed (error = %d)\n",
|
dev_err(&port->dev, "reading line status failed: %d\n", rc);
|
||||||
rc);
|
if (rc >= 0)
|
||||||
else {
|
rc = -EIO;
|
||||||
|
} else {
|
||||||
status = get_unaligned_le16(status_buf);
|
status = get_unaligned_le16(status_buf);
|
||||||
|
|
||||||
dev_info(&port->serial->dev->dev, "read status %x %x\n",
|
dev_info(&port->serial->dev->dev, "read status %x %x\n",
|
||||||
|
@ -216,7 +216,6 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc,
|
|||||||
struct scatterlist sg[4], sg_dst;
|
struct scatterlist sg[4], sg_dst;
|
||||||
void *dst_buf;
|
void *dst_buf;
|
||||||
size_t dst_size;
|
size_t dst_size;
|
||||||
const u8 bzero[16] = { 0 };
|
|
||||||
u8 iv[crypto_skcipher_ivsize(tfm_cbc)];
|
u8 iv[crypto_skcipher_ivsize(tfm_cbc)];
|
||||||
size_t zero_padding;
|
size_t zero_padding;
|
||||||
|
|
||||||
@ -261,7 +260,7 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc,
|
|||||||
sg_set_buf(&sg[1], &scratch->b1, sizeof(scratch->b1));
|
sg_set_buf(&sg[1], &scratch->b1, sizeof(scratch->b1));
|
||||||
sg_set_buf(&sg[2], b, blen);
|
sg_set_buf(&sg[2], b, blen);
|
||||||
/* 0 if well behaved :) */
|
/* 0 if well behaved :) */
|
||||||
sg_set_buf(&sg[3], bzero, zero_padding);
|
sg_set_page(&sg[3], ZERO_PAGE(0), zero_padding, 0);
|
||||||
sg_init_one(&sg_dst, dst_buf, dst_size);
|
sg_init_one(&sg_dst, dst_buf, dst_size);
|
||||||
|
|
||||||
skcipher_request_set_tfm(req, tfm_cbc);
|
skcipher_request_set_tfm(req, tfm_cbc);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user