Commit 7f97c000 authored by Maciej Szmigiero's avatar Maciej Szmigiero Committed by Greg Kroah-Hartman

serial: fix serial_cs I/O windows for Argosy RS-COM 2P

Current serial_cs driver has a problem when trying to detect whether
a card has multiple ports: serial_config() calls pcmcia_loop_config()
which iterates over card CIS configurations by calling
serial_check_for_multi() for each of them.

This function wants to check (and select) a configuration
that has either one long I/O window spanning multiple ports or two 8-port
windows for two serial ports.

Problem is, that every pcmcia_loop_config() iteration only updates
the windows (via pcmcia_do_loop_config() in resource[0] and resource[1])
when CONF_AUTO_SET_IO flag is set on the device, which is set only later
in the code.

Fix it by setting this flag earlier.

In addition to this, when multi-port card is detected
and it does not have an one, long I/O window
multi_config_check_notpicky() tries to locate two I/O windows and assumes
they are continuous without checking.

On an Argosy RS-COM 2P this selects first configuration, which
unfortunately has two non-continuous I/O windows.
The net effect is that the second serial port on the card does not work.

Fix it by checking whether the windows are really continuous.
Signed-off-by: default avatarMaciej Szmigiero <mhej@o2.pl>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7d73aaf1
...@@ -317,7 +317,7 @@ static int serial_probe(struct pcmcia_device *link) ...@@ -317,7 +317,7 @@ static int serial_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->config_flags |= CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
if (do_sound) if (do_sound)
link->config_flags |= CONF_ENABLE_SPKR; link->config_flags |= CONF_ENABLE_SPKR;
...@@ -445,7 +445,7 @@ static int simple_config(struct pcmcia_device *link) ...@@ -445,7 +445,7 @@ static int simple_config(struct pcmcia_device *link)
/* First pass: look for a config entry that looks normal. /* First pass: look for a config entry that looks normal.
* Two tries: without IO aliases, then with aliases */ * Two tries: without IO aliases, then with aliases */
link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_SET_IO; link->config_flags |= CONF_AUTO_SET_VPP;
for (try = 0; try < 4; try++) for (try = 0; try < 4; try++)
if (!pcmcia_loop_config(link, simple_config_check, &try)) if (!pcmcia_loop_config(link, simple_config_check, &try))
goto found_port; goto found_port;
...@@ -501,7 +501,8 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev, ...@@ -501,7 +501,8 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
{ {
int *base2 = priv_data; int *base2 = priv_data;
if (!p_dev->resource[0]->end || !p_dev->resource[1]->end) if (!p_dev->resource[0]->end || !p_dev->resource[1]->end ||
p_dev->resource[0]->start + 8 != p_dev->resource[1]->start)
return -ENODEV; return -ENODEV;
p_dev->resource[0]->end = p_dev->resource[1]->end = 8; p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
...@@ -520,7 +521,6 @@ static int multi_config(struct pcmcia_device *link) ...@@ -520,7 +521,6 @@ static int multi_config(struct pcmcia_device *link)
struct serial_info *info = link->priv; struct serial_info *info = link->priv;
int i, base2 = 0; int i, base2 = 0;
link->config_flags |= CONF_AUTO_SET_IO;
/* First, look for a generic full-sized window */ /* First, look for a generic full-sized window */
if (!pcmcia_loop_config(link, multi_config_check, &info->multi)) if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
base2 = link->resource[0]->start + 8; base2 = link->resource[0]->start + 8;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment