pcmcia: remove obsolete and wrong comments
[pandora-kernel.git] / drivers / serial / serial_cs.c
index 141c695..649ce54 100644 (file)
@@ -45,7 +45,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
 #include <pcmcia/ds.h>
@@ -183,10 +182,8 @@ static void quirk_config_socket(struct pcmcia_device *link)
 {
        struct serial_info *info = link->priv;
 
-       if (info->multi) {
-               link->conf.Present |= PRESENT_EXT_STATUS;
-               link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
-       }
+       if (info->multi)
+               link->config_flags |= CONF_ENABLE_ESR;
 }
 
 static const struct serial_quirk quirks[] = {
@@ -265,13 +262,6 @@ static const struct serial_quirk quirks[] = {
 static int serial_config(struct pcmcia_device * link);
 
 
-/*======================================================================
-
-    After a card is removed, serial_remove() will unregister
-    the serial device(s), and release the PCMCIA configuration.
-    
-======================================================================*/
-
 static void serial_remove(struct pcmcia_device *link)
 {
        struct serial_info *info = link->priv;
@@ -314,14 +304,6 @@ static int serial_resume(struct pcmcia_device *link)
        return 0;
 }
 
-/*======================================================================
-
-    serial_attach() creates an "instance" of the driver, allocating
-    local data structures for one device.  The device is registered
-    with Card Services.
-
-======================================================================*/
-
 static int serial_probe(struct pcmcia_device *link)
 {
        struct serial_info *info;
@@ -335,27 +317,13 @@ static int serial_probe(struct pcmcia_device *link)
        info->p_dev = link;
        link->priv = info;
 
-       link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-       link->resource[0]->end = 8;
-       link->conf.Attributes = CONF_ENABLE_IRQ;
-       if (do_sound) {
-               link->conf.Attributes |= CONF_ENABLE_SPKR;
-               link->conf.Status = CCSR_AUDIO_ENA;
-       }
-       link->conf.IntType = INT_MEMORY_AND_IO;
+       link->config_flags |= CONF_ENABLE_IRQ;
+       if (do_sound)
+               link->config_flags |= CONF_ENABLE_SPKR;
 
        return serial_config(link);
 }
 
-/*======================================================================
-
-    This deletes a driver "instance".  The device is de-registered
-    with Card Services.  If it has been released, all local data
-    structures are freed.  Otherwise, the structures will be freed
-    when the device is released.
-
-======================================================================*/
-
 static void serial_detach(struct pcmcia_device *link)
 {
        struct serial_info *info = link->priv;
@@ -411,47 +379,66 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
 
 /*====================================================================*/
 
-static int simple_config_check(struct pcmcia_device *p_dev,
-                              cistpl_cftable_entry_t *cf,
-                              cistpl_cftable_entry_t *dflt,
-                              unsigned int vcc,
-                              void *priv_data)
+static int pfc_config(struct pcmcia_device *p_dev)
+{
+       unsigned int port = 0;
+       struct serial_info *info = p_dev->priv;
+
+       if ((p_dev->resource[1]->end != 0) &&
+               (resource_size(p_dev->resource[1]) == 8)) {
+               port = p_dev->resource[1]->start;
+               info->slave = 1;
+       } else if ((info->manfid == MANFID_OSITECH) &&
+               (resource_size(p_dev->resource[0]) == 0x40)) {
+               port = p_dev->resource[0]->start + 0x28;
+               info->slave = 1;
+       }
+       if (info->slave)
+               return setup_serial(p_dev, info, port, p_dev->irq);
+
+       dev_warn(&p_dev->dev, "no usable port range found, giving up\n");
+       return -ENODEV;
+}
+
+static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data)
 {
        static const int size_table[2] = { 8, 16 };
        int *try = priv_data;
 
-       if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-               p_dev->conf.Vpp =
-                       cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       if (p_dev->resource[0]->start == 0)
+               return -ENODEV;
 
-       p_dev->io_lines = ((*try & 0x1) == 0) ?
-                       16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+       if ((*try & 0x1) == 0)
+               p_dev->io_lines = 16;
 
-       if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)])
-           && (cf->io.win[0].base != 0)) {
-               p_dev->resource[0]->start = cf->io.win[0].base;
-               if (!pcmcia_request_io(p_dev))
-                       return 0;
-       }
-       return -EINVAL;
+       if (p_dev->resource[0]->end != size_table[(*try >> 1)])
+               return -ENODEV;
+
+       p_dev->resource[0]->end = 8;
+       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+
+       return pcmcia_request_io(p_dev);
 }
 
 static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
