FAILED: patch "[PATCH] staging: gpib: Fix Oops after disconnect in ni_usb" failed to apply to 6.14-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.14.y
git checkout FETCH_HEAD
git cherry-pick -x a239c6e91b665f1837cf57b97fe638ef1baf2e78
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025040309-kabob-graph-ed91@gregkh' --subject-prefix 'PATCH 6.14.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From a239c6e91b665f1837cf57b97fe638ef1baf2e78 Mon Sep 17 00:00:00 2001
From: Dave Penkler <[email protected]>
Date: Sat, 22 Feb 2025 17:58:17 +0100
Subject: [PATCH] staging: gpib: Fix Oops after disconnect in ni_usb
If the usb dongle is disconnected subsequent calls to the driver cause a NULL dereference Oops as the bus_interface is set to NULL on disconnect.
This problem was introduced by setting usb_dev from the bus_interface for dev_xxx messages.
Previously bus_interface was checked for NULL only in the the functions directly calling usb_fill_bulk_urb or usb_control_msg.
Check for valid bus_interface on all interface entry points and return -ENODEV if it is NULL.
drivers/staging/gpib/ni_usb/ni_usb_gpib.c +73 -20
@@ -591,7 +591,7 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length, {int retval, parse_retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;u8 *out_data, *in_data;static const int out_data_length =0x20 ;int in_data_length;
@@ -604,8 +604,11 @@ static int ni_usb_read(gpib_board_t *board, uint8_t *buffer, size_t length,struct ni_usb_register reg; *bytes_read =0 ; +if (!ni_priv->bus_interface) +return -ENODEV ;if (length > max_read_length)return -EINVAL ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); out_data =kmalloc (out_data_length,GFP_KERNEL );if (!out_data)return -ENOMEM ;
@@ -718,7 +721,7 @@ static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length, {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;u8 *out_data, *in_data;int out_data_length;static const int in_data_length =0x10 ;
@@ -728,9 +731,11 @@ static int ni_usb_write(gpib_board_t *board, uint8_t *buffer, size_t length,struct ni_usb_status_block status;static const int max_write_length =0xffff ; - *bytes_written =0 ; +if (!ni_priv->bus_interface) +return -ENODEV ;if (length > max_write_length)return -EINVAL ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); out_data_length = length +0x10 ; out_data =kmalloc (out_data_length,GFP_KERNEL );if (!out_data)
@@ -819,7 +824,7 @@ static int ni_usb_command_chunk(gpib_board_t *board, uint8_t *buffer, size_t len {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;u8 *out_data, *in_data;int out_data_length;static const int in_data_length =0x10 ;
@@ -831,8 +836,11 @@ static int ni_usb_command_chunk(gpib_board_t *board, uint8_t *buffer, size_t lenstatic const int max_command_length =0x10 ; *command_bytes_written =0 ; +if (!ni_priv->bus_interface) +return -ENODEV ;if (length > max_command_length) length = max_command_length; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); out_data_length = length +0x10 ; out_data =kmalloc (out_data_length,GFP_KERNEL );if (!out_data)
@@ -925,7 +933,7 @@ static int ni_usb_take_control(gpib_board_t *board, int synchronous) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;u8 *out_data, *in_data;static const int out_data_length =0x10 ;static const int in_data_length =0x10 ;
@@ -933,6 +941,9 @@ static int ni_usb_take_control(gpib_board_t *board, int synchronous)int i =0 ;struct ni_usb_status_block status; +if (!ni_priv->bus_interface) +return -ENODEV ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); out_data =kmalloc (out_data_length,GFP_KERNEL );if (!out_data)return -ENOMEM ;
@@ -983,7 +994,7 @@ static int ni_usb_go_to_standby(gpib_board_t *board) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;u8 *out_data, *in_data;static const int out_data_length =0x10 ;static const int in_data_length =0x20 ;
@@ -991,6 +1002,9 @@ static int ni_usb_go_to_standby(gpib_board_t *board)int i =0 ;struct ni_usb_status_block status; +if (!ni_priv->bus_interface) +return -ENODEV ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); out_data =kmalloc (out_data_length,GFP_KERNEL );if (!out_data)return -ENOMEM ;
@@ -1039,11 +1053,14 @@ static void ni_usb_request_system_control(gpib_board_t *board, int request_contr {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;int i =0 ;struct ni_usb_register writes[4 ];unsigned int ibsta; +if (!ni_priv->bus_interface) +return ;// -ENODEV; + usb_dev =interface_to_usbdev (ni_priv->bus_interface);if (request_control) { writes[i].device =NIUSB_SUBDEV_TNT4882 ; writes[i].address =CMDR ;
@@ -1087,7 +1104,7 @@ static void ni_usb_interface_clear(gpib_board_t *board, int assert) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;u8 *out_data, *in_data;static const int out_data_length =0x10 ;static const int in_data_length =0x10 ;
@@ -1095,7 +1112,10 @@ static void ni_usb_interface_clear(gpib_board_t *board, int assert)int i =0 ;struct ni_usb_status_block status; -// FIXME: we are going to pulse when assert is true, and ignore otherwise +if (!ni_priv->bus_interface) +return ;// -ENODEV; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); +// FIXME: we are going to pulse when assert is true, and ignore otherwise if (assert ==0 )return ; out_data =kmalloc (out_data_length,GFP_KERNEL );
@@ -1133,10 +1153,13 @@ static void ni_usb_remote_enable(gpib_board_t *board, int enable) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;struct ni_usb_register reg;unsigned int ibsta; +if (!ni_priv->bus_interface) +return ;// -ENODEV; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); reg.device =NIUSB_SUBDEV_TNT4882 ; reg.address =nec7210_to_tnt4882_offset (AUXMR );if (enable)
@@ -1180,11 +1203,14 @@ static unsigned int ni_usb_update_status(gpib_board_t *board, unsigned int clear {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;static const int buffer_length =8 ;u8 *buffer;struct ni_usb_status_block status; +if (!ni_priv->bus_interface) +return -ENODEV ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); buffer =kmalloc (buffer_length,GFP_KERNEL );if (!buffer)return board->status;
@@ -1232,11 +1258,14 @@ static int ni_usb_primary_address(gpib_board_t *board, unsigned int address) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;int i =0 ;struct ni_usb_register writes[2 ];unsigned int ibsta; +if (!ni_priv->bus_interface) +return -ENODEV ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); writes[i].device =NIUSB_SUBDEV_TNT4882 ; writes[i].address =nec7210_to_tnt4882_offset (ADR ); writes[i].value = address;
@@ -1287,11 +1316,14 @@ static int ni_usb_secondary_address(gpib_board_t *board, unsigned int address, i {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;int i =0 ;struct ni_usb_register writes[3 ];unsigned int ibsta; +if (!ni_priv->bus_interface) +return -ENODEV ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); i +=ni_usb_write_sad (writes, address, enable); retval =ni_usb_write_registers (ni_priv, writes, i, &ibsta);if (retval <0 ) {
@@ -1306,7 +1338,7 @@ static int ni_usb_parallel_poll(gpib_board_t *board, uint8_t *result) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;u8 *out_data, *in_data;static const int out_data_length =0x10 ;static const int in_data_length =0x20 ;
@@ -1315,6 +1347,9 @@ static int ni_usb_parallel_poll(gpib_board_t *board, uint8_t *result)int j =0 ;struct ni_usb_status_block status; +if (!ni_priv->bus_interface) +return -ENODEV ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); out_data =kmalloc (out_data_length,GFP_KERNEL );if (!out_data)return -ENOMEM ;
@@ -1358,11 +1393,14 @@ static void ni_usb_parallel_poll_configure(gpib_board_t *board, uint8_t config) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;int i =0 ;struct ni_usb_register writes[1 ];unsigned int ibsta; +if (!ni_priv->bus_interface) +return ;// -ENODEV; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); writes[i].device =NIUSB_SUBDEV_TNT4882 ; writes[i].address =nec7210_to_tnt4882_offset (AUXMR ); writes[i].value =PPR | config;
@@ -1380,11 +1418,14 @@ static void ni_usb_parallel_poll_response(gpib_board_t *board, int ist) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;int i =0 ;struct ni_usb_register writes[1 ];unsigned int ibsta; +if (!ni_priv->bus_interface) +return ;// -ENODEV; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); writes[i].device =NIUSB_SUBDEV_TNT4882 ; writes[i].address =nec7210_to_tnt4882_offset (AUXMR );if (ist)
@@ -1405,11 +1446,14 @@ static void ni_usb_serial_poll_response(gpib_board_t *board, u8 status) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;int i =0 ;struct ni_usb_register writes[1 ];unsigned int ibsta; +if (!ni_priv->bus_interface) +return ;// -ENODEV; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); writes[i].device =NIUSB_SUBDEV_TNT4882 ; writes[i].address =nec7210_to_tnt4882_offset (SPMR ); writes[i].value = status;
@@ -1432,11 +1476,14 @@ static void ni_usb_return_to_local(gpib_board_t *board) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;int i =0 ;struct ni_usb_register writes[1 ];unsigned int ibsta; +if (!ni_priv->bus_interface) +return ;// -ENODEV; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); writes[i].device =NIUSB_SUBDEV_TNT4882 ; writes[i].address =nec7210_to_tnt4882_offset (AUXMR ); writes[i].value =AUX_RTL ;
@@ -1454,7 +1501,7 @@ static int ni_usb_line_status(const gpib_board_t *board) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;u8 *out_data, *in_data;static const int out_data_length =0x20 ;static const int in_data_length =0x20 ;
@@ -1464,6 +1511,9 @@ static int ni_usb_line_status(const gpib_board_t *board)int line_status = ValidALL;// NI windows driver reads 0xd(HSSEL), 0xc (ARD0), 0x1f (BSR) +if (!ni_priv->bus_interface) +return -ENODEV ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); out_data =kmalloc (out_data_length,GFP_KERNEL );if (!out_data)return -ENOMEM ;
@@ -1570,12 +1620,15 @@ static unsigned int ni_usb_t1_delay(gpib_board_t *board, unsigned int nano_sec) {int retval;struct ni_usb_priv *ni_priv = board->private_data; -struct usb_device *usb_dev =interface_to_usbdev (ni_priv->bus_interface); +struct usb_device *usb_dev;struct ni_usb_register writes[3 ];unsigned int ibsta;unsigned int actual_ns;int i; +if (!ni_priv->bus_interface) +return -ENODEV ; + usb_dev =interface_to_usbdev (ni_priv->bus_interface); i =ni_usb_setup_t1_delay (writes, nano_sec, &actual_ns); retval =ni_usb_write_registers (ni_priv, writes, i, &ibsta);if (retval <0 ) {