Merge branch 'kmemtrace-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / drivers / staging / comedi / drivers.c
index 36a93b95e3f24027c55cb01d2dd8da5b641dd0cb..6e13e450dc73979812fc8b50accbd19ef336f82f 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/usb.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
-static int postconfig(comedi_device * dev);
-static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
-       comedi_insn * insn, lsampl_t * data);
-static void *comedi_recognize(comedi_driver * driv, const char *name);
-static void comedi_report_boards(comedi_driver * driv);
-static int poll_invalid(comedi_device * dev, comedi_subdevice * s);
-int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
+static int postconfig(struct comedi_device *dev);
+static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+       struct comedi_insn *insn, unsigned int *data);
+static void *comedi_recognize(struct comedi_driver * driv, const char *name);
+static void comedi_report_boards(struct comedi_driver *driv);
+static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s);
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
        unsigned long new_size);
 
-comedi_driver *comedi_drivers;
+struct comedi_driver *comedi_drivers;
 
 int comedi_modprobe(int minor)
 {
        return -EINVAL;
 }
 
-static void cleanup_device(comedi_device * dev)
+static void cleanup_device(struct comedi_device *dev)
 {
        int i;
-       comedi_subdevice *s;
+       struct comedi_subdevice *s;
 
        if (dev->subdevices) {
                for (i = 0; i < dev->n_subdevices; i++) {
@@ -80,10 +81,8 @@ static void cleanup_device(comedi_device * dev)
                dev->subdevices = NULL;
                dev->n_subdevices = 0;
        }
-       if (dev->private) {
-               kfree(dev->private);
-               dev->private = NULL;
-       }
+       kfree(dev->private);
+       dev->private = NULL;
        dev->driver = 0;
        dev->board_name = NULL;
        dev->board_ptr = NULL;
@@ -96,7 +95,7 @@ static void cleanup_device(comedi_device * dev)
        comedi_set_hw_dev(dev, NULL);
 }
 
-static void __comedi_device_detach(comedi_device * dev)
+static void __comedi_device_detach(struct comedi_device *dev)
 {
        dev->attached = 0;
        if (dev->driver) {
@@ -107,16 +106,16 @@ static void __comedi_device_detach(comedi_device * dev)
        cleanup_device(dev);
 }
 
-void comedi_device_detach(comedi_device * dev)
+void comedi_device_detach(struct comedi_device *dev)
 {
        if (!dev->attached)
                return;
        __comedi_device_detach(dev);
 }
 
-int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
+int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-       comedi_driver *driv;
+       struct comedi_driver *driv;
        int ret;
 
        if (dev->attached)
@@ -139,7 +138,7 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
                                continue;
                        }
                }
-               //initialize dev->driver here so comedi_error() can be called from attach
+               /* initialize dev->driver here so comedi_error() can be called from attach */
                dev->driver = driv;
                ret = driv->attach(dev, it);
                if (ret < 0) {
@@ -150,8 +149,8 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
                goto attached;
        }
 
-       // recognize has failed if we get here
-       // report valid board names before returning error
+       /*  recognize has failed if we get here */
+       /*  report valid board names before returning error */
        for (driv = comedi_drivers; driv; driv = driv->next) {
                if (!try_module_get(driv->module)) {
                        printk("comedi: failed to increment module count\n");
@@ -181,7 +180,7 @@ attached:
        return 0;
 }
 
-int comedi_driver_register(comedi_driver * driver)
+int comedi_driver_register(struct comedi_driver *driver)
 {
        driver->next = comedi_drivers;
        comedi_drivers = driver;
@@ -189,15 +188,15 @@ int comedi_driver_register(comedi_driver * driver)
        return 0;
 }
 
-int comedi_driver_unregister(comedi_driver * driver)
+int comedi_driver_unregister(struct comedi_driver *driver)
 {
-       comedi_driver *prev;
+       struct comedi_driver *prev;
        int i;
 
        /* check for devices using this driver */
        for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
                struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
-               comedi_device *dev;
+               struct comedi_device *dev;
 
                if(dev_file_info == NULL) continue;
                dev = dev_file_info->device;
@@ -225,11 +224,11 @@ int comedi_driver_unregister(comedi_driver * driver)
        return -EINVAL;
 }
 
-static int postconfig(comedi_device * dev)
+static int postconfig(struct comedi_device *dev)
 {
        int i;
-       comedi_subdevice *s;
-       comedi_async *async = NULL;
+       struct comedi_subdevice *s;
+       struct comedi_async *async = NULL;
        int ret;
 
        for (i = 0; i < dev->n_subdevices; i++) {
@@ -246,7 +245,7 @@ static int postconfig(comedi_device * dev)
                                SDF_CMD_WRITE)) == 0);
                        BUG_ON(!s->do_cmdtest);
 
