Re: Kernel 3.17.x Attaching Keyspan 4-Port Serial to USB Adapter Causes Kernel Panic

From: Richard
Date: Tue Dec 23 2014 - 15:57:25 EST


> So the same kernel is used (3.17.4), but only the new system oopses?

Yes, using kernel.org's 3.17.4 on both systems, only the new Asus X99-A
based system oopses. The older Asus P6X58D motherboard, running a very
similarly configured 3.17.4 kernel has no issues with Keyspan USB adapter.

> This driver is a bit of a mess.
> Could you try the patch below and see if
> it fixes the problem?

Yes. Thank you. That fixes the issue. I can now plug in the Keyspan
USB adapter to my new running system without the kernel freezing. I
applied your patch to 3.17.7. I have not yet tried it on 3.18.1.

Using minicom I tested the usb-serial devices and everything seems to work.

Richard



On 12/22/14 09:53, Johan Hovold wrote:
> [+CC: linux-usb ]
>
> On Sat, Dec 20, 2014 at 04:08:20PM -0800, Richard wrote:
>> On a new Gentoo based system with Kernel.org Kernels 3.17.4 to 3.17.7
>> when I physically plug the Keyspan 4-Port Serial to USB adapter into a
>> usb port my system freezes with a "unable to handle kernel NULL pointer
>> deference" message.
>>
>> My old system (also Gentoo based with Kernel.org 3.17.4) does not have
>> this issue. Both systems are using the USB_SERIAL_KEYSPAN_USA49W
>> driver module.
>
> So the same kernel is used (3.17.4), but only the new system oopses?
>
>> I tried booting into single user mode, using modprobe to load
>> USB_SERIAL_KEYSPAN_USA49W. lsmod shows the driver. When I pluged the
>> device in I receive the system freeze. Below is what I copied off the
>> console ...
>>
>> BUG: Unable to handle kernel NULL pointer deference at 000...8c
>> IP: [<ffffffffa006fbdd>] usa49_instat_callback+0x4d/0xb0[keyspan]
>> PGD 1037faa067 PUD 1038301067 PMD 0
>> Oops: 0002 [#1] SMP
>> Modules linked in: keyspan ezusb usbserial hid_generic ...
>
> This driver is a bit of a mess. Could you try the patch below and see if
> it fixes the problem?
>
> Thanks,
> Johan
>
>
>>From 3e98e15094be174d08dc31daab5c7b7791228515 Mon Sep 17 00:00:00 2001
> From: Johan Hovold <johan@xxxxxxxxxx>
> Date: Mon, 22 Dec 2014 18:39:39 +0100
> Subject: [PATCH] USB: keyspan: fix null-deref at probe
>
> Fix null-pointer dereference during probe if the interface-status
> completion handler is called before the individual ports have been set
> up.
>
> Reported-by: Richard <richjunk@xxxxxxxxxxx>
> Signed-off-by: Johan Hovold <johan@xxxxxxxxxx>
> ---
> drivers/usb/serial/keyspan.c | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
> index 077c714f1285..e07b15ed5814 100644
> --- a/drivers/usb/serial/keyspan.c
> +++ b/drivers/usb/serial/keyspan.c
> @@ -410,6 +410,8 @@ static void usa26_instat_callback(struct urb *urb)
> }
> port = serial->port[msg->port];
> p_priv = usb_get_serial_port_data(port);
> + if (!p_priv)
> + goto resubmit;
>
> /* Update handshaking pin state information */
> old_dcd_state = p_priv->dcd_state;
> @@ -420,7 +422,7 @@ static void usa26_instat_callback(struct urb *urb)
>
> if (old_dcd_state != p_priv->dcd_state)
> tty_port_tty_hangup(&port->port, true);
> -
> +resubmit:
> /* Resubmit urb so we continue receiving */
> err = usb_submit_urb(urb, GFP_ATOMIC);
> if (err != 0)
> @@ -527,6 +529,8 @@ static void usa28_instat_callback(struct urb *urb)
> }
> port = serial->port[msg->port];
> p_priv = usb_get_serial_port_data(port);
> + if (!p_priv)
> + goto resubmit;
>
> /* Update handshaking pin state information */
> old_dcd_state = p_priv->dcd_state;
> @@ -537,7 +541,7 @@ static void usa28_instat_callback(struct urb *urb)
>
> if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
> tty_port_tty_hangup(&port->port, true);
> -
> +resubmit:
> /* Resubmit urb so we continue receiving */
> err = usb_submit_urb(urb, GFP_ATOMIC);
> if (err != 0)
> @@ -607,6 +611,8 @@ static void usa49_instat_callback(struct urb *urb)
> }
> port = serial->port[msg->portNumber];
> p_priv = usb_get_serial_port_data(port);
> + if (!p_priv)
> + goto resubmit;
>
> /* Update handshaking pin state information */
> old_dcd_state = p_priv->dcd_state;
> @@ -617,7 +623,7 @@ static void usa49_instat_callback(struct urb *urb)
>
> if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
> tty_port_tty_hangup(&port->port, true);
> -
> +resubmit:
> /* Resubmit urb so we continue receiving */
> err = usb_submit_urb(urb, GFP_ATOMIC);
> if (err != 0)
> @@ -855,6 +861,8 @@ static void usa90_instat_callback(struct urb *urb)
>
> port = serial->port[0];
> p_priv = usb_get_serial_port_data(port);
> + if (!p_priv)
> + goto resubmit;
>
> /* Update handshaking pin state information */
> old_dcd_state = p_priv->dcd_state;
> @@ -865,7 +873,7 @@ static void usa90_instat_callback(struct urb *urb)
>
> if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
> tty_port_tty_hangup(&port->port, true);
> -
> +resubmit:
> /* Resubmit urb so we continue receiving */
> err = usb_submit_urb(urb, GFP_ATOMIC);
> if (err != 0)
> @@ -926,6 +934,8 @@ static void usa67_instat_callback(struct urb *urb)
>
> port = serial->port[msg->port];
> p_priv = usb_get_serial_port_data(port);
> + if (!p_priv)
> + goto resubmit;
>
> /* Update handshaking pin state information */
> old_dcd_state = p_priv->dcd_state;
> @@ -934,7 +944,7 @@ static void usa67_instat_callback(struct urb *urb)
>
> if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
> tty_port_tty_hangup(&port->port, true);
> -
> +resubmit:
> /* Resubmit urb so we continue receiving */
> err = usb_submit_urb(urb, GFP_ATOMIC);
> if (err != 0)
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/