1
0

staging: gpib: Add return value to request_control

A number of drivers are unable to release control due to hardware or
software limitations. As request_system_control was defined as void,
no error could be signalled.

This patch changes the prototype of request_system_control to int and
adds the appropriate checking and returns. In the case that a board
cannot release control EINVAL is returned.  If a driver does not
implement request_system_control EPERM is returned.

Signed-off-by: Dave Penkler <dpenkler@gmail.com>
Link: https://lore.kernel.org/r/20250418133537.22491-1-dpenkler@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Dave Penkler
2025-04-18 15:35:37 +02:00
committed by Greg Kroah-Hartman
parent a5df13cd7b
commit 4960bce324
23 changed files with 76 additions and 70 deletions

View File

@@ -341,9 +341,7 @@ static int agilent_82350b_go_to_standby(struct gpib_board *board)
return tms9914_go_to_standby(board, &priv->tms9914_priv);
}
static void agilent_82350b_request_system_control(struct gpib_board *board,
int request_control)
static int agilent_82350b_request_system_control(struct gpib_board *board, int request_control)
{
struct agilent_82350b_priv *a_priv = board->private_data;
@@ -357,7 +355,7 @@ static void agilent_82350b_request_system_control(struct gpib_board *board,
writeb(0, a_priv->gpib_base + INTERNAL_CONFIG_REG);
}
writeb(a_priv->card_mode_bits, a_priv->gpib_base + CARD_MODE_REG);
tms9914_request_system_control(board, &a_priv->tms9914_priv, request_control);
return tms9914_request_system_control(board, &a_priv->tms9914_priv, request_control);
}
static void agilent_82350b_interface_clear(struct gpib_board *board, int assert)

View File

