]> err.no Git - linux-2.6/blobdiff - drivers/char/pcmcia/cm4000_cs.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bunk/trivial
[linux-2.6] / drivers / char / pcmcia / cm4000_cs.c
index 211c93fda6fc6c789bbe5edc55b4c0618ae98661..fee58e03dbe2bb30e5d8d715e9fab42be3b04e85 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
+#include <linux/bitrev.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -194,41 +195,17 @@ static inline unsigned char xinb(unsigned short port)
 }
 #endif
 
-#define        b_0000  15
-#define        b_0001  14
-#define        b_0010  13
-#define        b_0011  12
-#define        b_0100  11
-#define        b_0101  10
-#define        b_0110  9
-#define        b_0111  8
-#define        b_1000  7
-#define        b_1001  6
-#define        b_1010  5
-#define        b_1011  4
-#define        b_1100  3
-#define        b_1101  2
-#define        b_1110  1
-#define        b_1111  0
-
-static unsigned char irtab[16] = {
-       b_0000, b_1000, b_0100, b_1100,
-       b_0010, b_1010, b_0110, b_1110,
-       b_0001, b_1001, b_0101, b_1101,
-       b_0011, b_1011, b_0111, b_1111
-};
+static inline unsigned char invert_revert(unsigned char ch)
+{
+       return bitrev8(~ch);
+}
 
 static void str_invert_revert(unsigned char *b, int len)
 {
        int i;
 
        for (i = 0; i < len; i++)
-               b[i] = (irtab[b[i] & 0x0f] << 4) | irtab[b[i] >> 4];
-}
-
-static unsigned char invert_revert(unsigned char ch)
-{
-       return (irtab[ch & 0x0f] << 4) | irtab[ch >> 4];
+               b[i] = invert_revert(b[i]);
 }
 
 #define        ATRLENCK(dev,pos) \
@@ -946,8 +923,7 @@ release_io:
 
 return_with_timer:
        DEBUGP(7, dev, "<- monitor_card (returns with timer)\n");
-       dev->timer.expires = jiffies + dev->mdelay;
-       add_timer(&dev->timer);
+       mod_timer(&dev->timer, jiffies + dev->mdelay);
        clear_bit(LOCK_MONITOR, &dev->flags);
 }
 
@@ -1115,7 +1091,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf,
        /*
         * wait for atr to become valid.
         * note: it is important to lock this code. if we dont, the monitor
-        * could be run between test_bit and the the call the sleep on the
+        * could be run between test_bit and the call to sleep on the
         * atr-queue.  if *then* the monitor detects atr valid, it will wake up
         * any process on the atr-queue, *but* since we have been interrupted,
         * we do not yet sleep on this queue. this would result in a missed
@@ -1406,12 +1382,9 @@ static void start_monitor(struct cm4000_dev *dev)
        DEBUGP(3, dev, "-> start_monitor\n");
        if (!dev->monitor_running) {
                DEBUGP(5, dev, "create, init and add timer\n");
-               init_timer(&dev->timer);
+               setup_timer(&dev->timer, monitor_card, (unsigned long)dev);
                dev->monitor_running = 1;
-               dev->timer.expires = jiffies;
-               dev->timer.data = (unsigned long) dev;
-               dev->timer.function = monitor_card;
-               add_timer(&dev->timer);
+               mod_timer(&dev->timer, jiffies);
        } else
                DEBUGP(5, dev, "monitor already running\n");
        DEBUGP(3, dev, "<- start_monitor\n");
@@ -1885,8 +1858,11 @@ static int cm4000_probe(struct pcmcia_device *link)
        init_waitqueue_head(&dev->readq);
 
        ret = cm4000_config(link, i);
-       if (ret)
+       if (ret) {
+               dev_table[i] = NULL;
+               kfree(dev);
                return ret;
+       }
 
        class_device_create(cmm_class, NULL, MKDEV(major, i), NULL,
                            "cmm%d", i);
@@ -1911,7 +1887,7 @@ static void cm4000_detach(struct pcmcia_device *link)
        cm4000_release(link);
 
        dev_table[devno] = NULL;
-       kfree(dev);
+       kfree(dev);
 
        class_device_destroy(cmm_class, MKDEV(major, devno));
 
@@ -1960,12 +1936,14 @@ static int __init cmm_init(void)
        if (major < 0) {
                printk(KERN_WARNING MODULE_NAME
                        ": could not get major number\n");
+               class_destroy(cmm_class);
                return major;
        }
 
        rc = pcmcia_register_driver(&cm4000_driver);
        if (rc < 0) {
                unregister_chrdev(major, DEVICE_NAME);
+               class_destroy(cmm_class);
                return rc;
        }