The 'open' method in struct comedi_device_struct now returns 0 on success
authorIan Abbott <abbotti@mev.co.uk>
Wed, 24 Mar 2010 11:53:09 +0000 (11:53 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Wed, 24 Mar 2010 11:53:09 +0000 (11:53 +0000)
and a negative errno on failure.  The 'open' method must clean up after
itself on failure as the 'close' method won't be called.  A failure causes
the 'open' file operation for the comedi device to fail.

The dt9812 and serial2002 drivers now make use of the ability to return
an error.

comedi/comedi_fops.c
comedi/drivers/dt9812.c
comedi/drivers/jr3_pci.c
comedi/drivers/serial2002.c
include/linux/comedidev.h

index 19295728370fe692aaaf792a6453317f78051cae..9a5e0ea2a6e9095869b13c02af45ff24d1433a6c 100644 (file)
@@ -1837,7 +1837,14 @@ ok:
        }
 
        if (dev->attached && dev->use_count == 0 && dev->open) {
-               dev->open(dev);
+               int rc = dev->open(dev);
+
+               if (rc < 0) {
+                       module_put(dev->driver->module);
+                       module_put(THIS_MODULE);
+                       mutex_unlock(&dev->mutex);
+                       return rc;
+               }
        }
 
        dev->use_count++;
index 8afb9cb97c1c015caa8da2f326d659fd981f7f18..7d69a161ab6f599a9dc3e243321f6cc4b528021e 100644 (file)
@@ -685,8 +685,10 @@ static struct usb_driver dt9812_usb_driver = {
  * Comedi functions
  */
 
-static void dt9812_comedi_open(comedi_device * dev)
+static int dt9812_comedi_open(comedi_device * dev)
 {
+       int result = -ENODEV;
+
        down(&devpriv->slot->mutex);
        if (devpriv->slot->usb) {
                // We have an attached device, fill in current range info
@@ -729,8 +731,10 @@ static void dt9812_comedi_open(comedi_device * dev)
                        }
                        break;
                }
+               result = 0;
        }
        up(&devpriv->slot->mutex);
+       return result;
 }
 
 static int dt9812_di_rinsn(comedi_device * dev, comedi_subdevice * s,
index 0482a3fb96bf5307dd31412818ae25bcf32b1ffd..220e585c85158c905d58a9e13afaf2f32fedfe85 100644 (file)
@@ -372,7 +372,7 @@ static int jr3_pci_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
        return result;
 }
 
-static void jr3_pci_open(comedi_device * dev)
+static int jr3_pci_open(comedi_device * dev)
 {
        int i;
        jr3_pci_dev_private *devpriv = dev->private;
@@ -387,6 +387,7 @@ static void jr3_pci_open(comedi_device * dev)
                                p->channel_no);
                }
        }
+       return 0;
 }
 
 int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
index b0e285e8c0cf02f843af4a934ff883f9ce0a99d6..974f0a1c42bd7776f10c9126178ee5f31c15a810 100644 (file)
@@ -390,15 +390,16 @@ static void serial_write(struct file *f, struct serial_data data)
        }
 }
 
-static void serial_2002_open(comedi_device * dev)
+static int serial_2002_open(comedi_device * dev)
 {
+       int result;
        char port[20];
 
        sprintf(port, "/dev/ttyS%d", devpriv->port);
        devpriv->tty = filp_open(port, 0, O_RDWR);
        if (IS_ERR(devpriv->tty)) {
-               printk("serial_2002: file open error = %ld\n",
-                       PTR_ERR(devpriv->tty));
+               result = (int)PTR_ERR(devpriv->tty);
+               printk("serial_2002: file open error = %d\n", result);
        } else {
                typedef struct {
                        short int kind;
@@ -651,7 +652,9 @@ static void serial_2002_open(comedi_device * dev)
                                }
                        }
                }
+               result = 0;
        }
+       return result;
 }
 
 static void serial_2002_close(comedi_device * dev)
index b8db13805c9dabd48fc2b14df2e74571bf831519..6672d6e3fe749ba62847f73b06faca465c71303a 100644 (file)
@@ -286,7 +286,7 @@ struct comedi_device_struct {
 
        struct fasync_struct *async_queue;
 
-       void (*open) (comedi_device * dev);
+       int (*open) (comedi_device * dev);
        void (*close) (comedi_device * dev);
 };