Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[safe/jmp/linux-2.6] / drivers / ieee1394 / dv1394.c
index 6e71d68..c19f232 100644 (file)
@@ -94,7 +94,6 @@
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/poll.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/bitops.h>
 #include <asm/byteorder.h>
 #if DV1394_DEBUG_LEVEL >= 2
 #define irq_printk( args... ) printk( args )
 #else
-#define irq_printk( args... )
+#define irq_printk( args... ) do {} while (0)
 #endif
 
 #if DV1394_DEBUG_LEVEL >= 1
 #define debug_printk( args... ) printk( args)
 #else
-#define debug_printk( args... )
+#define debug_printk( args... ) do {} while (0)
 #endif
 
 /* issue a dummy PCI read to force the preceding write
@@ -919,7 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
                /* default SYT offset is 3 cycles */
                init->syt_offset = 3;
 
-       if ( (init->channel > 63) || (init->channel < 0) )
+       if (init->channel > 63)
                init->channel = 63;
 
        chan_mask = (u64)1 << init->channel;
@@ -1271,8 +1270,14 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
        struct video_card *video = file_to_video_card(file);
        int retval = -EINVAL;
 
-       /* serialize mmap */
-       mutex_lock(&video->mtx);
+       /*
+        * We cannot use the blocking variant mutex_lock here because .mmap
+        * is called with mmap_sem held, while .ioctl, .read, .write acquire
+        * video->mtx and subsequently call copy_to/from_user which will
+        * grab mmap_sem in case of a page fault.
+        */
+       if (!mutex_trylock(&video->mtx))
+               return -EAGAIN;
 
        if ( ! video_card_initialized(video) ) {
                retval = do_dv1394_init_default(video);
@@ -1536,27 +1541,20 @@ static ssize_t dv1394_read(struct file *file,  char __user *buffer, size_t count
 
 static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-       struct video_card *video;
+       struct video_card *video = file_to_video_card(file);
        unsigned long flags;
        int ret = -EINVAL;
        void __user *argp = (void __user *)arg;
 
        DECLARE_WAITQUEUE(wait, current);
 
-       lock_kernel();
-       video = file_to_video_card(file);
-
        /* serialize this to prevent multi-threaded mayhem */
        if (file->f_flags & O_NONBLOCK) {
-               if (!mutex_trylock(&video->mtx)) {
-                       unlock_kernel();
+               if (!mutex_trylock(&video->mtx))
                        return -EAGAIN;
-               }
        } else {
-               if (mutex_lock_interruptible(&video->mtx)) {
-                       unlock_kernel();
+               if (mutex_lock_interruptible(&video->mtx))
                        return -ERESTARTSYS;
-               }
        }
 
        switch(cmd)
@@ -1780,7 +1778,6 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
  out:
        mutex_unlock(&video->mtx);
-       unlock_kernel();
        return ret;
 }
 
@@ -1837,9 +1834,6 @@ static int dv1394_release(struct inode *inode, struct file *file)
        /* OK to free the DMA buffer, no more mappings can exist */
        do_dv1394_shutdown(video, 1);
 
-       /* clean up async I/O users */
-       dv1394_fasync(-1, file, 0);
-
        /* give someone else a turn */
        clear_bit(0, &video->open);
 
@@ -2155,7 +2149,7 @@ out:
 }
 
 static struct cdev dv1394_cdev;
-static struct file_operations dv1394_fops=
+static const struct file_operations dv1394_fops=
 {
        .owner =        THIS_MODULE,
        .poll =         dv1394_poll,
@@ -2176,6 +2170,7 @@ static struct file_operations dv1394_fops=
 /*
  * Export information about protocols/devices supported by this driver.
  */
+#ifdef MODULE
 static struct ieee1394_device_id dv1394_id_table[] = {
        {
                .match_flags    = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
@@ -2186,14 +2181,10 @@ static struct ieee1394_device_id dv1394_id_table[] = {
 };
 
 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
+#endif /* MODULE */
 
 static struct hpsb_protocol_driver dv1394_driver = {
-       .name           = "DV/1394 Driver",
-       .id_table       = dv1394_id_table,
-       .driver         = {
-               .name   = "dv1394",
-               .bus    = &ieee1394_bus_type,
-       },
+       .name = "dv1394",
 };
 
 
@@ -2267,49 +2258,37 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes
        return 0;
 }
 
-static void dv1394_un_init(struct video_card *video)
+static void dv1394_remove_host(struct hpsb_host *host)
 {
-       /* obviously nobody has the driver open at this point */
-       do_dv1394_shutdown(video, 1);
-       kfree(video);
-}
-
-
-static void dv1394_remove_host (struct hpsb_host *host)
-{
-       struct video_card *video;
+       struct video_card *video, *tmp_video;
        unsigned long flags;
-       int id = host->id;
-
-       /* We only work with the OHCI-1394 driver */
-       if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
-               return;
+       int found_ohci_card = 0;
 
-       /* find the corresponding video_cards */
        do {
-               struct video_card *tmp_vid;
-
                video = NULL;
-
                spin_lock_irqsave(&dv1394_cards_lock, flags);
-               list_for_each_entry(tmp_vid, &dv1394_cards, list) {
-                       if ((tmp_vid->id >> 2) == id) {
-                               list_del(&tmp_vid->list);
-                               video = tmp_vid;
+               list_for_each_entry(tmp_video, &dv1394_cards, list) {
+                       if ((tmp_video->id >> 2) == host->id) {
+                               list_del(&tmp_video->list);
+                               video = tmp_video;
+                               found_ohci_card = 1;
                                break;
                        }
                }
                spin_unlock_irqrestore(&dv1394_cards_lock, flags);
 
-               if (video)
-                       dv1394_un_init(video);
-       } while (video != NULL);
+               if (video) {
+                       do_dv1394_shutdown(video, 1);
+                       kfree(video);
+               }
+       } while (video);
 
-       class_device_destroy(hpsb_protocol_class,
-               MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)));
+       if (found_ohci_card)
+               device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
+                          IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2)));
 }
 
-static void dv1394_add_host (struct hpsb_host *host)
+static void dv1394_add_host(struct hpsb_host *host)
 {
        struct ti_ohci *ohci;
        int id = host->id;
@@ -2320,9 +2299,10 @@ static void dv1394_add_host (struct hpsb_host *host)
 
        ohci = (struct ti_ohci *)host->hostdata;
 
-       class_device_create(hpsb_protocol_class, NULL, MKDEV(
-               IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), 
-               NULL, "dv1394-%d", id);
+       device_create(hpsb_protocol_class, NULL,
+                     MKDEV(IEEE1394_MAJOR,
+                           IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
+                     NULL, "dv1394-%d", id);
 
        dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
        dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
@@ -2587,9 +2567,12 @@ static int __init dv1394_init_module(void)
 {
        int ret;
 
+       printk(KERN_WARNING
+              "NOTE: The dv1394 driver is unsupported and may be removed in a "
+              "future Linux release. Use raw1394 instead.\n");
+
        cdev_init(&dv1394_cdev, &dv1394_fops);
        dv1394_cdev.owner = THIS_MODULE;
-       kobject_set_name(&dv1394_cdev.kobj, "dv1394");
        ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16);
        if (ret) {
                printk(KERN_ERR "dv1394: unable to register character device\n");