-                       async = kzalloc(sizeof(comedi_async), GFP_KERNEL);
+                       async = kzalloc(sizeof(struct comedi_async), GFP_KERNEL);
                        if (async == NULL) {
                                printk("failed to allocate async struct\n");
                                return -ENOMEM;
@@ -298,8 +297,8 @@ static int postconfig(comedi_device * dev)
        return 0;
 }
 
-// generic recognize function for drivers that register their supported board names
-void *comedi_recognize(comedi_driver * driv, const char *name)
+/*  generic recognize function for drivers that register their supported board names */
+void *comedi_recognize(struct comedi_driver * driv, const char *name)
 {
        unsigned i;
        const char *const *name_ptr = driv->board_name;
@@ -314,7 +313,7 @@ void *comedi_recognize(comedi_driver * driv, const char *name)
        return NULL;
 }
 
-void comedi_report_boards(comedi_driver * driv)
+void comedi_report_boards(struct comedi_driver *driv)
 {
        unsigned int i;
        const char *const *name_ptr;
@@ -332,28 +331,28 @@ void comedi_report_boards(comedi_driver * driv)
                printk(" %s\n", driv->driver_name);
 }
 
-static int poll_invalid(comedi_device * dev, comedi_subdevice * s)
+static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        return -EINVAL;
 }
 
-int insn_inval(comedi_device * dev, comedi_subdevice * s,
-       comedi_insn * insn, lsampl_t * data)
+int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+       struct comedi_insn *insn, unsigned int *data)
 {
        return -EINVAL;
 }
 
-static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
-       comedi_insn * insn, lsampl_t * data)
+static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+       struct comedi_insn *insn, unsigned int *data)
 {
-       comedi_insn new_insn;
+       struct comedi_insn new_insn;
        int ret;
        static const unsigned channels_per_bitfield = 32;
 
        unsigned chan = CR_CHAN(insn->chanspec);
        const unsigned base_bitfield_channel =
                (chan < channels_per_bitfield) ? 0 : chan;
-       lsampl_t new_data[2];
+       unsigned int new_data[2];
        memset(new_data, 0, sizeof(new_data));
        memset(&new_insn, 0, sizeof(new_insn));
        new_insn.insn = INSN_BITS;
@@ -380,7 +379,7 @@ static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
        return 1;
 }
 
-static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr)
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
 {
        unsigned long ret = 0UL;
        pmd_t *pmd;
@@ -413,10 +412,10 @@ static inline unsigned long kvirt_to_kva(unsigned long adr)
        return kva;
 }
 
