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