pcmcia: introduce autoconfiguration feature
[linux-2.6.git] / drivers / char / pcmcia / synclink_cs.c
index 77b3648..c701434 100644 (file)
@@ -70,8 +70,6 @@
 #include <linux/workqueue.h>
 #include <linux/hdlc.h>
 
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
@@ -220,7 +218,6 @@ typedef struct _mgslpc_info {
 
        /* PCMCIA support */
        struct pcmcia_device    *p_dev;
-       dev_node_t            node;
        int                   stop;
 
        /* SPPP/Cisco HDLC device parts */
@@ -552,14 +549,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
 
     /* Initialize the struct pcmcia_device structure */
 
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1   = IRQ_LEVEL_ID;
-    link->irq.Handler = NULL;
-
-    link->conf.Attributes = 0;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-
     ret = mgslpc_config(link);
     if (ret)
            return ret;
@@ -572,90 +561,57 @@ static int mgslpc_probe(struct pcmcia_device *link)
 /* Card has been inserted.
  */
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
+                         cistpl_cftable_entry_t *cfg,
+                         cistpl_cftable_entry_t *dflt,
+                         void *priv_data)
+{
+       if (!cfg->io.nwin)
+               return -ENODEV;
+
+       p_dev->resource[0]->start = cfg->io.win[0].base;
+       p_dev->resource[0]->end = cfg->io.win[0].len;
+       p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
+       p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+
+       return pcmcia_request_io(p_dev);
+}
 
 static int mgslpc_config(struct pcmcia_device *link)
 {
     MGSLPC_INFO *info = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
-    int last_fn, last_ret;
-    u_char buf[64];
-    cistpl_cftable_entry_t dflt = { 0 };
-    cistpl_cftable_entry_t *cfg;
+    int ret;
 
     if (debug_level >= DEBUG_LEVEL_INFO)
            printk("mgslpc_config(0x%p)\n", link);
 
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.TupleOffset = 0;
-
-    /* get CIS configuration entry */
-
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-
-    cfg = &(parse.cftable_entry);
-    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-    CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
-
-    if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
-    if (cfg->index == 0)
-           goto cs_failed;
-
-    link->conf.ConfigIndex = cfg->index;
-    link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-    /* IO window settings */
-    link->io.NumPorts1 = 0;
-    if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-           cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-           link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-           if (!(io->flags & CISTPL_IO_8BIT))
-                   link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-           if (!(io->flags & CISTPL_IO_16BIT))
-                   link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-           link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-           link->io.BasePort1 = io->win[0].base;
-           link->io.NumPorts1 = io->win[0].len;
-           CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
-    }
+    ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
+    if (ret != 0)
+           goto failed;
 
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.ConfigIndex = 8;
-    link->conf.Present = PRESENT_OPTION;
-
-    link->irq.Attributes |= IRQ_HANDLE_PRESENT;
-    link->irq.Handler     = mgslpc_isr;
-    link->irq.Instance    = info;
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
-
-    info->io_base = link->io.BasePort1;
-    info->irq_level = link->irq.AssignedIRQ;
-
-    /* add to linked list of devices */
-    sprintf(info->node.dev_name, "mgslpc0");
-    info->node.major = info->node.minor = 0;
-    link->dev_node = &info->node;
-
-    printk(KERN_INFO "%s: index 0x%02x:",
-          info->node.dev_name, link->conf.ConfigIndex);
-    if (link->conf.Attributes & CONF_ENABLE_IRQ)
-           printk(", irq %d", link->irq.AssignedIRQ);
-    if (link->io.NumPorts1)
-           printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                  link->io.BasePort1+link->io.NumPorts1-1);
+    link->config_flags |= CONF_ENABLE_IRQ;
+    link->config_index = 8;
+    link->config_regs = PRESENT_OPTION;
+
+    ret = pcmcia_request_irq(link, mgslpc_isr);
+    if (ret)
+           goto failed;
+    ret = pcmcia_enable_device(link);
+    if (ret)
+           goto failed;
+
+    info->io_base = link->resource[0]->start;
+    info->irq_level = link->irq;
+
+    dev_info(&link->dev, "index 0x%02x:",
+           link->config_index);
+    printk(", irq %d", link->irq);
+    if (link->resource[0])
+           printk(", io %pR", link->resource[0]);
     printk("\n");
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
+failed:
     mgslpc_release((u_long)link);
     return -ENODEV;
 }
@@ -4005,10 +3961,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
  *
  * skb  socket buffer containing HDLC frame
  * dev  pointer to network device structure
- *
- * returns 0 if success, otherwise error code
  */
-static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
+                                     struct net_device *dev)
 {
        MGSLPC_INFO *info = dev_to_port(dev);
        unsigned long flags;
@@ -4043,7 +3998,7 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        spin_unlock_irqrestore(&info->lock,flags);
 
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 /**