-int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
        unsigned long new_size)
 {
-       comedi_async *async = s->async;
+       struct comedi_async *async = s->async;
 
        /* Round up new_size to multiple of PAGE_SIZE */
        new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
@@ -425,7 +424,7 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
        if (async->prealloc_buf && async->prealloc_bufsz == new_size) {
                return 0;
        }
-       // deallocate old buffer
+       /*  deallocate old buffer */
        if (async->prealloc_buf) {
                vunmap(async->prealloc_buf);
                async->prealloc_buf = NULL;
@@ -454,7 +453,7 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
                async->buf_page_list = NULL;
                async->n_buf_pages = 0;
        }
-       // allocate new buffer
+       /*  allocate new buffer */
        if (new_size) {
                unsigned i = 0;
                unsigned n_pages = new_size >> PAGE_SHIFT;
@@ -537,16 +536,15 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
 
 /* munging is applied to data by core as it passes between user
  * and kernel space */
-unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
+unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes)
 {
-       comedi_subdevice *s = async->subdevice;
+       struct comedi_subdevice *s = async->subdevice;
        unsigned int count = 0;
        const unsigned num_sample_bytes = bytes_per_sample(s);
 
        if (s->munge == NULL || (async->cmd.flags & CMDF_RAWDATA)) {
                async->munge_count += num_bytes;
-               if ((int)(async->munge_count - async->buf_write_count) > 0)
-                       BUG();
+               BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
                return num_bytes;
        }
        /* don't munge partial samples */
@@ -567,7 +565,7 @@ unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
                s->munge(s->device, s, async->prealloc_buf + async->munge_ptr,
                        block_size, async->munge_chan);
 
-               smp_wmb();      //barrier insures data is munged in buffer before munge_count is incremented
+               smp_wmb();      /* barrier insures data is munged in buffer before munge_count is incremented */
 
                async->munge_chan += block_size / num_sample_bytes;
                async->munge_chan %= async->cmd.chanlist_len;
@@ -576,12 +574,11 @@ unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
                async->munge_ptr %= async->prealloc_bufsz;
                count += block_size;
        }
-       if ((int)(async->munge_count - async->buf_write_count) > 0)
-               BUG();
+       BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
        return count;
 }
 
-unsigned int comedi_buf_write_n_available(comedi_async * async)
+unsigned int comedi_buf_write_n_available(struct comedi_async *async)
 {
        unsigned int free_end;
        unsigned int nbytes;
@@ -601,7 +598,7 @@ unsigned int comedi_buf_write_n_available(comedi_async * async)
 }
 
 /* allocates chunk for the writer from free buffer space */
-unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
+unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes)
 {
        unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
 
@@ -616,7 +613,7 @@ unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
 }
 
 /* allocates nothing unless it can completely fulfill the request */
-unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
+unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
        unsigned int nbytes)
 {
        unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
@@ -632,7 +629,7 @@ unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
 }
 
 /* transfers a chunk from writer to filled buffer space */
-unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
+unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
 {
        if ((int)(async->buf_write_count + nbytes -
                        async->buf_write_alloc_count) > 0) {
@@ -650,7 +647,7 @@ unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
 }
 
 /* allocates a chunk for the reader from filled (and munged) buffer space */
-unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
+unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes)
 {
        if ((int)(async->buf_read_alloc_count + nbytes - async->munge_count) >
                0) {
@@ -664,9 +661,9 @@ unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
 }
 
 /* transfers control of a chunk from reader to free buffer space */
-unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
+unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes)
 {
-       // barrier insures data has been read out of buffer before read count is incremented
+       /*  barrier insures data has been read out of buffer before read count is incremented */
        smp_mb();
        if ((int)(async->buf_read_count + nbytes -
                        async->buf_read_alloc_count) > 0) {
@@ -680,7 +677,7 @@ unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
        return nbytes;
 }
 
-void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
+void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
        const void *data, unsigned int num_bytes)
 {
        unsigned int write_ptr = async->buf_write_ptr + offset;
@@ -705,7 +702,7 @@ void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
        }
 }
 
-void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
+void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
        void *dest, unsigned int nbytes)
 {
        void *src;
@@ -731,7 +728,7 @@ void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
        }
 }
 
-unsigned int comedi_buf_read_n_available(comedi_async * async)
+unsigned int comedi_buf_read_n_available(struct comedi_async *async)
 {
        unsigned num_bytes;
 
@@ -746,32 +743,32 @@ unsigned int comedi_buf_read_n_available(comedi_async * async)
        return num_bytes;
 }
 
