]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/char/pcmcia/cm4000_cs.c
[PATCH] pcmcia: embed dev_link_t into struct pcmcia_device
[mirror_ubuntu-artful-kernel.git] / drivers / char / pcmcia / cm4000_cs.c
index 649677b5dc36ad93a6badd5ee24f20301fb1b5b3..3e6d6e0bb6ee8d6666af08807c6f7cd28f7261fa 100644 (file)
   *
   * (C) 2000,2001,2002,2003,2004 Omnikey AG
   *
-  * (C) 2005 Harald Welte <laforge@gnumonks.org>
+  * (C) 2005-2006 Harald Welte <laforge@gnumonks.org>
   *    - Adhere to Kernel CodingStyle
   *    - Port to 2.6.13 "new" style PCMCIA
   *    - Check for copy_{from,to}_user return values
   *    - Use nonseekable_open()
+  *    - add class interface for udev device creation
   *
   * All rights reserved. Licensed under dual BSD/GPL license.
   */
@@ -45,7 +46,7 @@
 /* #define ATR_CSUM */
 
 #ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)       (&handle_to_dev(x->link.handle))
+#define reader_to_dev(x)       (&handle_to_dev(x->p_dev->handle))
 static int pc_debug = PCMCIA_DEBUG;
 module_param(pc_debug, int, 0600);
 #define DEBUGP(n, rdr, x, args...) do {                                \
@@ -56,7 +57,7 @@ module_param(pc_debug, int, 0600);
 #else
 #define DEBUGP(n, rdr, x, args...)
 #endif
-static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";
+static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
 
 #define        T_1SEC          (HZ)
 #define        T_10MSEC        msecs_to_jiffies(10)