-                                       cistpl_cftable_entry_t *cf,
-                                       cistpl_cftable_entry_t *dflt,
-                                       unsigned int vcc,
                                        void *priv_data)
 {
        static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
        int j;
 
-       if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-               for (j = 0; j < 5; j++) {
-                       p_dev->resource[0]->start = base[j];
-                       p_dev->io_lines = base[j] ? 16 : 3;
-                       if (!pcmcia_request_io(p_dev))
-                               return 0;
-               }
+       if (p_dev->io_lines > 3)
+               return -ENODEV;
+
+       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       p_dev->resource[0]->end = 8;
+
+       for (j = 0; j < 5; j++) {
+               p_dev->resource[0]->start = base[j];
+               p_dev->io_lines = base[j] ? 16 : 3;
+               if (!pcmcia_request_io(p_dev))
+                       return 0;
        }
        return -ENODEV;
 }
@@ -461,26 +448,9 @@ static int simple_config(struct pcmcia_device *link)
        struct serial_info *info = link->priv;
        int i = -ENODEV, try;
 
-       /* If the card is already configured, look up the port and irq */
-       if (link->function_config) {
-               unsigned int port = 0;
-               if ((link->resource[1]->end != 0) &&
-                       (resource_size(link->resource[1]) == 8)) {
-                       port = link->resource[1]->end;
-                       info->slave = 1;
-               } else if ((info->manfid == MANFID_OSITECH) &&
-                       (resource_size(link->resource[0]) == 0x40)) {
-                       port = link->resource[0]->start + 0x28;
-                       info->slave = 1;
-               }
-               if (info->slave) {
-                       return setup_serial(link, info, port,
-                                           link->irq);
-               }
-       }
-
        /* First pass: look for a config entry that looks normal.
         * Two tries: without IO aliases, then with aliases */
+       link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_SET_IO;
        for (try = 0; try < 4; try++)
                if (!pcmcia_loop_config(link, simple_config_check, &try))
                        goto found_port;
@@ -491,13 +461,12 @@ static int simple_config(struct pcmcia_device *link)
        if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
                goto found_port;
 
-       printk(KERN_NOTICE
-              "serial_cs: no usable port range found, giving up\n");
+       dev_warn(&link->dev, "no usable port range found, giving up\n");
        return -1;
 
 found_port:
        if (info->multi && (info->manfid == MANFID_3COM))
-               link->conf.ConfigIndex &= ~(0x08);
+               link->config_index &= ~(0x08);
 
        /*
         * Apply any configuration quirks.
@@ -505,51 +474,50 @@ found_port:
        if (info->quirk && info->quirk->config)
                info->quirk->config(link);
 
-       i = pcmcia_request_configuration(link, &link->conf);
+       i = pcmcia_enable_device(link);
        if (i != 0)
                return -1;
        return setup_serial(link, info, link->resource[0]->start, link->irq);
 }
 
-static int multi_config_check(struct pcmcia_device *p_dev,
-                             cistpl_cftable_entry_t *cf,
-                             cistpl_cftable_entry_t *dflt,
-                             unsigned int vcc,
-                             void *priv_data)
+static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data)
 {
-       int *base2 = priv_data;
+       int *multi = priv_data;
+
+       if (p_dev->resource[1]->end)
+               return -EINVAL;
 
        /* The quad port cards have bad CIS's, so just look for a
           window larger than 8 ports and assume it will be right */
-       if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
-               p_dev->resource[0]->start = cf->io.win[0].base;
-               p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
-               if (!pcmcia_request_io(p_dev)) {
-                       *base2 = p_dev->resource[0]->start + 8;
-                       return 0;
-               }
-       }
-       return -ENODEV;
+       if (p_dev->resource[0]->end <= 8)
+               return -EINVAL;
+
+       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       p_dev->resource[0]->end = *multi * 8;
+
+       if (pcmcia_request_io(p_dev))
+               return -ENODEV;
+       return 0;
 }
 
 static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
-                                      cistpl_cftable_entry_t *cf,
-                                      cistpl_cftable_entry_t *dflt,
-                                      unsigned int vcc,
                                       void *priv_data)
 {
        int *base2 = priv_data;
 
-       if (cf->io.nwin == 2) {
-               p_dev->resource[0]->start = cf->io.win[0].base;
-               p_dev->resource[1]->start = cf->io.win[1].base;
-               p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
-               if (!pcmcia_request_io(p_dev)) {
-                       *base2 = p_dev->resource[1]->start;
-                       return 0;
-               }
-       }
-       return -ENODEV;
+       if (!p_dev->resource[0]->end || !p_dev->resource[1]->end)
+               return -ENODEV;
+
+       p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
+       p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+
+       if (pcmcia_request_io(p_dev))
+               return -ENODEV;
+
+       *base2 = p_dev->resource[0]->start + 8;
+       return 0;
 }
 
 static int multi_config(struct pcmcia_device *link)
@@ -557,23 +525,23 @@ static int multi_config(struct pcmcia_device *link)
        struct serial_info *info = link->priv;
        int i, base2 = 0;
 
+       link->config_flags |= CONF_AUTO_SET_IO;
        /* First, look for a generic full-sized window */