-int comedi_buf_get(comedi_async * async, sampl_t * x)
+int comedi_buf_get(struct comedi_async *async, short *x)
 {
        unsigned int n = comedi_buf_read_n_available(async);
 
-       if (n < sizeof(sampl_t))
+       if (n < sizeof(short))
                return 0;
-       comedi_buf_read_alloc(async, sizeof(sampl_t));
-       *x = *(sampl_t *) (async->prealloc_buf + async->buf_read_ptr);
-       comedi_buf_read_free(async, sizeof(sampl_t));
+       comedi_buf_read_alloc(async, sizeof(short));
+       *x = *(short *) (async->prealloc_buf + async->buf_read_ptr);
+       comedi_buf_read_free(async, sizeof(short));
        return 1;
 }
 
-int comedi_buf_put(comedi_async * async, sampl_t x)
+int comedi_buf_put(struct comedi_async *async, short x)
 {
-       unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(sampl_t));
+       unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(short));
 
-       if (n < sizeof(sampl_t)) {
+       if (n < sizeof(short)) {
                async->events |= COMEDI_CB_ERROR;
                return 0;
        }
-       *(sampl_t *) (async->prealloc_buf + async->buf_write_ptr) = x;
-       comedi_buf_write_free(async, sizeof(sampl_t));
+       *(short *) (async->prealloc_buf + async->buf_write_ptr) = x;
+       comedi_buf_write_free(async, sizeof(short));
        return 1;
 }
 
-void comedi_reset_async_buf(comedi_async * async)
+void comedi_reset_async_buf(struct comedi_async *async)
 {
        async->buf_write_alloc_count = 0;
        async->buf_write_count = 0;
@@ -792,14 +789,27 @@ void comedi_reset_async_buf(comedi_async * async)
 
 int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options)
 {
-       comedi_devconfig it;
+       struct comedi_devconfig it;
        int minor;
        struct comedi_device_file_info *dev_file_info;
        int retval;
+       unsigned *private_data = NULL;
+
+       if (!comedi_autoconfig) {
+               dev_set_drvdata(hardware_device, NULL);
+               return 0;
+       }
 
        minor = comedi_alloc_board_minor(hardware_device);
        if(minor < 0) return minor;
-       dev_set_drvdata(hardware_device, (void*)(unsigned long)minor);
+
+       private_data = kmalloc(sizeof(unsigned), GFP_KERNEL);
+       if (private_data == NULL) {
+               retval = -ENOMEM;
+               goto cleanup;
+       }
+       *private_data = minor;
+       dev_set_drvdata(hardware_device, private_data);
 
        dev_file_info = comedi_get_device_file_info(minor);
 
@@ -812,8 +822,11 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
        mutex_lock(&dev_file_info->device->mutex);
        retval = comedi_device_attach(dev_file_info->device, &it);
        mutex_unlock(&dev_file_info->device->mutex);
+
+cleanup:
        if(retval < 0)
        {
+               kfree(private_data);
                comedi_free_board_minor(minor);
        }
        return retval;
@@ -821,20 +834,23 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
 
 void comedi_auto_unconfig(struct device *hardware_device)
 {
-       unsigned long minor = (unsigned long)dev_get_drvdata(hardware_device);
+       unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device);
+       if(minor == NULL) return;
 
-       BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
+       BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS);
 
-       comedi_free_board_minor(minor);
+       comedi_free_board_minor(*minor);
+       dev_set_drvdata(hardware_device, NULL);
+       kfree(minor);
 }
 
 int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name)
 {
        int options[2];
 
-       // pci bus
+       /*  pci bus */
        options[0] = pcidev->bus->number;
-       // pci slot
+       /*  pci slot */
        options[1] = PCI_SLOT(pcidev->devfn);
 
        return comedi_auto_config(&pcidev->dev, board_name, options, sizeof(options) / sizeof(options[0]));
@@ -844,3 +860,16 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
 {
        comedi_auto_unconfig(&pcidev->dev);
 }
+
+int comedi_usb_auto_config(struct usb_device *usbdev,
+       const char *board_name)
+{
+       BUG_ON(usbdev == NULL);
+       return comedi_auto_config(&usbdev->dev, board_name, NULL, 0);
+}
+
+void comedi_usb_auto_unconfig(struct usb_device *usbdev)
+{
+       BUG_ON(usbdev == NULL);
+       comedi_auto_unconfig(&usbdev->dev);
+}