dt9812, usbdux, usbduxfast: Use mutex instead of semaphore.
authorIan Abbott <abbotti@mev.co.uk>
Mon, 26 Jul 2010 11:47:08 +0000 (11:47 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Mon, 26 Jul 2010 11:47:08 +0000 (11:47 +0000)
comedi/drivers/dt9812.c
comedi/drivers/usbdux.c
comedi/drivers/usbduxfast.c

index 7d69a161ab6f599a9dc3e243321f6cc4b528021e..226619e1da5dde881118f7626aaf1e1d6a8a72c3 100644 (file)
@@ -60,7 +60,7 @@ for my needs.
 
 #define DT9812_NUM_SLOTS 16
 
-static DECLARE_MUTEX(dt9812_mutex);
+static DEFINE_MUTEX(dt9812_mutex);
 
 static struct usb_device_id dt9812_table[] = {
        {USB_DEVICE(0x0867, 0x9812)},
@@ -92,7 +92,7 @@ typedef struct comedi_dt9812 {
 } comedi_dt9812_t;
 
 typedef struct slot_dt9812 {
-       struct semaphore mutex;
+       struct mutex mutex;
        u32 serial;
        usb_dt9812_t *usb;
        comedi_dt9812_t *comedi;
@@ -217,7 +217,7 @@ static int dt9812_digital_in(slot_dt9812_t * slot, u8 * bits)
 {
        int result = -ENODEV;
 
-       down(&slot->mutex);
+       mutex_lock(&slot->mutex);
        if (slot->usb) {
                u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 };
                u8 value[2];
@@ -231,7 +231,7 @@ static int dt9812_digital_in(slot_dt9812_t * slot, u8 * bits)
 //    printk("%2.2x, %2.2x -> %2.2x\n", value[0], value[1], *bits);
                }
        }
-       up(&slot->mutex);
+       mutex_unlock(&slot->mutex);
 
        return result;
 }
@@ -240,7 +240,7 @@ static int dt9812_digital_out(slot_dt9812_t * slot, u8 bits)
 {
        int result = -ENODEV;
 
-       down(&slot->mutex);
+       mutex_lock(&slot->mutex);
        if (slot->usb) {
                u8 reg[1];
                u8 value[1];
@@ -251,7 +251,7 @@ static int dt9812_digital_out(slot_dt9812_t * slot, u8 bits)
                        value);
                slot->usb->digital_out_shadow = bits;
        }
-       up(&slot->mutex);
+       mutex_unlock(&slot->mutex);
        return result;
 }
 
@@ -259,12 +259,12 @@ static int dt9812_digital_out_shadow(slot_dt9812_t * slot, u8 * bits)
 {
        int result = -ENODEV;
 
-       down(&slot->mutex);
+       mutex_lock(&slot->mutex);
        if (slot->usb) {
                *bits = slot->usb->digital_out_shadow;
                result = 0;
        }
-       up(&slot->mutex);
+       mutex_unlock(&slot->mutex);
        return result;
 }
 
@@ -340,7 +340,7 @@ static int dt9812_analog_in(slot_dt9812_t * slot,
 {
        int result = -ENODEV;
 
-       down(&slot->mutex);
+       mutex_lock(&slot->mutex);
        if (slot->usb) {
                dt9812_rmw_byte_t rmw[3];
 
@@ -395,7 +395,7 @@ static int dt9812_analog_in(slot_dt9812_t * slot,
                        }
                }
        }
-       up(&slot->mutex);
+       mutex_unlock(&slot->mutex);
        return result;
 }
 
@@ -404,12 +404,12 @@ static int dt9812_analog_out_shadow(slot_dt9812_t * slot, int channel,
 {
        int result = -ENODEV;
 
-       down(&slot->mutex);
+       mutex_lock(&slot->mutex);
        if (slot->usb) {
                *value = slot->usb->analog_out_shadow[channel];
                result = 0;
        }
-       up(&slot->mutex);
+       mutex_unlock(&slot->mutex);
 
        return result;
 }
@@ -418,7 +418,7 @@ static int dt9812_analog_out(slot_dt9812_t * slot, int channel, u16 value)
 {
        int result = -ENODEV;
 
-       down(&slot->mutex);
+       mutex_lock(&slot->mutex);
        if (slot->usb) {
                dt9812_rmw_byte_t rmw[3];
 
@@ -461,7 +461,7 @@ static int dt9812_analog_out(slot_dt9812_t * slot, int channel, u16 value)
                result = dt9812_rmw_multiple_registers(slot->usb, 3, rmw);
                slot->usb->analog_out_shadow[channel] = value;
        }
-       up(&slot->mutex);
+       mutex_unlock(&slot->mutex);
 
        return result;
 }
@@ -612,7 +612,7 @@ static int dt9812_probe(struct usb_interface *interface,
        dev_info(&interface->dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n",
                dev->vendor, dev->product, dev->device, dev->serial);
 
-       down(&dt9812_mutex);
+       mutex_lock(&dt9812_mutex);
        {
                // Find a slot for the USB device
                slot_dt9812_t *first = NULL;
@@ -632,13 +632,13 @@ static int dt9812_probe(struct usb_interface *interface,
                }
 
                if (best) {
-                       down(&best->mutex);
+                       mutex_lock(&best->mutex);
                        best->usb = dev;
                        dev->slot = best;
-                       up(&best->mutex);
+                       mutex_unlock(&best->mutex);
                }
        }
-       up(&dt9812_mutex);
+       mutex_unlock(&dt9812_mutex);
 
        return 0;
 
@@ -654,16 +654,16 @@ static void dt9812_disconnect(struct usb_interface *interface)
        usb_dt9812_t *dev;
        int minor = interface->minor;
 
-       down(&dt9812_mutex);
+       mutex_lock(&dt9812_mutex);
        dev = usb_get_intfdata(interface);
        if (dev->slot) {
-               down(&dev->slot->mutex);
+               mutex_lock(&dev->slot->mutex);
                dev->slot->usb = NULL;
-               up(&dev->slot->mutex);
+               mutex_unlock(&dev->slot->mutex);
                dev->slot = NULL;
        }
        usb_set_intfdata(interface, NULL);
-       up(&dt9812_mutex);
+       mutex_unlock(&dt9812_mutex);
 
        /* queue final destruction */
        kref_put(&dev->kref, dt9812_delete);
@@ -689,7 +689,7 @@ static int dt9812_comedi_open(comedi_device * dev)
 {
        int result = -ENODEV;
 
-       down(&devpriv->slot->mutex);
+       mutex_lock(&devpriv->slot->mutex);
        if (devpriv->slot->usb) {
                // We have an attached device, fill in current range info
                comedi_subdevice *s;
@@ -733,7 +733,7 @@ static int dt9812_comedi_open(comedi_device * dev)
                }
                result = 0;
        }
-       up(&devpriv->slot->mutex);
+       mutex_unlock(&devpriv->slot->mutex);
        return result;
 }
 
@@ -869,7 +869,7 @@ static int dt9812_attach(comedi_device * dev, comedi_devconfig * it)
 
        printk("comedi%d: successfully attached to dt9812.\n", dev->minor);
 
-       down(&dt9812_mutex);
+       mutex_lock(&dt9812_mutex);
        // Find a slot for the comedi device
        {
                slot_dt9812_t *first = NULL;
@@ -890,14 +890,14 @@ static int dt9812_attach(comedi_device * dev, comedi_devconfig * it)
                        best = first;
                }
                if (best) {
-                       down(&best->mutex);
+                       mutex_lock(&best->mutex);
                        best->comedi = devpriv;
                        best->serial = devpriv->serial;
                        devpriv->slot = best;
-                       up(&best->mutex);
+                       mutex_unlock(&best->mutex);
                }
        }