-       link->resource[0]->end = info->multi * 8;
-       if (pcmcia_loop_config(link, multi_config_check, &base2)) {
+       if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
+               base2 = link->resource[0]->start + 8;
+       else {
                /* If that didn't work, look for two windows */
-               link->resource[0]->end = link->resource[1]->end = 8;
                info->multi = 2;
                if (pcmcia_loop_config(link, multi_config_check_notpicky,
                                       &base2)) {
-                       printk(KERN_NOTICE "serial_cs: no usable port range"
+                       dev_warn(&link->dev, "no usable port range "
                               "found, giving up\n");
                        return -ENODEV;
                }
        }
 
        if (!link->irq)
-               dev_warn(&link->dev,
-                       "serial_cs: no usable IRQ found, continuing...\n");
+               dev_warn(&link->dev, "no usable IRQ found, continuing...\n");
 
        /*
         * Apply any configuration quirks.
@@ -581,7 +549,7 @@ static int multi_config(struct pcmcia_device *link)
        if (info->quirk && info->quirk->config)
                info->quirk->config(link);
 
-       i = pcmcia_request_configuration(link, &link->conf);
+       i = pcmcia_enable_device(link);
        if (i != 0)
                return -ENODEV;
 
@@ -593,11 +561,11 @@ static int multi_config(struct pcmcia_device *link)
                                info->prodid == PRODID_POSSIO_GCC)) {
                int err;
 
-               if (link->conf.ConfigIndex == 1 ||
-                   link->conf.ConfigIndex == 3) {
+               if (link->config_index == 1 ||
+                   link->config_index == 3) {
                        err = setup_serial(link, info, base2,
                                        link->irq);
-                       base2 = link->resource[0]->start;;
+                       base2 = link->resource[0]->start;
                } else {
                        err = setup_serial(link, info, link->resource[0]->start,
                                        link->irq);
@@ -621,33 +589,24 @@ static int multi_config(struct pcmcia_device *link)
        return 0;
 }
 
-static int serial_check_for_multi(struct pcmcia_device *p_dev,
-                                 cistpl_cftable_entry_t *cf,
-                                 cistpl_cftable_entry_t *dflt,
-                                 unsigned int vcc,
-                                 void *priv_data)
+static int serial_check_for_multi(struct pcmcia_device *p_dev,  void *priv_data)
 {
        struct serial_info *info = p_dev->priv;
 
-       if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
-               info->multi = cf->io.win[0].len >> 3;
+       if (!p_dev->resource[0]->end)
+               return -EINVAL;
+
+       if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0))
+               info->multi = p_dev->resource[0]->end >> 3;
 
-       if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
-               (cf->io.win[1].len == 8))
+       if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8)
+               && (p_dev->resource[1]->end == 8))
                info->multi = 2;
 
        return 0; /* break */
 }
 
 
-/*======================================================================
-
-    serial_config() is scheduled to run after a CARD_INSERTION event
-    is received, to configure the PCMCIA socket, and to make the
-    serial device available to the system.
-
-======================================================================*/
-
 static int serial_config(struct pcmcia_device * link)
 {
        struct serial_info *info = link->priv;
@@ -675,6 +634,7 @@ static int serial_config(struct pcmcia_device * link)
           multifunction cards that ask for appropriate IO port ranges */
        if ((info->multi == 0) &&
            (link->has_func_id) &&
+           (link->socket->pcmcia_pfc == 0) &&
            ((link->func_id == CISTPL_FUNCID_MULTI) ||
             (link->func_id == CISTPL_FUNCID_SERIAL)))
                pcmcia_loop_config(link, serial_check_for_multi, info);
@@ -685,7 +645,13 @@ static int serial_config(struct pcmcia_device * link)
        if (info->quirk && info->quirk->multi != -1)
                info->multi = info->quirk->multi;
 
-       if (info->multi > 1)
+       dev_info(&link->dev,
+               "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n",
+               link->manf_id, link->card_id,
+               link->socket->pcmcia_pfc, info->multi, info->quirk);
+       if (link->socket->pcmcia_pfc)
+               i = pfc_config(link);
+       else if (info->multi > 1)
                i = multi_config(link);
        else
                i = simple_config(link);
@@ -704,7 +670,7 @@ static int serial_config(struct pcmcia_device * link)
        return 0;
 
 failed:
-       dev_warn(&link->dev, "serial_cs: failed to initialize\n");
+       dev_warn(&link->dev, "failed to initialize\n");
        serial_remove(link);
        return -ENODEV;
 }
@@ -884,9 +850,7 @@ MODULE_FIRMWARE("cis/RS-COM-2P.cis");
 
 static struct pcmcia_driver serial_cs_driver = {
        .owner          = THIS_MODULE,
-       .drv            = {
-               .name   = "serial_cs",
-       },
+       .name           = "serial_cs",
        .probe          = serial_probe,
        .remove         = serial_detach,
        .id_table       = serial_ids,