Skip to content

Commit 8491e73

Browse files
dpenklergregkh
authored andcommitted
staging: gpib: Fix Oops after disconnect in agilent usb
If the agilent 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 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. Fixes: fbae709 ("staging: gpib: Update messaging and usb_device refs in agilent_usb") Cc: stable <[email protected]> Signed-off-by: Dave Penkler <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a239c6e commit 8491e73

File tree

1 file changed

+55
-10
lines changed

1 file changed

+55
-10
lines changed

drivers/staging/gpib/agilent_82357a/agilent_82357a.c

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ static int agilent_82357a_read(gpib_board_t *board, uint8_t *buffer, size_t leng
427427
{
428428
int retval;
429429
struct agilent_82357a_priv *a_priv = board->private_data;
430-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
430+
struct usb_device *usb_dev;
431431
u8 *out_data, *in_data;
432432
int out_data_length, in_data_length;
433433
int bytes_written, bytes_read;
@@ -438,6 +438,10 @@ static int agilent_82357a_read(gpib_board_t *board, uint8_t *buffer, size_t leng
438438

439439
*nbytes = 0;
440440
*end = 0;
441+
442+
if (!a_priv->bus_interface)
443+
return -ENODEV;
444+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
441445
out_data_length = 0x9;
442446
out_data = kmalloc(out_data_length, GFP_KERNEL);
443447
if (!out_data)
@@ -534,7 +538,7 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
534538
{
535539
int retval;
536540
struct agilent_82357a_priv *a_priv = board->private_data;
537-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
541+
struct usb_device *usb_dev;
538542
u8 *out_data = NULL;
539543
u8 *status_data = NULL;
540544
int out_data_length;
@@ -545,6 +549,10 @@ static ssize_t agilent_82357a_generic_write(gpib_board_t *board, uint8_t *buffer
545549
struct agilent_82357a_register_pairlet read_reg;
546550

547551
*bytes_written = 0;
552+
if (!a_priv->bus_interface)
553+
return -ENODEV;
554+
555+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
548556
out_data_length = length + 0x8;
549557
out_data = kmalloc(out_data_length, GFP_KERNEL);
550558
if (!out_data)
@@ -697,9 +705,13 @@ int agilent_82357a_take_control_internal(gpib_board_t *board, int synchronous)
697705

698706
static int agilent_82357a_take_control(gpib_board_t *board, int synchronous)
699707
{
708+
struct agilent_82357a_priv *a_priv = board->private_data;
700709
const int timeout = 10;
701710
int i;
702711

712+
if (!a_priv->bus_interface)
713+
return -ENODEV;
714+
703715
/* It looks like the 9914 does not handle tcs properly.
704716
* See comment above tms9914_take_control_workaround() in
705717
* drivers/gpib/tms9914/tms9914_aux.c
@@ -723,10 +735,14 @@ static int agilent_82357a_take_control(gpib_board_t *board, int synchronous)
723735
static int agilent_82357a_go_to_standby(gpib_board_t *board)
724736
{
725737
struct agilent_82357a_priv *a_priv = board->private_data;
726-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
738+
struct usb_device *usb_dev;
727739
struct agilent_82357a_register_pairlet write;
728740
int retval;
729741

742+
if (!a_priv->bus_interface)
743+
return -ENODEV;
744+
745+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
730746
write.address = AUXCR;
731747
write.value = AUX_GTS;
732748
retval = agilent_82357a_write_registers(a_priv, &write, 1);
@@ -739,11 +755,15 @@ static int agilent_82357a_go_to_standby(gpib_board_t *board)
739755
static void agilent_82357a_request_system_control(gpib_board_t *board, int request_control)
740756
{
741757
struct agilent_82357a_priv *a_priv = board->private_data;
742-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
758+
struct usb_device *usb_dev;
743759
struct agilent_82357a_register_pairlet writes[2];
744760
int retval;
745761
int i = 0;
746762

763+
if (!a_priv->bus_interface)
764+
return; // -ENODEV;
765+
766+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
747767
/* 82357B needs bit to be set in 9914 AUXCR register */
748768
writes[i].address = AUXCR;
749769
if (request_control) {
@@ -767,10 +787,14 @@ static void agilent_82357a_request_system_control(gpib_board_t *board, int reque
767787
static void agilent_82357a_interface_clear(gpib_board_t *board, int assert)
768788
{
769789
struct agilent_82357a_priv *a_priv = board->private_data;
770-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
790+
struct usb_device *usb_dev;
771791
struct agilent_82357a_register_pairlet write;
772792
int retval;
773793

794+
if (!a_priv->bus_interface)
795+
return; // -ENODEV;
796+
797+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
774798
write.address = AUXCR;
775799
write.value = AUX_SIC;
776800
if (assert) {
@@ -785,10 +809,14 @@ static void agilent_82357a_interface_clear(gpib_board_t *board, int assert)
785809
static void agilent_82357a_remote_enable(gpib_board_t *board, int enable)
786810
{
787811
struct agilent_82357a_priv *a_priv = board->private_data;
788-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
812+
struct usb_device *usb_dev;
789813
struct agilent_82357a_register_pairlet write;
790814
int retval;
791815

816+
if (!a_priv->bus_interface)
817+
return; //-ENODEV;
818+
819+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
792820
write.address = AUXCR;
793821
write.value = AUX_SRE;
794822
if (enable)
@@ -804,6 +832,8 @@ static int agilent_82357a_enable_eos(gpib_board_t *board, uint8_t eos_byte, int
804832
{
805833
struct agilent_82357a_priv *a_priv = board->private_data;
806834

835+
if (!a_priv->bus_interface)
836+
return -ENODEV;
807837
if (compare_8_bits == 0)
808838
return -EOPNOTSUPP;
809839

@@ -822,10 +852,13 @@ static void agilent_82357a_disable_eos(gpib_board_t *board)
822852
static unsigned int agilent_82357a_update_status(gpib_board_t *board, unsigned int clear_mask)
823853
{
824854
struct agilent_82357a_priv *a_priv = board->private_data;
825-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
855+
struct usb_device *usb_dev;
826856
struct agilent_82357a_register_pairlet address_status, bus_status;
827857
int retval;
828858

859+
if (!a_priv->bus_interface)
860+
return -ENODEV;
861+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
829862
board->status &= ~clear_mask;
830863
if (a_priv->is_cic)
831864
set_bit(CIC_NUM, &board->status);
@@ -885,6 +918,9 @@ static int agilent_82357a_primary_address(gpib_board_t *board, unsigned int addr
885918
struct agilent_82357a_register_pairlet write;
886919
int retval;
887920

921+
if (!a_priv->bus_interface)
922+
return -ENODEV;
923+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
888924
// put primary address in address0
889925
write.address = ADR;
890926
write.value = address & ADDRESS_MASK;
@@ -906,11 +942,14 @@ static int agilent_82357a_secondary_address(gpib_board_t *board, unsigned int ad
906942
static int agilent_82357a_parallel_poll(gpib_board_t *board, uint8_t *result)
907943
{
908944
struct agilent_82357a_priv *a_priv = board->private_data;
909-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
945+
struct usb_device *usb_dev;
910946
struct agilent_82357a_register_pairlet writes[2];
911947
struct agilent_82357a_register_pairlet read;
912948
int retval;
913949

950+
if (!a_priv->bus_interface)
951+
return -ENODEV;
952+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
914953
// execute parallel poll
915954
writes[0].address = AUXCR;
916955
writes[0].value = AUX_CS | AUX_RPP;
@@ -975,11 +1014,14 @@ static void agilent_82357a_return_to_local(gpib_board_t *board)
9751014
static int agilent_82357a_line_status(const gpib_board_t *board)
9761015
{
9771016
struct agilent_82357a_priv *a_priv = board->private_data;
978-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
1017+
struct usb_device *usb_dev;
9791018
struct agilent_82357a_register_pairlet bus_status;
9801019
int retval;
9811020
int status = ValidALL;
9821021

1022+
if (!a_priv->bus_interface)
1023+
return -ENODEV;
1024+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
9831025
bus_status.address = BSR;
9841026
retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);
9851027
if (retval) {
@@ -1025,10 +1067,13 @@ static unsigned short nanosec_to_fast_talker_bits(unsigned int *nanosec)
10251067
static unsigned int agilent_82357a_t1_delay(gpib_board_t *board, unsigned int nanosec)
10261068
{
10271069
struct agilent_82357a_priv *a_priv = board->private_data;
1028-
struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
1070+
struct usb_device *usb_dev;
10291071
struct agilent_82357a_register_pairlet write;
10301072
int retval;
10311073

1074+
if (!a_priv->bus_interface)
1075+
return -ENODEV;
1076+
usb_dev = interface_to_usbdev(a_priv->bus_interface);
10321077
write.address = FAST_TALKER_T1;
10331078
write.value = nanosec_to_fast_talker_bits(&nanosec);
10341079
retval = agilent_82357a_write_registers(a_priv, &write, 1);

0 commit comments

Comments
 (0)