-       up(&dt9812_mutex);
+       mutex_unlock(&dt9812_mutex);
 
        return 0;
 }
@@ -921,7 +921,7 @@ static int __init usb_dt9812_init(void)
 
        // Initialize all driver slots
        for (i = 0; i < DT9812_NUM_SLOTS; i++) {
-               init_MUTEX(&dt9812[i].mutex);
+               mutex_init(&dt9812[i].mutex);
                dt9812[i].serial = 0;
                dt9812[i].usb = NULL;
                dt9812[i].comedi = NULL;
@@ -945,11 +945,18 @@ static int __init usb_dt9812_init(void)
 
 static void __exit usb_dt9812_exit(void)
 {
+       int i;
+
        // unregister with comedi
        comedi_driver_unregister(&dt9812_comedi_driver);
 
        /* deregister this driver with the USB subsystem */
        usb_deregister(&dt9812_usb_driver);
+
+       /* destroy mutexes (for mutex debugging) */
+       for (i = 0; i < DT9812_NUM_SLOTS; i++) {
+               mutex_destroy(&dt9812[i].mutex);
+       }
 }
 
 module_init(usb_dt9812_init);
index e2c81e502efcd9024cd30fd0bd887149cc9ff4ed..c547a571ab6cb2363d2bf68cab7a3ae7bc921eb6 100644 (file)
@@ -286,7 +286,7 @@ typedef struct {
        int8_t *dac_commands;
        // commands
        int8_t *dux_commands;
-       struct semaphore sem;
+       struct mutex mutex;
 } usbduxsub_t;
 
 // The pointer to the private usb-data of the driver
@@ -298,7 +298,7 @@ typedef struct {
 // initialised before comedi can access it.
 static usbduxsub_t usbduxsub[NUMUSBDUX];
 
-static DECLARE_MUTEX(start_stop_sem);
+static DEFINE_MUTEX(start_stop_mutex);
 
 // Stops the data acquision
 // It should be safe to call this function from any context
@@ -376,14 +376,14 @@ static int usbdux_ai_cancel(comedi_device * dev, comedi_subdevice * s)
                return -EFAULT;
        }
        // prevent other CPUs from submitting new commands just now
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
        // unlink only if the urb really has been submitted
        res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running);
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return res;
 }
 
@@ -611,14 +611,14 @@ static int usbdux_ao_cancel(comedi_device * dev, comedi_subdevice * s)
                return -EFAULT;
        }
        // prevent other CPUs from submitting a command just now
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
        // unlink only if it is really running
        res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->ao_cmd_running);
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return res;
 }
 
@@ -1152,9 +1152,9 @@ static int usbdux_ai_inttrig(comedi_device * dev,
        if (!this_usbduxsub) {
                return -EFAULT;
        }
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
 #ifdef NOISY_DUX_DEBUGBUG
@@ -1164,7 +1164,7 @@ static int usbdux_ai_inttrig(comedi_device * dev,
        if (trignum != 0) {
                printk("comedi%d: usbdux_ai_inttrig: invalid trignum\n",
                        dev->minor);
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -EINVAL;
        }
        if (!(this_usbduxsub->ai_cmd_running)) {
@@ -1173,7 +1173,7 @@ static int usbdux_ai_inttrig(comedi_device * dev,
                if (ret < 0) {
                        printk("comedi%d: usbdux_ai_inttrig: urbSubmit: err=%d\n", dev->minor, ret);
                        this_usbduxsub->ai_cmd_running = 0;
-                       up(&this_usbduxsub->sem);
+                       mutex_unlock(&this_usbduxsub->mutex);
                        return ret;
                }
                s->async->inttrig = NULL;
@@ -1181,7 +1181,7 @@ static int usbdux_ai_inttrig(comedi_device * dev,
                printk("comedi%d: ai_inttrig but acqu is already running\n",
                        dev->minor);
        }
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return 1;
 }
 
@@ -1200,15 +1200,15 @@ static int usbdux_ai_cmd(comedi_device * dev, comedi_subdevice * s)
                return -EFAULT;
        }
        // block other CPUs from starting an ai_cmd
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
 
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
        if (this_usbduxsub->ai_cmd_running) {
                printk("comedi%d: ai_cmd not possible. Another ai_cmd is running.\n", dev->minor);
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -EBUSY;
        }
        // set current channel of the running aquisition to zero
@@ -1231,7 +1231,7 @@ static int usbdux_ai_cmd(comedi_device * dev, comedi_subdevice * s)
        printk("size=%u\n", NUMCHANNELS);
 #endif
        if ((result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS)) < 0) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return result;
        }
 