@@ -756,9 +756,7 @@ static int agilent_82357a_go_to_standby(struct gpib_board *board)
return 0;
}
//FIXME should change prototype to return int
static void agilent_82357a_request_system_control(struct gpib_board *board,
int request_control)
static int agilent_82357a_request_system_control(struct gpib_board *board, int request_control)
{
struct agilent_82357a_priv *a_priv = board->private_data;
struct usb_device *usb_dev;
@@ -767,7 +765,7 @@ static void agilent_82357a_request_system_control(struct gpib_board *board,
int i = 0;
if (!a_priv->bus_interface)
return; // -ENODEV;
return -ENODEV;
usb_dev = interface_to_usbdev(a_priv->bus_interface);
/* 82357B needs bit to be set in 9914 AUXCR register */
@@ -776,9 +774,7 @@ static void agilent_82357a_request_system_control(struct gpib_board *board,
writes[i].value = AUX_RQC;
a_priv->hw_control_bits |= SYSTEM_CONTROLLER;
} else {
writes[i].value = AUX_RLC;
a_priv->is_cic = 0;
a_priv->hw_control_bits &= ~SYSTEM_CONTROLLER;
return -EINVAL;
}
++i;
writes[i].address = HW_CONTROL;
@@ -787,7 +783,7 @@ static void agilent_82357a_request_system_control(struct gpib_board *board,
retval = agilent_82357a_write_registers(a_priv, writes, i);
if (retval)
dev_err(&usb_dev->dev, "write_registers() returned error\n");
return;// retval;
return retval;
}
static void agilent_82357a_interface_clear(struct gpib_board *board, int assert)
@@ -1593,7 +1589,7 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface)
{
struct usb_device *usb_dev = interface_to_usbdev(interface);
struct gpib_board *board;
int i, retval;
int i, retval = 0;
mutex_lock(&agilent_82357a_hotplug_lock);
@@ -1604,8 +1600,10 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface)
break;
}
}
if (i == MAX_NUM_82357A_INTERFACES)
if (i == MAX_NUM_82357A_INTERFACES) {
retval = -ENOENT;
goto resume_exit;
}
struct agilent_82357a_priv *a_priv = board->private_data;
@@ -1628,7 +1626,7 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface)
return retval;
}
// set/unset system controller
agilent_82357a_request_system_control(board, board->master);
retval = agilent_82357a_request_system_control(board, board->master);
// toggle ifc if master
if (board->master) {
agilent_82357a_interface_clear(board, 1);
@@ -1646,7 +1644,7 @@ static int agilent_82357a_driver_resume(struct usb_interface *interface)
resume_exit:
mutex_unlock(&agilent_82357a_hotplug_lock);
return 0;
return retval;
}
static struct usb_driver agilent_82357a_bus_driver = {

View File

@@ -578,7 +578,7 @@ static int cb7210_go_to_standby(struct gpib_board *board)
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
static void cb7210_request_system_control(struct gpib_board *board, int request_control)
static int cb7210_request_system_control(struct gpib_board *board, int request_control)
{
struct cb7210_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
@@ -589,7 +589,7 @@ static void cb7210_request_system_control(struct gpib_board *board, int request_
priv->hs_mode_bits &= ~HS_SYS_CONTROL;
cb7210_write_byte(priv, priv->hs_mode_bits, HS_MODE);
nec7210_request_system_control(board, nec_priv, request_control);
return nec7210_request_system_control(board, nec_priv, request_control);
}
static void cb7210_interface_clear(struct gpib_board *board, int assert)

View File

@@ -83,11 +83,11 @@ static int cec_go_to_standby(struct gpib_board *board)
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
static void cec_request_system_control(struct gpib_board *board, int request_control)
static int cec_request_system_control(struct gpib_board *board, int request_control)
{
struct cec_priv *priv = board->private_data;
nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
return nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
}
static void cec_interface_clear(struct gpib_board *board, int assert)

View File

@@ -1988,9 +1988,7 @@ static int request_system_control_ioctl(struct gpib_board *board, unsigned long
if (retval)
return -EFAULT;
ibrsc(board, request_control);
return 0;
return ibrsc(board, request_control);
}
static int t1_delay_ioctl(struct gpib_board *board, unsigned long arg)

View File

@@ -422,12 +422,21 @@ int ibsic(struct gpib_board *board, unsigned int usec_duration)
return 0;
}
/* FIXME make int */
void ibrsc(struct gpib_board *board, int request_control)
int ibrsc(struct gpib_board *board, int request_control)
{
int retval;
if (!board->interface->request_system_control)
return -EPERM;
retval = board->interface->request_system_control(board, request_control);
if (retval)
return retval;
board->master = request_control != 0;
if (board->interface->request_system_control)
board->interface->request_system_control(board, request_control);
return 0;
}
/*

View File

@@ -94,12 +94,12 @@ static int fluke_go_to_standby(struct gpib_board *board)
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
static void fluke_request_system_control(struct gpib_board *board, int request_control)
static int fluke_request_system_control(struct gpib_board *board, int request_control)
{
struct fluke_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
nec7210_request_system_control(board, nec_priv, request_control);
return nec7210_request_system_control(board, nec_priv, request_control);
}
static void fluke_interface_clear(struct gpib_board *board, int assert)

View File

@@ -86,12 +86,12 @@ static int fmh_gpib_go_to_standby(struct gpib_board *board)
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
static void fmh_gpib_request_system_control(struct gpib_board *board, int request_control)
static int fmh_gpib_request_system_control(struct gpib_board *board, int request_control)
{
struct fmh_priv *priv = board->private_data;
struct nec7210_priv *nec_priv = &priv->nec7210_priv;
nec7210_request_system_control(board, nec_priv, request_control);
return nec7210_request_system_control(board, nec_priv, request_control);
}
static void fmh_gpib_interface_clear(struct gpib_board *board, int assert)

View File

@@ -883,16 +883,16 @@ static int bb_go_to_standby(struct gpib_board *board)
return 0;
}
static void bb_request_system_control(struct gpib_board *board, int request_control)
static int bb_request_system_control(struct gpib_board *board, int request_control)
{
dbg_printk(2, "%d\n", request_control);
if (request_control) {
set_bit(CIC_NUM, &board->status);
// drive DAV & EOI false, enable NRFD & NDAC irqs
SET_DIR_WRITE(board->private_data);
} else {
clear_bit(CIC_NUM, &board->status);
}
if (!request_control)
return -EINVAL;
set_bit(CIC_NUM, &board->status);
// drive DAV & EOI false, enable NRFD & NDAC irqs
SET_DIR_WRITE(board->private_data);
return 0;
}
static void bb_interface_clear(struct gpib_board *board, int assert)

View File

@@ -68,11 +68,11 @@ static int hp82335_go_to_standby(struct gpib_board *board)
return tms9914_go_to_standby(board, &priv->tms9914_priv);
}
static void hp82335_request_system_control(struct gpib_board *board, int request_control)
static int hp82335_request_system_control(struct gpib_board *board, int request_control)
{
struct hp82335_priv *priv = board->private_data;
tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
return tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
}
static void hp82335_interface_clear(struct gpib_board *board, int assert)

View File

@@ -294,7 +294,7 @@ static int hp_82341_go_to_standby(struct gpib_board *board)
return tms9914_go_to_standby(board, &priv->tms9914_priv);
}
static void hp_82341_request_system_control(struct gpib_board *board, int request_control)
static int hp_82341_request_system_control(struct gpib_board *board, int request_control)
{
struct hp_82341_priv *priv = board->private_data;
@@ -303,7 +303,7 @@ static void hp_82341_request_system_control(struct gpib_board *board, int reques
else
priv->mode_control_bits &= ~SYSTEM_CONTROLLER_BIT;
outb(priv->mode_control_bits, priv->iobase[0] + MODE_CONTROL_STATUS_REG);
tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
return tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
}
static void hp_82341_interface_clear(struct gpib_board *board, int assert)

View File

@@ -31,7 +31,7 @@ int iblines(const struct gpib_board *board, short *lines);
int ibrd(struct gpib_board *board, u8 *buf, size_t length, int *end_flag, size_t *bytes_read);
int ibrpp(struct gpib_board *board, u8 *buf);
int ibrsv2(struct gpib_board *board, u8 status_byte, int new_reason_for_service);
void ibrsc(struct gpib_board *board, int request_control);
int ibrsc(struct gpib_board *board, int request_control);
int ibsic(struct gpib_board *board, unsigned int usec_duration);
int ibsre(struct gpib_board *board, int enable);
int ibpad(struct gpib_board *board, unsigned int addr);

View File

@@ -100,7 +100,7 @@ struct gpib_interface {
*/
int (*go_to_standby)(struct gpib_board *board);
/* request/release control of the IFC and REN lines (system controller) */
void (*request_system_control)(struct gpib_board *board, int request_control);
int (*request_system_control)(struct gpib_board *board, int request_control);
/*
* Asserts or de-asserts 'interface clear' (IFC) depending on
* boolean value of 'assert'

View File

@@ -86,8 +86,8 @@ int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, u8 *buf
size_t length, size_t *bytes_written);
int nec7210_take_control(struct gpib_board *board, struct nec7210_priv *priv, int syncronous);
int nec7210_go_to_standby(struct gpib_board *board, struct nec7210_priv *priv);
void nec7210_request_system_control(struct gpib_board *board,
struct nec7210_priv *priv, int request_control);
int nec7210_request_system_control(struct gpib_board *board,
struct nec7210_priv *priv, int request_control);
void nec7210_interface_clear(struct gpib_board *board, struct nec7210_priv *priv, int assert);
void nec7210_remote_enable(struct gpib_board *board, struct nec7210_priv *priv, int enable);
int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, u8 eos_bytes,

View File

@@ -93,8 +93,8 @@ int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, in
int tms9914_take_control_workaround(struct gpib_board *board, struct tms9914_priv *priv,
int syncronous);
int tms9914_go_to_standby(struct gpib_board *board, struct tms9914_priv *priv);
void tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
int request_control);
int tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
int request_control);
void tms9914_interface_clear(struct gpib_board *board, struct tms9914_priv *priv, int assert);
void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, int enable);
int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, u8 eos_bytes,

View File

@@ -47,7 +47,7 @@ int ines_accel_write(struct gpib_board *board, u8 *buffer, size_t length,
int ines_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written);
int ines_take_control(struct gpib_board *board, int synchronous);
int ines_go_to_standby(struct gpib_board *board);
void ines_request_system_control(struct gpib_board *board, int request_control);
int ines_request_system_control(struct gpib_board *board, int request_control);
void ines_interface_clear(struct gpib_board *board, int assert);
void ines_remote_enable(struct gpib_board *board, int enable);
int ines_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits);

View File

@@ -441,11 +441,11 @@ int ines_go_to_standby(struct gpib_board *board)
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
void ines_request_system_control(struct gpib_board *board, int request_control)
int ines_request_system_control(struct gpib_board *board, int request_control)
{
struct ines_priv *priv = board->private_data;
nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
return nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
}
void ines_interface_clear(struct gpib_board *board, int assert)

View File

@@ -911,15 +911,14 @@ static void usb_gpib_remote_enable(struct gpib_board *board, int enable)
/* request_system_control */
static void usb_gpib_request_system_control(struct gpib_board *board,
int request_control)
static int usb_gpib_request_system_control(struct gpib_board *board, int request_control)
{
if (request_control)
set_bit(CIC_NUM, &board->status);
else
clear_bit(CIC_NUM, &board->status);
if (!request_control)
return -EINVAL;
set_bit(CIC_NUM, &board->status);
DIA_LOG(1, "done with %d -> %lx\n", request_control, board->status);
return 0;
}
/* take_control */

View File

@@ -332,14 +332,15 @@ int nec7210_go_to_standby(struct gpib_board *board, struct nec7210_priv *priv)
}
EXPORT_SYMBOL(nec7210_go_to_standby);
void nec7210_request_system_control(struct gpib_board *board, struct nec7210_priv *priv,
int request_control)
int nec7210_request_system_control(struct gpib_board *board, struct nec7210_priv *priv,
int request_control)
{
if (request_control == 0) {
write_byte(priv, AUX_CREN, AUXMR);
write_byte(priv, AUX_CIFC, AUXMR);
write_byte(priv, AUX_DSC, AUXMR);
}
return 0;
}
EXPORT_SYMBOL(nec7210_request_system_control);

