David Ford wrote: > > > 10. To Do But Non Showstopper > > * PCMCIA/Cardbus hangs (Basically unusable - Hinds pcmcia code is > > reliable) > > + PCMCIA crashes on unloading pci_socket > > With test8, pcmcia either with kernel code, mixed, or dhinds code; nothing is > usable. David, I'll take a stab at this while my PCMCIA memories are fresh. Can you please try the attached patch and, when it doesn't work, send me all the usual details?
--- linux-2.4.0-test8/include/pcmcia/ss.h Sat Sep 9 16:19:30 2000 +++ linux-akpm/include/pcmcia/ss.h Wed Sep 13 00:13:06 2000 @@ -82,6 +82,7 @@ #define SS_DMA_MODE 0x0080 #define SS_SPKR_ENA 0x0100 #define SS_OUTPUT_ENA 0x0200 +#define SS_DEBOUNCED 0x0400 /* Tell driver that the debounce delay has ended */ /* Flags for I/O port and memory windows */ #define MAP_ACTIVE 0x01 --- linux-2.4.0-test8/drivers/pcmcia/cardbus.c Sat Sep 9 16:19:26 2000 +++ linux-akpm/drivers/pcmcia/cardbus.c Wed Sep 13 00:13:06 2000 @@ -58,11 +58,6 @@ #include <asm/irq.h> #include <asm/io.h> -#ifndef PCMCIA_DEBUG -#define PCMCIA_DEBUG 1 -#endif -static int pc_debug = PCMCIA_DEBUG; - #define IN_CARD_SERVICES #include <pcmcia/version.h> #include <pcmcia/cs_types.h> @@ -72,6 +67,11 @@ #include <pcmcia/cistpl.h> #include "cs_internal.h" #include "rsrc_mgr.h" + +#ifndef PCMCIA_DEBUG +#define PCMCIA_DEBUG 1 +#endif +static int pc_debug = PCMCIA_DEBUG; /*====================================================================*/ --- linux-2.4.0-test8/drivers/pcmcia/cs.c Sat Sep 9 16:19:26 2000 +++ linux-akpm/drivers/pcmcia/cs.c Wed Sep 13 00:13:06 2000 @@ -103,13 +103,13 @@ #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") -INT_MODULE_PARM(setup_delay, HZ/20); /* ticks */ -INT_MODULE_PARM(resume_delay, HZ/5); /* ticks */ -INT_MODULE_PARM(shutdown_delay, HZ/40); /* ticks */ -INT_MODULE_PARM(vcc_settle, 400); /* msecs */ +INT_MODULE_PARM(setup_delay, 10); /* centiseconds */ +INT_MODULE_PARM(resume_delay, 20); /* centiseconds */ +INT_MODULE_PARM(shutdown_delay, 3); /* centiseconds */ +INT_MODULE_PARM(vcc_settle, 40); /* centiseconds */ INT_MODULE_PARM(reset_time, 10); /* usecs */ -INT_MODULE_PARM(unreset_delay, 100); /* msecs */ -INT_MODULE_PARM(unreset_check, 100); /* msecs */ +INT_MODULE_PARM(unreset_delay, 10); /* centiseconds */ +INT_MODULE_PARM(unreset_check, 10); /* centiseconds */ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */ /* Access speed for attribute memory windows */ @@ -446,10 +446,13 @@ static int send_event(socket_info_t *s, event_t event, int priority); -static void msleep(unsigned int msec) +/* + * Sleep for n_cs centiseconds (1 cs = 1/100th of a second) + */ +static void cs_sleep(unsigned int n_cs) { current->state = TASK_INTERRUPTIBLE; - schedule_timeout( (msec * HZ + 999) / 1000); + schedule_timeout( (n_cs * HZ + 99) / 100); } static void shutdown_socket(socket_info_t *s) @@ -504,7 +507,7 @@ if (!(val & SS_PENDING)) break; if (--setup_timeout) { - msleep(100); + cs_sleep(10); continue; } printk(KERN_NOTICE "cs: socket %p voltage interrogation" @@ -516,7 +519,7 @@ if (val & SS_DETECT) { DEBUG(1, "cs: setup_socket(%p): applying power\n", s); s->state |= SOCKET_PRESENT; - s->socket.flags = 0; + s->socket.flags &= SS_DEBOUNCED; if (val & SS_3VCARD) s->socket.Vcc = s->socket.Vpp = 33; else if (!(val & SS_XVCARD)) @@ -533,7 +536,7 @@ #endif } set_socket(s, &s->socket); - msleep(vcc_settle); + cs_sleep(vcc_settle); reset_socket(s); ret = 1; } else { @@ -561,7 +564,7 @@ udelay((long)reset_time); s->socket.flags &= ~SS_RESET; set_socket(s, &s->socket); - msleep(unreset_delay); + cs_sleep(unreset_delay); unreset_socket(s); } /* reset_socket */ @@ -580,11 +583,11 @@ break; DEBUG(2, "cs: socket %d not ready yet\n", s->sock); if (--setup_timeout) { - msleep(unreset_check); + cs_sleep(unreset_check); continue; } printk(KERN_NOTICE "cs: socket %p timed out during" - " reset\n", s); + " reset. Try increasing setup_delay.\n", s); s->state &= ~EVENT_MASK; return; } @@ -656,7 +659,7 @@ DEBUG(0, "cs: flushing pending setup\n"); s->state &= ~EVENT_MASK; } - msleep(shutdown_delay); + cs_sleep(shutdown_delay); s->state &= ~SOCKET_PRESENT; shutdown_socket(s); } @@ -679,11 +682,13 @@ } s->state |= SOCKET_SETUP_PENDING; if (s->state & SOCKET_SUSPEND) - msleep(resume_delay); + cs_sleep(resume_delay); else - msleep(setup_delay); + cs_sleep(setup_delay); + s->socket.flags |= SS_DEBOUNCED; if (setup_socket(s) == 0) s->state &= ~SOCKET_SETUP_PENDING; + s->socket.flags &= ~SS_DEBOUNCED; } } if (events & SS_BATDEAD) --- linux-2.4.0-test8/drivers/pcmcia/yenta.c Sat Sep 9 16:19:26 2000 +++ linux-akpm/drivers/pcmcia/yenta.c Wed Sep 13 00:13:06 2000 @@ -233,6 +233,11 @@ { u16 bridge; + if (state->flags & SS_DEBOUNCED) { + /* The insertion debounce period has ended. Clear any pending +insertion events */ + socket->events &= ~SS_DETECT; + state->flags &= ~SS_DEBOUNCED; /* SS_DEBOUNCED is oneshot */ + } yenta_set_power(socket, state); socket->io_irq = state->io_irq; bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);