@@ -1255,7 +1255,7 @@ static int usbdux_ai_cmd(comedi_device * dev, comedi_subdevice * s)
        }
        if (this_usbduxsub->ai_timer < 1) {
                printk("comedi%d: usbdux: ai_cmd: timer=%d, scan_begin_arg=%d. Not properly tested by cmdtest?\n", dev->minor, this_usbduxsub->ai_timer, cmd->scan_begin_arg);
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -EINVAL;
        }
        this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
@@ -1277,7 +1277,7 @@ static int usbdux_ai_cmd(comedi_device * dev, comedi_subdevice * s)
                if (ret < 0) {
                        this_usbduxsub->ai_cmd_running = 0;
                        // fixme: unlink here??
-                       up(&this_usbduxsub->sem);
+                       mutex_unlock(&this_usbduxsub->mutex);
                        return ret;
                }
                s->async->inttrig = NULL;
@@ -1287,7 +1287,7 @@ static int usbdux_ai_cmd(comedi_device * dev, comedi_subdevice * s)
                // wait for an internal signal
                s->async->inttrig = usbdux_ai_inttrig;
        }
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return 0;
 }
 
@@ -1309,14 +1309,14 @@ static int usbdux_ai_insn_read(comedi_device * dev,
        printk("comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
                dev->minor, insn->n, insn->subdev);
 #endif
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
        if (this_usbduxsub->ai_cmd_running) {
                printk("comedi%d: ai_insn_read not possible. Async Command is running.\n", dev->minor);
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return 0;
        }
 
@@ -1328,14 +1328,14 @@ static int usbdux_ai_insn_read(comedi_device * dev,
 
        // adc commands
        if ((err = send_dux_commands(this_usbduxsub, SENDSINGLEAD)) < 0) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return err;
        }
 
        for (i = 0; i < insn->n; i++) {
                if ((err = receive_dux_commands(this_usbduxsub,
                                        SENDSINGLEAD)) < 0) {
-                       up(&this_usbduxsub->sem);
+                       mutex_unlock(&this_usbduxsub->mutex);
                        return 0;
                }
                one = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
@@ -1344,7 +1344,7 @@ static int usbdux_ai_insn_read(comedi_device * dev,
                }
                data[i] = one;
        }
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return i;
 }
 
@@ -1361,15 +1361,15 @@ static int usbdux_ao_insn_read(comedi_device * dev, comedi_subdevice * s,
        if (!this_usbduxsub) {
                return -EFAULT;
        }
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
        for (i = 0; i < insn->n; i++) {
                data[i] = this_usbduxsub->outBuffer[chan];
        }
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return i;
 }
 
@@ -1386,14 +1386,14 @@ static int usbdux_ao_insn_write(comedi_device * dev, comedi_subdevice * s,
        if (!this_usbduxsub) {
                return -EFAULT;
        }
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
        if (this_usbduxsub->ao_cmd_running) {
                printk("comedi%d: ao_insn_write: ERROR: asynchronous ao_cmd is running\n", dev->minor);
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return 0;
        }
 
@@ -1412,11 +1412,11 @@ static int usbdux_ao_insn_write(comedi_device * dev, comedi_subdevice * s,
                this_usbduxsub->dux_commands[4] = (chan << 6);
                if ((err = send_dux_commands(this_usbduxsub,
                                        SENDDACOMMANDS)) < 0) {
-                       up(&this_usbduxsub->sem);
+                       mutex_unlock(&this_usbduxsub->mutex);
                        return err;
                }
        }
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
 
        return i;
 }
