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: Maciej Szmigiero <mhej@o2.pl> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
7d73aaf1d4
commit
7f97c000e8
|
@ -317,7 +317,7 @@ static int serial_probe(struct pcmcia_device *link)
|
|||
info->p_dev = link;
|
||||
link->priv = info;
|
||||
|
||||
link->config_flags |= CONF_ENABLE_IRQ;
|
||||
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
|
||||
if (do_sound)
|
||||
link->config_flags |= CONF_ENABLE_SPKR;
|
||||
|
||||
|
@ -445,7 +445,7 @@ static int simple_config(struct pcmcia_device *link)
|
|||
|
||||
/* 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;
|
||||
link->config_flags |= CONF_AUTO_SET_VPP;
|
||||
for (try = 0; try < 4; try++)
|
||||
if (!pcmcia_loop_config(link, simple_config_check, &try))
|
||||
goto found_port;
|
||||
|
@ -501,7 +501,8 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
|
|||
{
|
||||
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;
|
||||
|
||||
p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
|
||||
|
@ -520,7 +521,6 @@ 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 */
|
||||
if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
|
||||
base2 = link->resource[0]->start + 8;
|
||||
|
|
Loading…
Reference in New Issue