diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index aeb2c00875cd..14091313cebb 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1845,8 +1845,15 @@ ok: } } - if (dev->attached && dev->use_count == 0 && dev->open) - dev->open(dev); + if (dev->attached && dev->use_count == 0 && dev->open) { + 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++; diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 4eb2b77f56dc..41ef9207f99c 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -285,7 +285,7 @@ struct comedi_device { struct fasync_struct *async_queue; - void (*open) (struct comedi_device *dev); + int (*open) (struct comedi_device *dev); void (*close) (struct comedi_device *dev); }; diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 96caae36279c..d01d2dc79112 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -890,8 +890,10 @@ static struct usb_driver dt9812_usb_driver = { * Comedi functions */ -static void dt9812_comedi_open(struct comedi_device *dev) +static int dt9812_comedi_open(struct comedi_device *dev) { + int result = -ENODEV; + down(&devpriv->slot->mutex); if (devpriv->slot->usb) { /* We have an attached device, fill in current range info */ @@ -934,8 +936,10 @@ static void dt9812_comedi_open(struct comedi_device *dev) } break; } + result = 0; } up(&devpriv->slot->mutex); + return result; } static int dt9812_di_rinsn(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index d330b1886846..4683a0b90f22 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -373,7 +373,7 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, return result; } -static void jr3_pci_open(struct comedi_device *dev) +static int jr3_pci_open(struct comedi_device *dev) { int i; struct jr3_pci_dev_private *devpriv = dev->private; @@ -388,6 +388,7 @@ static void jr3_pci_open(struct comedi_device *dev) p->channel_no); } } + return 0; } int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 0792617ebc35..a4a99b870369 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -393,15 +393,16 @@ static void serial_write(struct file *f, struct serial_data data) } } -static void serial_2002_open(struct comedi_device *dev) +static int serial_2002_open(struct comedi_device *dev) { + int result; char port[20]; sprintf(port, "/dev/ttyS%d", devpriv->port); devpriv->tty = filp_open(port, O_RDWR, 0); 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 { struct config_t { @@ -673,7 +674,9 @@ static void serial_2002_open(struct comedi_device *dev) } } } + result = 0; } + return result; } static void serial_2002_close(struct comedi_device *dev)