@@ -1430,9 +1430,9 @@ static int usbdux_ao_inttrig(comedi_device * dev, comedi_subdevice * s,
        if (!this_usbduxsub) {
                return -EFAULT;
        }
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
        if (trignum != 0) {
@@ -1446,7 +1446,7 @@ static int usbdux_ao_inttrig(comedi_device * dev, comedi_subdevice * s,
                if (ret < 0) {
                        printk("comedi%d: usbdux_ao_inttrig: submitURB: err=%d\n", dev->minor, ret);
                        this_usbduxsub->ao_cmd_running = 0;
-                       up(&this_usbduxsub->sem);
+                       mutex_unlock(&this_usbduxsub->mutex);
                        return ret;
                }
                s->async->inttrig = NULL;
@@ -1454,7 +1454,7 @@ static int usbdux_ao_inttrig(comedi_device * dev, comedi_subdevice * s,
                printk("comedi%d: ao_inttrig but acqu is already running.\n",
                        dev->minor);
        }
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return 1;
 }
 
@@ -1601,9 +1601,9 @@ static int usbdux_ao_cmd(comedi_device * dev, comedi_subdevice * s)
        if (!this_usbduxsub) {
                return -EFAULT;
        }
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
 #ifdef NOISY_DUX_DEBUGBUG
@@ -1643,7 +1643,7 @@ static int usbdux_ao_cmd(comedi_device * dev, comedi_subdevice * s)
 #endif
                if (this_usbduxsub->ao_timer < 1) {
                        printk("comedi%d: usbdux: ao_timer=%d,  scan_begin_arg=%d. Not properly tested by cmdtest?\n", dev->minor, this_usbduxsub->ao_timer, cmd->scan_begin_arg);
-                       up(&this_usbduxsub->sem);
+                       mutex_unlock(&this_usbduxsub->mutex);
                        return -EINVAL;
                }
        }
@@ -1676,7 +1676,7 @@ static int usbdux_ao_cmd(comedi_device * dev, comedi_subdevice * s)
                if (ret < 0) {
                        this_usbduxsub->ao_cmd_running = 0;
                        // fixme: unlink here??
-                       up(&this_usbduxsub->sem);
+                       mutex_unlock(&this_usbduxsub->mutex);
                        return ret;
                }
                s->async->inttrig = NULL;
@@ -1687,7 +1687,7 @@ static int usbdux_ao_cmd(comedi_device * dev, comedi_subdevice * s)
                s->async->inttrig = usbdux_ao_inttrig;
        }
 
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return 0;
 }
 
@@ -1736,10 +1736,10 @@ static int usbdux_dio_insn_bits(comedi_device * dev,
        if (insn->n != 2)
                return -EINVAL;
 
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
 
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
 
@@ -1753,17 +1753,17 @@ static int usbdux_dio_insn_bits(comedi_device * dev,
        // This command also tells the firmware to return
        // the digital input lines
        if ((err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND)) < 0) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return err;
        }
        if ((err = receive_dux_commands(this_usbduxsub,
                                SENDDIOBITSCOMMAND)) < 0) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return err;
        }
 
        data[1] = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return 2;
 }
 
@@ -1780,26 +1780,26 @@ static int usbdux_counter_read(comedi_device * dev, comedi_subdevice * s,
                return -EFAULT;
        }
 
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
 
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
 
        if ((err = send_dux_commands(this_usbduxsub, READCOUNTERCOMMAND)) < 0) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return err;
        }
 
        if ((err = receive_dux_commands(this_usbduxsub,
                                READCOUNTERCOMMAND)) < 0) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return err;
        }
 
        data[0] = le16_to_cpu(this_usbduxsub->insnBuffer[chan + 1]);
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
        return 1;
 }
 
@@ -1813,10 +1813,10 @@ static int usbdux_counter_write(comedi_device * dev, comedi_subdevice * s,
                return -EFAULT;
        }
 
-       down(&this_usbduxsub->sem);
+       mutex_lock(&this_usbduxsub->mutex);
 
        if (!(this_usbduxsub->probed)) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return -ENODEV;
        }
 
@@ -1824,11 +1824,11 @@ static int usbdux_counter_write(comedi_device * dev, comedi_subdevice * s,
        *((int16_t *) (this_usbduxsub->dux_commands + 2)) = cpu_to_le16(*data);
 
        if ((err = send_dux_commands(this_usbduxsub, WRITECOUNTERCOMMAND)) < 0) {
-               up(&this_usbduxsub->sem);
+               mutex_unlock(&this_usbduxsub->mutex);
                return err;
        }
 
-       up(&this_usbduxsub->sem);
+       mutex_unlock(&this_usbduxsub->mutex);
 
        return 1;
 }
@@ -2476,7 +2476,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi_: usbdux_: finding a free structure for the usb-device\n");
 #endif
-       down(&start_stop_sem);
+       mutex_lock(&start_stop_mutex);
        // look for a free place in the usbdux array
        index = -1;
        for (i = 0; i < NUMUSBDUX; i++) {
@@ -2489,14 +2489,14 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        // no more space
        if (index == -1) {
                printk("Too many usbdux-devices connected.\n");
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-EMFILE);
        }
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi_: usbdux: usbduxsub[%d] is ready to connect to comedi.\n", index);
 #endif
 
-       init_MUTEX(&(usbduxsub[index].sem));
+       mutex_init(&(usbduxsub[index].mutex));
        // save a pointer to the usb device
        usbduxsub[index].usbdev = udev;
 