@@ -105,7 +106,7 @@ static int major;           /* major number we get from the kernel */
 #define REG_STOPBITS(x)                (x + 7)
 
 struct cm4000_dev {
-       dev_link_t link;                /* pcmcia link */
+       struct pcmcia_device *p_dev;
        dev_node_t node;                /* OS node (major,minor) */
 
        unsigned char atr[MAX_ATR];
@@ -156,6 +157,7 @@ struct cm4000_dev {
                /*queue*/ 4*sizeof(wait_queue_head_t))
 
 static dev_link_t *dev_table[CM4000_MAX_DEV];
+static struct class *cmm_class;
 
 /* This table doesn't use spaces after the comma between fields and thus
  * violates CodingStyle.  However, I don't really think wrapping it around will
@@ -452,7 +454,7 @@ static struct card_fixup card_fixups[] = {
 static void set_cardparameter(struct cm4000_dev *dev)
 {
        int i;
-       ioaddr_t iobase = dev->link.io.BasePort1;
+       ioaddr_t iobase = dev->p_dev->io.BasePort1;
        u_int8_t stopbits = 0x02; /* ISO default */
 
        DEBUGP(3, dev, "-> set_cardparameter\n");
@@ -485,7 +487,7 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
        unsigned short num_bytes_read;
        unsigned char pts_reply[4];
        ssize_t rc;
-       ioaddr_t iobase = dev->link.io.BasePort1;
+       ioaddr_t iobase = dev->p_dev->io.BasePort1;
 
        rc = 0;
 
@@ -697,7 +699,7 @@ static void terminate_monitor(struct cm4000_dev *dev)
 static void monitor_card(unsigned long p)
 {
        struct cm4000_dev *dev = (struct cm4000_dev *) p;
-       ioaddr_t iobase = dev->link.io.BasePort1;
+       ioaddr_t iobase = dev->p_dev->io.BasePort1;
        unsigned short s;
        struct ptsreq ptsreq;
        int i, atrc;
@@ -960,7 +962,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
                        loff_t *ppos)
 {
        struct cm4000_dev *dev = filp->private_data;
-       ioaddr_t iobase = dev->link.io.BasePort1;
+       ioaddr_t iobase = dev->p_dev->io.BasePort1;
        ssize_t rc;
        int i, j, k;
 
@@ -969,7 +971,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
        if (count == 0)         /* according to manpage */
                return 0;
 
-       if ((dev->link.state & DEV_PRESENT) == 0 ||     /* socket removed */
+       if ((dev->p_dev->state & DEV_PRESENT) == 0 ||   /* socket removed */
            test_bit(IS_CMM_ABSENT, &dev->flags))
                return -ENODEV;
 
@@ -1081,7 +1083,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf,
                         size_t count, loff_t *ppos)
 {
        struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
-       ioaddr_t iobase = dev->link.io.BasePort1;
+       ioaddr_t iobase = dev->p_dev->io.BasePort1;
        unsigned short s;
        unsigned char tmp;
        unsigned char infolen;
@@ -1106,7 +1108,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf,
 
        sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0;
 
-       if ((dev->link.state & DEV_PRESENT) == 0 ||     /* socket removed */
+       if ((dev->p_dev->state & DEV_PRESENT) == 0 ||   /* socket removed */
            test_bit(IS_CMM_ABSENT, &dev->flags))
                return -ENODEV;
 
@@ -1438,7 +1440,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                     unsigned long arg)
 {
        struct cm4000_dev *dev = filp->private_data;
-       ioaddr_t iobase = dev->link.io.BasePort1;
+       ioaddr_t iobase = dev->p_dev->io.BasePort1;
        dev_link_t *link;
        int size;
        int rc;
@@ -1763,7 +1765,6 @@ static void cm4000_config(dev_link_t * link, int devno)
        struct cm4000_dev *dev;
        tuple_t tuple;
        cisparse_t parse;
-       config_info_t conf;
        u_char buf[64];
        int fail_fn, fail_rc;
        int rc;
@@ -1788,16 +1789,10 @@ static void cm4000_config(dev_link_t * link, int devno)
                fail_fn = ParseTuple;
                goto cs_failed;
        }
-       if ((fail_rc =
-            pcmcia_get_configuration_info(handle, &conf)) != CS_SUCCESS) {
-               fail_fn = GetConfigurationInfo;
-               goto cs_failed;
-       }
 
        link->state |= DEV_CONFIG;
        link->conf.ConfigBase = parse.config.base;
        link->conf.Present = parse.config.rmask[0];
-       link->conf.Vcc = conf.Vcc;
 
        link->io.BasePort2 = 0;
        link->io.NumPorts2 = 0;
@@ -1849,7 +1844,7 @@ static void cm4000_config(dev_link_t * link, int devno)
        dev->node.major = major;
        dev->node.minor = devno;
        dev->node.next = NULL;
-       link->dev = &dev->node;
+       link->dev_node = &dev->node;
        link->state &= ~DEV_CONFIG_PENDING;
 
        return;
@@ -1868,10 +1863,6 @@ static int cm4000_suspend(struct pcmcia_device *p_dev)
        struct cm4000_dev *dev;
 
        dev = link->priv;
-
-       link->state |= DEV_SUSPEND;
-       if (link->state & DEV_CONFIG)
-               pcmcia_release_configuration(link->handle);
        stop_monitor(dev);
 
        return 0;
@@ -1883,11 +1874,6 @@ static int cm4000_resume(struct pcmcia_device *p_dev)
        struct cm4000_dev *dev;
 
        dev = link->priv;
-
-       link->state &= ~DEV_SUSPEND;
-       if (link->state & DEV_CONFIG)
-               pcmcia_request_configuration(link->handle, &link->conf);
-
        if (link->open)
                start_monitor(dev);
 
@@ -1897,15 +1883,14 @@ static int cm4000_resume(struct pcmcia_device *p_dev)
 static void cm4000_release(dev_link_t *link)
 {
        cmm_cm4000_release(link->priv); /* delay release until device closed */
-       pcmcia_release_configuration(link->handle);
-       pcmcia_release_io(link->handle, &link->io);
+       pcmcia_disable_device(link->handle);
 }
 
 static int cm4000_attach(struct pcmcia_device *p_dev)
 {
        struct cm4000_dev *dev;
-       dev_link_t *link;
        int i;
+       dev_link_t *link = dev_to_instance(p_dev);
 
        for (i = 0; i < CM4000_MAX_DEV; i++)
                if (dev_table[i] == NULL)
@@ -1921,7 +1906,7 @@ static int cm4000_attach(struct pcmcia_device *p_dev)
        if (dev == NULL)
                return -ENOMEM;
 
-       link = &dev->link;
+       dev->p_dev = p_dev;
        link->priv = dev;
        link->conf.IntType = INT_MEMORY_AND_IO;
        dev_table[i] = link;
@@ -1931,12 +1916,12 @@ static int cm4000_attach(struct pcmcia_device *p_dev)
        init_waitqueue_head(&dev->atrq);
        init_waitqueue_head(&dev->readq);
 
-       link->handle = p_dev;
-       p_dev->instance = link;
-
        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
        cm4000_config(link, i);
 
+       class_device_create(cmm_class, NULL, MKDEV(major, i), NULL,
+                           "cmm%d", i);
+
        return 0;
 }
 
@@ -1962,6 +1947,8 @@ static void cm4000_detach(struct pcmcia_device *p_dev)
        dev_table[devno] = NULL;
        kfree(dev);
 
+       class_device_destroy(cmm_class, MKDEV(major, devno));
+
        return;
 }
 
@@ -1995,8 +1982,18 @@ static struct pcmcia_driver cm4000_driver = {
 
 static int __init cmm_init(void)
 {
+       int rc;
+
        printk(KERN_INFO "%s\n", version);
-       pcmcia_register_driver(&cm4000_driver);
+
+       cmm_class = class_create(THIS_MODULE, "cardman_4000");
+       if (!cmm_class)
+               return -1;
+
+       rc = pcmcia_register_driver(&cm4000_driver);
+       if (rc < 0)
+               return rc;
+
        major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
        if (major < 0) {
                printk(KERN_WARNING MODULE_NAME
@@ -2012,6 +2009,7 @@ static void __exit cmm_exit(void)
        printk(KERN_INFO MODULE_NAME ": unloading\n");
        pcmcia_unregister_driver(&cm4000_driver);
        unregister_chrdev(major, DEVICE_NAME);
+       class_destroy(cmm_class);
 };
 
 module_init(cmm_init);