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:
committed by
Greg Kroah-Hartman
parent
a5df13cd7b
commit
4960bce324
@@ -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)
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user