@@ -2525,7 +2525,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        if (!usbduxsub[index].dac_commands) {
                printk("comedi_: usbdux: error alloc space for dac commands\n");
                tidy_up(&(usbduxsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        // create space for the commands going to the usb device
@@ -2533,7 +2533,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        if (!usbduxsub[index].dux_commands) {
                printk("comedi_: usbdux: error alloc space for dac commands\n");
                tidy_up(&(usbduxsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        // create space for the in buffer and set it to zero
@@ -2541,7 +2541,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        if (!(usbduxsub[index].inBuffer)) {
                printk("comedi_: usbdux: could not alloc space for inBuffer\n");
                tidy_up(&(usbduxsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        // create space of the instruction buffer
@@ -2549,7 +2549,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        if (!(usbduxsub[index].insnBuffer)) {
                printk("comedi_: usbdux: could not alloc space for insnBuffer\n");
                tidy_up(&(usbduxsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        // create space for the outbuffer
@@ -2557,7 +2557,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        if (!(usbduxsub[index].outBuffer)) {
                printk("comedi_: usbdux: could not alloc space for outBuffer\n");
                tidy_up(&(usbduxsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        // setting to alternate setting 3: enabling iso ep and bulk ep.
@@ -2566,7 +2566,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        if (i < 0) {
                printk("comedi_: usbdux%d: could not set alternate setting 3 in high speed.\n", index);
                tidy_up(&(usbduxsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENODEV);
        }
        if (usbduxsub[index].high_speed) {
@@ -2580,7 +2580,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        if (!(usbduxsub[index].urbIn)) {
                printk("comedi_: usbdux: Could not alloc. urbIn array\n");
                tidy_up(&(usbduxsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) {
@@ -2590,7 +2590,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
                        printk("comedi_: usbdux%d: Could not alloc. urb(%d)\n",
                                index, i);
                        tidy_up(&(usbduxsub[index]));
-                       up(&start_stop_sem);
+                       mutex_unlock(&start_stop_mutex);
                        return PROBE_ERR_RETURN(-ENOMEM);
                }
                usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev;
@@ -2606,7 +2606,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
                        printk("comedi_: usbdux%d: could not alloc. transb.\n",
                                index);
                        tidy_up(&(usbduxsub[index]));
-                       up(&start_stop_sem);
+                       mutex_unlock(&start_stop_mutex);
                        return PROBE_ERR_RETURN(-ENOMEM);
                }
                usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq;
@@ -2628,7 +2628,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        if (!(usbduxsub[index].urbOut)) {
                printk("comedi_: usbdux: Could not alloc. urbOut array\n");
                tidy_up(&(usbduxsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) {
@@ -2638,7 +2638,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
                        printk("comedi_: usbdux%d: Could not alloc. urb(%d)\n",
                                index, i);
                        tidy_up(&(usbduxsub[index]));
-                       up(&start_stop_sem);
+                       mutex_unlock(&start_stop_mutex);
                        return PROBE_ERR_RETURN(-ENOMEM);
                }
                usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev;
@@ -2654,7 +2654,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
                        printk("comedi_: usbdux%d: could not alloc. transb.\n",
                                index);
                        tidy_up(&(usbduxsub[index]));
-                       up(&start_stop_sem);
+                       mutex_unlock(&start_stop_mutex);
                        return PROBE_ERR_RETURN(-ENOMEM);
                }
                usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq;
@@ -2680,7 +2680,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
                        printk("comedi_: usbdux%d: Could not alloc. pwm urb\n",
                                index);
                        tidy_up(&(usbduxsub[index]));
-                       up(&start_stop_sem);
+                       mutex_unlock(&start_stop_mutex);
                        return PROBE_ERR_RETURN(-ENOMEM);
                }
                usbduxsub[index].urbPwm->transfer_buffer =
@@ -2688,7 +2688,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
                if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
                        printk("comedi_: usbdux%d: could not alloc. transb. for pwm\n", index);
                        tidy_up(&(usbduxsub[index]));
-                       up(&start_stop_sem);
+                       mutex_unlock(&start_stop_mutex);
                        return PROBE_ERR_RETURN(-ENOMEM);
                }
        } else {
@@ -2702,7 +2702,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 
        // we've reached the bottom of the function
        usbduxsub[index].probed = 1;
-       up(&start_stop_sem);
+       mutex_unlock(&start_stop_mutex);
 
        ret = request_firmware_nowait(THIS_MODULE,
                                      FW_ACTION_HOTPLUG,
@@ -2747,11 +2747,11 @@ static void usbduxsub_disconnect(struct usb_interface *intf)
                return;
        }
        comedi_usb_auto_unconfig(udev);
-       down(&start_stop_sem);
-       down(&usbduxsub_tmp->sem);
+       mutex_lock(&start_stop_mutex);
+       mutex_lock(&usbduxsub_tmp->mutex);
        tidy_up(usbduxsub_tmp);
-       up(&usbduxsub_tmp->sem);
-       up(&start_stop_sem);
+       mutex_unlock(&usbduxsub_tmp->mutex);
+       mutex_unlock(&start_stop_mutex);
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi_: usbdux: disconnected from the usb\n");
 #endif
@@ -2766,7 +2766,7 @@ static int usbdux_attach(comedi_device * dev, comedi_devconfig * it)
        comedi_subdevice *s = NULL;
        dev->private = NULL;
 
-       down(&start_stop_sem);
+       mutex_lock(&start_stop_mutex);
        // find a valid device which has been detected by the probe function of the usb
        index = -1;
        for (i = 0; i < NUMUSBDUX; i++) {
@@ -2778,11 +2778,11 @@ static int usbdux_attach(comedi_device * dev, comedi_devconfig * it)
 
        if (index < 0) {
                printk("comedi%d: usbdux: error: attach failed, no usbdux devs connected to the usb bus.\n", dev->minor);
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return -ENODEV;
        }
 
-       down(&(usbduxsub[index].sem));
+       mutex_lock(&(usbduxsub[index].mutex));
        // pointer back to the corresponding comedi device
        usbduxsub[index].comedidev = dev;
 
@@ -2809,7 +2809,7 @@ static int usbdux_attach(comedi_device * dev, comedi_devconfig * it)
        if ((ret = alloc_subdevices(dev, dev->n_subdevices)) < 0) {
                printk("comedi%d: usbdux: error alloc space for subdev\n",
                        dev->minor);
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return ret;
        }
 
@@ -2910,9 +2910,9 @@ static int usbdux_attach(comedi_device * dev, comedi_devconfig * it)
        // finally decide that it's attached
        usbduxsub[index].attached = 1;
 
-       up(&(usbduxsub[index].sem));
+       mutex_unlock(&(usbduxsub[index].mutex));
 
-       up(&start_stop_sem);
+       mutex_unlock(&start_stop_mutex);
 
        printk("comedi%d: attached to usbdux.\n", dev->minor);
 
@@ -2938,7 +2938,7 @@ static int usbdux_detach(comedi_device * dev)
                return -EFAULT;
        }
 
-       down(&usbduxsub_tmp->sem);
+       mutex_lock(&usbduxsub_tmp->mutex);
        // Don't allow detach to free the private structure
        // It's one entry of of usbduxsub[]
        dev->private = NULL;
@@ -2947,7 +2947,7 @@ static int usbdux_detach(comedi_device * dev)
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi%d: usbdux: detach: successfully removed\n", dev->minor);
 #endif
-       up(&usbduxsub_tmp->sem);
+       mutex_unlock(&usbduxsub_tmp->mutex);
        return 0;
 }
 
@@ -2970,7 +2970,16 @@ static void init_usb_devices(void)
        // and then finally by the attach-function
        for (index = 0; index < NUMUSBDUX; index++) {
                memset(&(usbduxsub[index]), 0x00, sizeof(usbduxsub[index]));
-               init_MUTEX(&(usbduxsub[index].sem));
+               mutex_init(&(usbduxsub[index].mutex));
+       }
+}
+
+static void uninit_usb_devices(void)
+{
+       int index;
+
+       for (index = 0; index < NUMUSBDUX; index++) {
+               mutex_destroy(&(usbduxsub[index].mutex));
        }
 }
 
@@ -3014,6 +3023,7 @@ static void exit_usbdux(void)
 {
        comedi_driver_unregister(&driver_usbdux);
        usb_deregister(&usbduxsub_driver);
+       uninit_usb_devices();
 }
 
 module_init(init_usbdux);
index d0651f18845aea378dfc706c2a98fb149dc3c82f..b35e654ed6804823b750497a3a5107267c869340 100644 (file)
@@ -174,7 +174,7 @@ typedef struct {
        uint8_t *dux_commands;
        // counter which ignores the first buffers
        int ignore;
-       struct semaphore sem;
+       struct mutex mutex;
 } usbduxfastsub_t;
 
 // The pointer to the private usb-data of the driver
@@ -186,7 +186,7 @@ typedef struct {
 // initialised before comedi can access it.
 static usbduxfastsub_t usbduxfastsub[NUMUSBDUXFAST];
 
-static DECLARE_MUTEX(start_stop_sem);
+static DEFINE_MUTEX(start_stop_mutex);
 
 // bulk transfers to usbduxfast
 
@@ -286,14 +286,14 @@ static int usbduxfast_ai_cancel(comedi_device * dev, comedi_subdevice * s)
                printk("comedi: usbduxfast_ai_cancel: this_usbduxfastsub=NULL\n");
                return -EFAULT;
        }
-       down(&this_usbduxfastsub->sem);
+       mutex_lock(&this_usbduxfastsub->mutex);
        if (!(this_usbduxfastsub->probed)) {
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -ENODEV;
        }
        // unlink
        res = usbduxfast_ai_stop(this_usbduxfastsub, 1);
-       up(&this_usbduxfastsub->sem);
+       mutex_unlock(&this_usbduxfastsub->mutex);
 
        return res;
 }
@@ -713,9 +713,9 @@ static int usbduxfast_ai_inttrig(comedi_device * dev,
        if (!this_usbduxfastsub) {
                return -EFAULT;
        }
-       down(&this_usbduxfastsub->sem);
+       mutex_lock(&this_usbduxfastsub->mutex);
        if (!(this_usbduxfastsub->probed)) {
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -ENODEV;
        }
 #ifdef CONFIG_COMEDI_DEBUG
@@ -725,7 +725,7 @@ static int usbduxfast_ai_inttrig(comedi_device * dev,
        if (trignum != 0) {
                printk("comedi%d: usbduxfast_ai_inttrig: invalid trignum\n",
                        dev->minor);
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -EINVAL;
        }
        if (!(this_usbduxfastsub->ai_cmd_running)) {
@@ -734,7 +734,7 @@ static int usbduxfast_ai_inttrig(comedi_device * dev,
                if (ret < 0) {
                        printk("comedi%d: usbduxfast_ai_inttrig: urbSubmit: err=%d\n", dev->minor, ret);
                        this_usbduxfastsub->ai_cmd_running = 0;
-                       up(&this_usbduxfastsub->sem);
+                       mutex_unlock(&this_usbduxfastsub->mutex);
                        return ret;
                }
                s->async->inttrig = NULL;
@@ -742,7 +742,7 @@ static int usbduxfast_ai_inttrig(comedi_device * dev,
                printk("comedi%d: ai_inttrig but acqu is already running\n",
                        dev->minor);
        }
-       up(&this_usbduxfastsub->sem);
+       mutex_unlock(&this_usbduxfastsub->mutex);
        return 1;
 }
 
@@ -768,14 +768,14 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
        if (!this_usbduxfastsub) {
                return -EFAULT;
        }
-       down(&this_usbduxfastsub->sem);
+       mutex_lock(&this_usbduxfastsub->mutex);
        if (!(this_usbduxfastsub->probed)) {
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -ENODEV;
        }
        if (this_usbduxfastsub->ai_cmd_running) {
                printk("comedi%d: ai_cmd not possible. Another ai_cmd is running.\n", dev->minor);
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -EBUSY;
        }
        // set current channel of the running aquisition to zero
@@ -790,13 +790,13 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
                        chan = CR_CHAN(cmd->chanlist[i]);
                        if (chan != i) {
                                printk("comedi%d: cmd is accepting only consecutive channels.\n", dev->minor);
-                               up(&this_usbduxfastsub->sem);
+                               mutex_unlock(&this_usbduxfastsub->mutex);
                                return -EINVAL;
                        }
                        if ((gain != CR_RANGE(cmd->chanlist[i]))
                                && (cmd->chanlist_len > 3)) {
                                printk("comedi%d: the gain must be the same for all channels.\n", dev->minor);
-                               up(&this_usbduxfastsub->sem);
+                               mutex_unlock(&this_usbduxfastsub->mutex);
                                return -EINVAL;
                        }
                        if (i >= NUMCHANNELS) {
@@ -809,7 +809,7 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
        steps = 0;
        if (cmd->scan_begin_src == TRIG_TIMER) {
                printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -EINVAL;
        }
        if (cmd->convert_src == TRIG_TIMER) {
@@ -817,19 +817,19 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
        }
        if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
                printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", dev->minor, steps, cmd->scan_begin_arg);
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -EINVAL;
        }
        if (steps > MAX_SAMPLING_PERIOD) {
                printk("comedi%d: usbduxfast: ai_cmd: sampling rate too low.\n",
                        dev->minor);
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -EINVAL;
        }
        if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
                && (cmd->chanlist_len != 16)) {
                printk("comedi%d: usbduxfast: ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n", dev->minor);
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -EINVAL;
        }
 #ifdef CONFIG_COMEDI_DEBUG
@@ -1082,7 +1082,7 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
        default:
                printk("comedi %d: unsupported combination of channels\n",
                        dev->minor);
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return -EFAULT;
        }
 
@@ -1093,7 +1093,7 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
        result = send_dux_commands(this_usbduxfastsub, SENDADCOMMANDS);
        if (result < 0) {
                printk("comedi%d: adc command could not be submitted. Aborting...\n", dev->minor);
-               up(&this_usbduxfastsub->sem);
+               mutex_unlock(&this_usbduxfastsub->mutex);
                return result;
        }
        if (cmd->stop_src == TRIG_COUNT) {
@@ -1101,7 +1101,7 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
                        (cmd->stop_arg) * (cmd->scan_end_arg);
                if (usbduxfastsub->ai_sample_count < 1) {
                        printk("comedi%d: (cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting.\n", dev->minor);
-                       up(&this_usbduxfastsub->sem);
+                       mutex_unlock(&this_usbduxfastsub->mutex);
                        return -EFAULT;
                }
                this_usbduxfastsub->ai_continous = 0;
@@ -1118,7 +1118,7 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
                if (ret < 0) {
                        this_usbduxfastsub->ai_cmd_running = 0;
                        // fixme: unlink here??
-                       up(&this_usbduxfastsub->sem);
+                       mutex_unlock(&this_usbduxfastsub->mutex);
                        return ret;
                }
                s->async->inttrig = NULL;
@@ -1128,7 +1128,7 @@ static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
                // wait for an internal signal
                s->async->inttrig = usbduxfast_ai_inttrig;
        }
-       up(&this_usbduxfastsub->sem);
+       mutex_unlock(&this_usbduxfastsub->mutex);
 
        return 0;
 }
@@ -1150,14 +1150,14 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
        printk("comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
                dev->minor, insn->n, insn->subdev);
 #endif
-       down(&usbduxfastsub->sem);
+       mutex_lock(&usbduxfastsub->mutex);
        if (!(usbduxfastsub->probed)) {
-               up(&usbduxfastsub->sem);
+               mutex_unlock(&usbduxfastsub->mutex);
                return -ENODEV;
        }
        if (usbduxfastsub->ai_cmd_running) {
                printk("comedi%d: ai_insn_read not possible. Async Command is running.\n", dev->minor);
-               up(&usbduxfastsub->sem);
+               mutex_unlock(&usbduxfastsub->mutex);
                return -EBUSY;
        }
        // sample one channel
@@ -1214,7 +1214,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
        err = send_dux_commands(usbduxfastsub, SENDADCOMMANDS);
        if (err < 0) {
                printk("comedi%d: adc command could not be submitted. Aborting...\n", dev->minor);
-               up(&usbduxfastsub->sem);
+               mutex_unlock(&usbduxfastsub->mutex);
                return err;
        }
 #ifdef CONFIG_COMEDI_DEBUG
@@ -1231,7 +1231,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
                if (err < 0) {
                        printk("comedi%d: insn timeout. No data.\n",
                                dev->minor);
-                       up(&usbduxfastsub->sem);
+                       mutex_unlock(&usbduxfastsub->mutex);
                        return err;
                }
        }
@@ -1244,14 +1244,14 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
                if (err < 0) {
                        printk("comedi%d: insn data error: %d\n",
                                dev->minor, err);
-                       up(&usbduxfastsub->sem);
+                       mutex_unlock(&usbduxfastsub->mutex);
                        return err;
                }
                n = actual_length / sizeof(uint16_t);
                if ((n % 16) != 0) {
                        printk("comedi%d: insn data packet corrupted.\n",
                                dev->minor);
-                       up(&usbduxfastsub->sem);
+                       mutex_unlock(&usbduxfastsub->mutex);
                        return -EINVAL;
                }
                for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
@@ -1261,7 +1261,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev,
                        i++;
                }
        }
-       up(&usbduxfastsub->sem);
+       mutex_unlock(&usbduxfastsub->mutex);
        return i;
 }
 
@@ -1475,7 +1475,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi_: usbduxfast_: finding a free structure for the usb-device\n");
 #endif
-       down(&start_stop_sem);
+       mutex_lock(&start_stop_mutex);
        // look for a free place in the usbduxfast array
        index = -1;
        for (i = 0; i < NUMUSBDUXFAST; i++) {
@@ -1488,14 +1488,14 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
        // no more space
        if (index == -1) {
                printk("Too many usbduxfast-devices connected.\n");
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-EMFILE);
        }
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi_: usbduxfast: usbduxfastsub[%d] is ready to connect to comedi.\n", index);
 #endif
 
-       init_MUTEX(&(usbduxfastsub[index].sem));
+       mutex_init(&(usbduxfastsub[index].mutex));
        // save a pointer to the usb device
        usbduxfastsub[index].usbdev = udev;
 
@@ -1521,7 +1521,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
        if (!usbduxfastsub[index].dux_commands) {
                printk("comedi_: usbduxfast: error alloc space for dac commands\n");
                tidy_up(&(usbduxfastsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        // create space of the instruction buffer
@@ -1529,7 +1529,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
        if (!(usbduxfastsub[index].insnBuffer)) {
                printk("comedi_: usbduxfast: could not alloc space for insnBuffer\n");
                tidy_up(&(usbduxfastsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        // setting to alternate setting 1: enabling bulk ep
@@ -1538,14 +1538,14 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
        if (i < 0) {
                printk("comedi_: usbduxfast%d: could not switch to alternate setting 1.\n", index);
                tidy_up(&(usbduxfastsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENODEV);
        }
        usbduxfastsub[index].urbIn = USB_ALLOC_URB(0);
        if (usbduxfastsub[index].urbIn == NULL) {
                printk("comedi_: usbduxfast%d: Could not alloc. urb\n", index);
                tidy_up(&(usbduxfastsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL);
@@ -1553,12 +1553,12 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
                printk("comedi_: usbduxfast%d: could not alloc. transb.\n",
                        index);
                tidy_up(&(usbduxfastsub[index]));
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return PROBE_ERR_RETURN(-ENOMEM);
        }
        // we've reached the bottom of the function
        usbduxfastsub[index].probed = 1;
-       up(&start_stop_sem);
+       mutex_unlock(&start_stop_mutex);
 
        ret = request_firmware_nowait(THIS_MODULE,
                                      FW_ACTION_HOTPLUG,
@@ -1607,11 +1607,11 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf)
 
        comedi_usb_auto_unconfig(udev);
 
-       down(&start_stop_sem);
-       down(&usbduxfastsub_tmp->sem);
+       mutex_lock(&start_stop_mutex);
+       mutex_lock(&usbduxfastsub_tmp->mutex);
        tidy_up(usbduxfastsub_tmp);
-       up(&usbduxfastsub_tmp->sem);
-       up(&start_stop_sem);
+       mutex_unlock(&usbduxfastsub_tmp->mutex);
+       mutex_unlock(&start_stop_mutex);
 #ifdef CONFIG_COMEDI_DEBUG
        printk("comedi_: usbduxfast: disconnected from the usb\n");
 #endif
@@ -1626,7 +1626,7 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
        comedi_subdevice *s = NULL;
        dev->private = NULL;
 
-       down(&start_stop_sem);
+       mutex_lock(&start_stop_mutex);
        // find a valid device which has been detected by the probe function of the usb
        index = -1;
        for (i = 0; i < NUMUSBDUXFAST; i++) {
@@ -1638,11 +1638,11 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
 
        if (index < 0) {
                printk("comedi%d: usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n", dev->minor);
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return -ENODEV;
        }
 
-       down(&(usbduxfastsub[index].sem));
+       mutex_lock(&(usbduxfastsub[index].mutex));
        // pointer back to the corresponding comedi device
        usbduxfastsub[index].comedidev = dev;
 
@@ -1663,7 +1663,7 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
        if ((ret = alloc_subdevices(dev, N_SUBDEVICES)) < 0) {
                printk("comedi%d: usbduxfast: error alloc space for subdev\n",
                        dev->minor);
-               up(&start_stop_sem);
+               mutex_unlock(&start_stop_mutex);
                return ret;
        }
 
@@ -1701,9 +1701,9 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
        // finally decide that it's attached
        usbduxfastsub[index].attached = 1;
 
-       up(&(usbduxfastsub[index].sem));
+       mutex_unlock(&(usbduxfastsub[index].mutex));
 
-       up(&start_stop_sem);
+       mutex_unlock(&start_stop_mutex);
 
        printk("comedi%d: successfully attached to usbduxfast.\n", dev->minor);
 
@@ -1729,8 +1729,8 @@ static int usbduxfast_detach(comedi_device * dev)
                return -EFAULT;
        }
 
-       down(&usbduxfastsub_tmp->sem);
-       down(&start_stop_sem);
+       mutex_lock(&usbduxfastsub_tmp->mutex);
+       mutex_lock(&start_stop_mutex);
        // Don't allow detach to free the private structure
        // It's one entry of of usbduxfastsub[]
        dev->private = NULL;
@@ -1740,8 +1740,8 @@ static int usbduxfast_detach(comedi_device * dev)
        printk("comedi%d: usbduxfast: detach: successfully removed\n",
                dev->minor);
 #endif
-       up(&start_stop_sem);
-       up(&usbduxfastsub_tmp->sem);
+       mutex_unlock(&start_stop_mutex);
+       mutex_unlock(&usbduxfastsub_tmp->mutex);
        return 0;
 }
 
@@ -1765,7 +1765,16 @@ static void init_usb_devices(void)
        for (index = 0; index < NUMUSBDUXFAST; index++) {
                memset(&(usbduxfastsub[index]), 0x00,
                        sizeof(usbduxfastsub[index]));
-               init_MUTEX(&(usbduxfastsub[index].sem));
+               mutex_init(&(usbduxfastsub[index].mutex));
+       }
+}
+
+static void uninit_usb_devices(void)
+{
+       int index;
+
+       for (index = 0; index < NUMUSBDUXFAST; index++) {
+               mutex_destroy(&(usbduxfastsub[index].mutex));
        }
 }
 
@@ -1811,6 +1820,7 @@ static void exit_usbduxfast(void)
 {
        comedi_driver_unregister(&driver_usbduxfast);
        usb_deregister(&usbduxfastsub_driver);
+       uninit_usb_devices();
 }
 
 module_init(init_usbduxfast);