View File

@@ -1055,7 +1055,7 @@ static int ni_usb_go_to_standby(struct gpib_board *board)
return 0;
}
static void ni_usb_request_system_control(struct gpib_board *board, int request_control)
static int ni_usb_request_system_control(struct gpib_board *board, int request_control)
{
int retval;
struct ni_usb_priv *ni_priv = board->private_data;
@@ -1065,7 +1065,7 @@ static void ni_usb_request_system_control(struct gpib_board *board, int request_
unsigned int ibsta;
if (!ni_priv->bus_interface)
return; // -ENODEV;
return -ENODEV;
usb_dev = interface_to_usbdev(ni_priv->bus_interface);
if (request_control) {
writes[i].device = NIUSB_SUBDEV_TNT4882;
@@ -1097,12 +1097,12 @@ static void ni_usb_request_system_control(struct gpib_board *board, int request_
retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
if (retval < 0) {
dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
return; // retval;
return retval;
}
if (!request_control)
ni_priv->ren_state = 0;
ni_usb_soft_update_status(board, ibsta, 0);
return; // 0;
return 0;
}
//FIXME maybe the interface should have a "pulse interface clear" function that can return an error?

View File

@@ -128,11 +128,11 @@ static int pc2_go_to_standby(struct gpib_board *board)
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
static void pc2_request_system_control(struct gpib_board *board, int request_control)
static int pc2_request_system_control(struct gpib_board *board, int request_control)
{
struct pc2_priv *priv = board->private_data;
nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
return nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
}
static void pc2_interface_clear(struct gpib_board *board, int assert)

View File

@@ -118,8 +118,8 @@ void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv,
}
EXPORT_SYMBOL_GPL(tms9914_remote_enable);
void tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
int request_control)
int tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
int request_control)
{
if (request_control) {
write_byte(priv, AUX_RQC, AUXCR);
@@ -127,6 +127,7 @@ void tms9914_request_system_control(struct gpib_board *board, struct tms9914_pri
clear_bit(CIC_NUM, &board->status);
write_byte(priv, AUX_RLC, AUXCR);
}
return 0;
}
EXPORT_SYMBOL_GPL(tms9914_request_system_control);

View File

@@ -645,19 +645,21 @@ static int tnt4882_go_to_standby(struct gpib_board *board)
return nec7210_go_to_standby(board, &priv->nec7210_priv);
}
static void tnt4882_request_system_control(struct gpib_board *board, int request_control)
static int tnt4882_request_system_control(struct gpib_board *board, int request_control)
{
struct tnt4882_priv *priv = board->private_data;
int retval;
if (request_control) {
tnt_writeb(priv, SETSC, CMDR);
udelay(1);
}
nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
retval = nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
if (!request_control) {
tnt_writeb(priv, CLRSC, CMDR);
udelay(1);
}
return retval;
}
static void tnt4882_interface_clear(struct gpib_board *board, int assert)