Replace binary semaphore with mutex because mutex gives better
performance.
This change is safe because the thread that decrements the value of semaphore
is also the one that increments it, and acts like a mutex where owner of the
lock is the only one that can release the lock.
Signed-off-by: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
unsigned int ai_interval;
/* commands */
u8 *dux_commands;
unsigned int ai_interval;
/* commands */
u8 *dux_commands;
};
static void usbdux_unlink_urbs(struct urb **urbs, int num_urbs)
};
static void usbdux_unlink_urbs(struct urb **urbs, int num_urbs)
struct usbdux_private *devpriv = dev->private;
/* prevent other CPUs from submitting new commands just now */
struct usbdux_private *devpriv = dev->private;
/* prevent other CPUs from submitting new commands just now */
+ mutex_lock(&devpriv->mut);
/* unlink only if the urb really has been submitted */
usbdux_ai_stop(dev, devpriv->ai_cmd_running);
/* unlink only if the urb really has been submitted */
usbdux_ai_stop(dev, devpriv->ai_cmd_running);
+ mutex_unlock(&devpriv->mut);
struct usbdux_private *devpriv = dev->private;
/* prevent other CPUs from submitting a command just now */
struct usbdux_private *devpriv = dev->private;
/* prevent other CPUs from submitting a command just now */
+ mutex_lock(&devpriv->mut);
/* unlink only if it is really running */
usbdux_ao_stop(dev, devpriv->ao_cmd_running);
/* unlink only if it is really running */
usbdux_ao_stop(dev, devpriv->ao_cmd_running);
+ mutex_unlock(&devpriv->mut);
if (trig_num != cmd->start_arg)
return -EINVAL;
if (trig_num != cmd->start_arg)
return -EINVAL;
+ mutex_lock(&devpriv->mut);
if (!devpriv->ai_cmd_running) {
devpriv->ai_cmd_running = 1;
if (!devpriv->ai_cmd_running) {
devpriv->ai_cmd_running = 1;
+ mutex_unlock(&devpriv->mut);
int i;
/* block other CPUs from starting an ai_cmd */
int i;
/* block other CPUs from starting an ai_cmd */
+ mutex_lock(&devpriv->mut);
if (devpriv->ai_cmd_running)
goto ai_cmd_exit;
if (devpriv->ai_cmd_running)
goto ai_cmd_exit;
+ mutex_unlock(&devpriv->mut);
+ mutex_lock(&devpriv->mut);
if (devpriv->ai_cmd_running)
goto ai_read_exit;
if (devpriv->ai_cmd_running)
goto ai_read_exit;
+ mutex_unlock(&devpriv->mut);
return ret ? ret : insn->n;
}
return ret ? ret : insn->n;
}
struct usbdux_private *devpriv = dev->private;
int ret;
struct usbdux_private *devpriv = dev->private;
int ret;
+ mutex_lock(&devpriv->mut);
ret = comedi_readback_insn_read(dev, s, insn, data);
ret = comedi_readback_insn_read(dev, s, insn, data);
+ mutex_unlock(&devpriv->mut);
+ mutex_lock(&devpriv->mut);
if (devpriv->ao_cmd_running)
goto ao_write_exit;
if (devpriv->ao_cmd_running)
goto ao_write_exit;
+ mutex_unlock(&devpriv->mut);
return ret ? ret : insn->n;
}
return ret ? ret : insn->n;
}
if (trig_num != cmd->start_arg)
return -EINVAL;
if (trig_num != cmd->start_arg)
return -EINVAL;
+ mutex_lock(&devpriv->mut);
if (!devpriv->ao_cmd_running) {
devpriv->ao_cmd_running = 1;
if (!devpriv->ao_cmd_running) {
devpriv->ao_cmd_running = 1;
+ mutex_unlock(&devpriv->mut);
struct comedi_cmd *cmd = &s->async->cmd;
int ret = -EBUSY;
struct comedi_cmd *cmd = &s->async->cmd;
int ret = -EBUSY;
+ mutex_lock(&devpriv->mut);
if (devpriv->ao_cmd_running)
goto ao_cmd_exit;
if (devpriv->ao_cmd_running)
goto ao_cmd_exit;
+ mutex_unlock(&devpriv->mut);
struct usbdux_private *devpriv = dev->private;
int ret;
struct usbdux_private *devpriv = dev->private;
int ret;
+ mutex_lock(&devpriv->mut);
comedi_dio_update_state(s, data);
comedi_dio_update_state(s, data);
data[1] = le16_to_cpu(devpriv->insn_buf[1]);
dio_exit:
data[1] = le16_to_cpu(devpriv->insn_buf[1]);
dio_exit:
+ mutex_unlock(&devpriv->mut);
return ret ? ret : insn->n;
}
return ret ? ret : insn->n;
}
+ mutex_lock(&devpriv->mut);
for (i = 0; i < insn->n; i++) {
ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD);
for (i = 0; i < insn->n; i++) {
ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD);
+ mutex_unlock(&devpriv->mut);
return ret ? ret : insn->n;
}
return ret ? ret : insn->n;
}
+ mutex_lock(&devpriv->mut);
devpriv->dux_commands[1] = chan;
devpriv->dux_commands[1] = chan;
+ mutex_unlock(&devpriv->mut);
return ret ? ret : insn->n;
}
return ret ? ret : insn->n;
}
struct usbdux_private *devpriv = dev->private;
int ret;
struct usbdux_private *devpriv = dev->private;
int ret;
+ mutex_lock(&devpriv->mut);
/* unlink only if it is really running */
usbdux_pwm_stop(dev, devpriv->pwm_cmd_running);
ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF);
/* unlink only if it is really running */
usbdux_pwm_stop(dev, devpriv->pwm_cmd_running);
ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF);
+ mutex_unlock(&devpriv->mut);
struct usbdux_private *devpriv = dev->private;
int ret = 0;
struct usbdux_private *devpriv = dev->private;
int ret = 0;
+ mutex_lock(&devpriv->mut);
if (devpriv->pwm_cmd_running)
goto pwm_start_exit;
if (devpriv->pwm_cmd_running)
goto pwm_start_exit;
devpriv->pwm_cmd_running = 0;
pwm_start_exit:
devpriv->pwm_cmd_running = 0;
pwm_start_exit:
+ mutex_unlock(&devpriv->mut);
if (!devpriv)
return -ENOMEM;
if (!devpriv)
return -ENOMEM;
- sema_init(&devpriv->sem, 1);
+ mutex_init(&devpriv->mut);
usb_set_intfdata(intf, devpriv);
usb_set_intfdata(intf, devpriv);
+ mutex_lock(&devpriv->mut);
/* force unlink all urbs */
usbdux_pwm_stop(dev, 1);
/* force unlink all urbs */
usbdux_pwm_stop(dev, 1);
usbdux_free_usb_buffers(dev);
usbdux_free_usb_buffers(dev);
+ mutex_unlock(&devpriv->mut);
}
static struct comedi_driver usbdux_driver = {
}
static struct comedi_driver usbdux_driver = {