Possible fix for "exclude"
Pete Zaitcev
zaitcev at redhat.com
Wed Mar 30 19:03:33 EST 2005
Hi, Guys:
One of our users has a strangely broken laptop, where a read from its
SoundBlaster emulator breaks something, and thereafter the sound does
not work right (either not at all, or is very choppy).
A natural suggestion was to add "exclude 0x220-0x22f" to pcmcia.opts,
but this does not actually work. A region is scanned after it was
defined. If "include" statement is first and covers a port range,
it is scanned even if it is excluded further down the file.
This is a Red Hat bug 53293.
The fix was included into David Hinds' codebase (which included kernel
modules), but not into Marcelo's tree.
I looked at the way 2.6 does things, and it seems to me that a similar
fix might be in order. Patch is attached. Is anyone willing to have a look
and share an opinion about it? Does it make sense?
Thank you,
-- Pete
diff -urp -X dontdiff linux-2.6.12-rc1-mm3/drivers/pcmcia/rsrc_nonstatic.c linux-2.6.12-rc1-mm3-pp/drivers/pcmcia/rsrc_nonstatic.c
--- linux-2.6.12-rc1-mm3/drivers/pcmcia/rsrc_nonstatic.c 2005-03-30 14:11:37.000000000 -0800
+++ linux-2.6.12-rc1-mm3-pp/drivers/pcmcia/rsrc_nonstatic.c 2005-03-30 15:46:36.000000000 -0800
@@ -64,6 +64,7 @@ struct socket_data {
static DECLARE_MUTEX(rsrc_sem);
#define MEM_PROBE_LOW (1 << 0)
#define MEM_PROBE_HIGH (1 << 1)
+#define IO_PROBE (1 << 2)
/*======================================================================
@@ -253,7 +254,32 @@ static void do_io_probe(struct pcmcia_so
printk(any ? "\n" : " clean.\n");
}
-#endif
+
+static void invalidate_io(struct pcmcia_socket *s)
+{
+ struct socket_data *s_data = s->resource_data;
+ s_data->rsrc_mem_probe &= ~IO_PROBE;
+}
+
+static void validate_io(struct pcmcia_socket *s)
+{
+ struct socket_data *s_data = s->resource_data;
+ struct resource_map *m;
+
+ if (!probe_io || (s_data->rsrc_mem_probe & IO_PROBE) != 0)
+ return;
+ s_data->rsrc_mem_probe |= IO_PROBE;
+ /* down(&rsrc_sem); */ /* Already taken? */
+ for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next)
+ do_io_probe(s, m->base, m->num);
+ /* up(&rsrc_sem); */
+}
+
+#else /* CONFIG_PCMCIA_PROBE */
+
+#define validate_io(s) do { } while (0)
+#define invalidate_io(s) do { } while (0)
+#endif /* CONFIG_PCMCIA_PROBE */
/*======================================================================
@@ -610,6 +636,8 @@ static struct resource *nonstatic_find_i
unsigned long min = base;
int ret;
+ validate_io(s);
+
if (align == 0)
align = 0x10000;
@@ -735,13 +763,10 @@ static int adjust_io(struct pcmcia_socke
ret = -EBUSY;
break;
}
-#ifdef CONFIG_PCMCIA_PROBE
- if (probe_io)
- do_io_probe(s, start, size);
-#endif
break;
case REMOVE_MANAGED_RESOURCE:
sub_interval(&data->io_db, start, size);
+ invalidate_io(s);
break;
default:
ret = -EINVAL;
More information about the linux-pcmcia
mailing list