Skip to contentSkip to conversation

pcmcia event thread. (fwd)

PATCH In review David Woodhouse 13 participants 52 messages Nov 13, 2000 – Nov 19, 2000

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 pcmcia event thread. (fwd)

Argh. I give up - I've added a rewrite rule to my MTA because I'm too stupid to remember that the list moved.

--
dwmw2

------- Forwarded Message

From: David Woodhouse <[email protected]>
To: [email protected], [email protected]
Cc: [email protected]
Subject: [PATCH] pcmcia event thread.
Date: Mon, 13 Nov 2000 12:27:13 +0000

I'm not sure why we changed from the existing state machine / timer setup to sleeping in the PCMCIA parse_events() routine, but as parse_events() was often called from interrupt handlers, this has had the effect that a number of socket drivers now start their own kernel thread to submit events instead of doing from the interrupt handler.

Driver authors being, well, driver authors, this is generally going to be done badly, aside from the fact that it's needless duplication of code.

Therefore, I propose the that the core PCMCIA code should start its own kernel thread, so socket drivers can use the pcmcia_queue_task() function to queue a task to be executed in process context.

Much like this...

Index: drivers/pcmcia/cs.c
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/cs.c,v retrieving revision 1.1.2.28

pcmcia/cs.c +57 -0
diff -u -r1.1.2.28 cs.c
@@ -2333,6 +2333,62 @@
 
 /*======================================================================
 
+    Kernel thread for submitting events on behalf of interrupt handlers
+    
+======================================================================*/
+static int event_thread_leaving = 0;
+static DECLARE_TASK_QUEUE(tq_pcmcia);
+static DECLARE_WAIT_QUEUE_HEAD(event_thread_wq);
+static DECLARE_MUTEX_LOCKED(event_thread_exit_sem);
+
+static int pcmcia_event_thread(void * dummy)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	current->session = 1;
+        current->pgrp = 1;
+        strcpy(current->comm, "kpcmciad");
+        current->tty = NULL;
+        spin_lock_irq(&current->sigmask_lock);
+        sigfillset(&current->blocked);
+        recalc_sigpending(current);
+        spin_unlock_irq(&current->sigmask_lock);
+        exit_mm(current);
+        exit_files(current);
+        exit_sighand(current);
+        exit_fs(current);
+
+	while(!event_thread_leaving) {
+		void *active;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&event_thread_wq, &wait);
+
+		/* Don't really need locking. But the implied mb() */
+		spin_lock(&tqueue_lock);
+		active = tq_pcmcia;
+		spin_unlock(&tqueue_lock);
+
+		if (!active)
+			schedule();
+
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&event_thread_wq, &wait);
+
+		run_task_queue(&tq_pcmcia);
+	}
+	/* Need up_and_exit() */
+	up(&event_thread_exit_sem);
+	return 0;
+}
+
+void pcmcia_queue_task(struct tq_struct *task)
+{
+	queue_task(task, &tq_pcmcia);
+	wake_up(&event_thread_wq);
+}
+
+/*======================================================================
+
     OS-specific module glue goes here
     

======================================================================*/
@@ -2366,6 +2422,7 @@
EXPORT_SYMBOL(pcmcia_modify_window); EXPORT_SYMBOL(pcmcia_open_memory); EXPORT_SYMBOL(pcmcia_parse_tuple);
+EXPORT_SYMBOL(pcmcia_queue_task);
EXPORT_SYMBOL(pcmcia_read_memory); EXPORT_SYMBOL(pcmcia_register_client); EXPORT_SYMBOL(pcmcia_register_erase_queue);
@@ -2411,6 +2468,9 @@

 #ifdef CONFIG_PROC_FS
     proc_pccard = proc_mkdir("pccard", proc_bus);
 #endif
+    /* Start the thread for handling queued events for socket drivers */
+    kernel_thread (pcmcia_event_thread, NULL,
+		   CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
     return 0;

}

@@ -2424,6 +2484,14 @@

 #endif
     if (do_apm)
 	pm_unregister_all(handle_pm_event);
+
+    /* Tell the event thread to die */
+    event_thread_leaving = 1;
+    wake_up(&event_thread_wq);

+
+ /* Wait for it... */
+ down(&event_thread_exit_sem);
+

     release_resource_db();

}

Index: include/pcmcia/cs.h
===================================================================
RCS file: /inst/cvs/linux/include/pcmcia/Attic/cs.h,v retrieving revision 1.1.2.8

pcmcia/cs.h +1 -0
diff -u -r1.1.2.8 cs.h
@@ -443,6 +443,7 @@
 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
 int pcmcia_modify_configuration(client_handle_t handle, modconf_t *mod);
 int pcmcia_modify_window(window_handle_t win, modwin_t *req);
+void pcmcia_queue_task(struct tq_struct *task);
 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
 int pcmcia_release_configuration(client_handle_t handle);
 int pcmcia_release_io(client_handle_t handle, io_req_t *req);

--
dwmw2

------- End of Forwarded Message

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#1 lore raw
Quoted 2 lines · David Woodhouse

I'm not sure why we changed from the existing state machine / timer setup to sleeping in the PCMCIA parse_events() routine,

I don't remember the exact reason, but Linus changed it for yenta... maybe because CardBus Watcher always called the state machine from user context...

Quoted 6 lines
pcmcia/cs.c +6 -0
+static int pcmcia_event_thread(void * dummy)
+{
+       DECLARE_WAITQUEUE(wait, current);
+
+       current->session = 1;
+        current->pgrp = 1;

pcmcia/cs.c line 2359

Quoted 10 lines
pcmcia/cs.c +10 -0
+        strcpy(current->comm, "kpcmciad");
+        current->tty = NULL;
+        spin_lock_irq(&current->sigmask_lock);
+        sigfillset(&current->blocked);
+        recalc_sigpending(current);
+        spin_unlock_irq(&current->sigmask_lock);
+        exit_mm(current);
+        exit_files(current);
+        exit_sighand(current);
+        exit_fs(current);

Replace most if not all of this crap w/ daemonize()

Quoted 10 lines
pcmcia/cs.c +10 -0
+
+       while(!event_thread_leaving) {
+               void *active;
+
+               set_current_state(TASK_INTERRUPTIBLE);
+               add_wait_queue(&event_thread_wq, &wait);
+
+               /* Don't really need locking. But the implied mb() */
+               spin_lock(&tqueue_lock);
+               active = tq_pcmcia;

pcmcia/cs.c line 2379

Quoted 10 lines
pcmcia/cs.c +10 -0
+               spin_unlock(&tqueue_lock);
+
+               if (!active)
+                       schedule();
+
+               set_current_state(TASK_RUNNING);
+               remove_wait_queue(&event_thread_wq, &wait);
+
+               run_task_queue(&tq_pcmcia);
+       }

it looks like the loop can be simplified to

while (1) {
	mb();
	active = tq_pcmcia;
	if (!active)
		interruptible_sleep_on(&event_thread_wq);
	if (signal_pending(current)
		break;
	run_task_queue(&tq_pcmcia);
}

pcmcia/cs.c line 2381

Quoted 2 lines
pcmcia/cs.c +2 -0
+       /* Need up_and_exit() */
+       up(&event_thread_exit_sem);

Racy. Use waitpid() in the thread killer instead. You also need to reap the process, just like in userland...

Review

Quoted 3 lines
(quoted diff) +3 -0
+    /* Start the thread for handling queued events for socket drivers */
+    kernel_thread (pcmcia_event_thread, NULL,
+                  CLONE_FS | CLONE_FILES | CLONE_SIGHAND);

Why are you cloning _FS, _FILES, and _SIGHAND? I don't see why the third arg should not be zero. man clone...

Signature · 7 lines
Jeff Garzik             |
Building 1024           | The chief enemy of creativity is "good" sense
MandrakeSoft            |          -- Picasso
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#2 lore raw
Quoted 1 line · [email protected] said:

Replace most if not all of this crap w/ daemonize()

OK.

Quoted 1 line

it looks like the loop can be simplified to

Nope. sleep_on is bad. We have to set_current_state(TASK_INTERRUPTIBLE) before checking tq_pcmcia.

Quoted 3 lines
while (1) {
	mb();
	active = tq_pcmcia;
        /* EVENT ARRIVES NOW */
Quoted 2 lines
	if (!active)
		interruptible_sleep_on(&event_thread_wq);
	/* WE SLEEP ANYWAY */
Quoted 3 lines
	if (signal_pending(current)
		break;
	run_task_queue(&tq_pcmcia); } 
Quoted 1 line · [email protected] said:

Racy. Use waitpid() in the thread killer instead.

Doesn't waitpid() require the thread we're waiting for to be child of the rmmod process? I suppose we could arrange that, but it's not particularly clean.

I prefer the tiny race and the campaign for up_and_exit() :)

Quoted 1 line

You also need to reap the process, just like in userland...

Gratuitous cruft. Just let init(8) do it.

Quoted 2 lines · [email protected] said:

Why are you cloning _FS, _FILES, and _SIGHAND? I don't see why the third arg should not be zero. man clone...

If we don't specify CLONE_FS | CLONE_FILES | CLONE_SIGHAND then new ones get allocated just for us to free them again immediately. If we clone them, then we just increase and decrease the use counts of the parent's ones. The latter is slightly more efficient, and I don't think it really matters. If you really care, that can be changed. I've dropped CLONE_SIGHAND because daemonize() doesn't free that, but left CLONE_FS and CLONE_FILES.

Revised patch:

Index: drivers/pcmcia/cs.c
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/cs.c,v retrieving revision 1.1.2.28

pcmcia/cs.c +70 -0
diff -u -r1.1.2.28 cs.c
@@ -2333,6 +2333,58 @@
 
 /*======================================================================
 
+    Kernel thread for submitting events on behalf of interrupt handlers
+    
+======================================================================*/
+static int event_thread_leaving = 0;
+static DECLARE_TASK_QUEUE(tq_pcmcia);
+static DECLARE_WAIT_QUEUE_HEAD(event_thread_wq);
+static DECLARE_MUTEX_LOCKED(event_thread_exit_sem);
+static int event_thread_pid;
+
+static int pcmcia_event_thread(void * dummy)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	daemonize();
+        strcpy(current->comm, "kpcmciad");
+        spin_lock_irq(&current->sigmask_lock);
+        sigfillset(&current->blocked);
+        recalc_sigpending(current);
+        spin_unlock_irq(&current->sigmask_lock);
+
+	while(!event_thread_leaving) {
+		void *active;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&event_thread_wq, &wait);
+
+		spin_lock(&tqueue_lock);
+		active = tq_pcmcia;
+		spin_unlock(&tqueue_lock);
+
+		if (!active)
+			schedule();
+
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&event_thread_wq, &wait);
+
+		run_task_queue(&tq_pcmcia);
+	}
+
+	/* Need up_and_exit() */
+	up(&event_thread_exit_sem);
+	return 0;
+}
+
+void pcmcia_queue_task(struct tq_struct *task)
+{
+	queue_task(task, &tq_pcmcia);
+	wake_up(&event_thread_wq);
+}
+
+/*======================================================================
+
     OS-specific module glue goes here
     
 ======================================================================*/
@@ -2366,6 +2418,7 @@
 EXPORT_SYMBOL(pcmcia_modify_window);
 EXPORT_SYMBOL(pcmcia_open_memory);
 EXPORT_SYMBOL(pcmcia_parse_tuple);
+EXPORT_SYMBOL(pcmcia_queue_task);
 EXPORT_SYMBOL(pcmcia_read_memory);
 EXPORT_SYMBOL(pcmcia_register_client);
 EXPORT_SYMBOL(pcmcia_register_erase_queue);
@@ -2406,6 +2459,15 @@
     printk(KERN_INFO "%s\n", release);
     printk(KERN_INFO "  %s\n", options);
     DEBUG(0, "%s\n", version);
+
+    /* Start the thread for handling queued events for socket drivers */
+    event_thread_pid = kernel_thread (pcmcia_event_thread, NULL, CLONE_FS | CLONE_FILES);
+
+    if (event_thread_pid < 0) {
+	    printk(KERN_ERR "init_pcmcia_cs: fork failed: errno %d\n", -event_thread_pid);
+	    return event_thread_pid;
+    }
+
     if (do_apm)
 	pm_register(PM_SYS_DEV, PM_SYS_PCMCIA, handle_pm_event);
 #ifdef CONFIG_PROC_FS
@@ -2417,6 +2479,14 @@
 static void __exit exit_pcmcia_cs(void)
 {
     printk(KERN_INFO "unloading PCMCIA Card Services\n");
+
+    /* Tell the event thread to die */
+    event_thread_leaving = 1;
+    wake_up(&event_thread_wq);
+
+    /* Wait for it... */
+    down(&event_thread_exit_sem);
+
 #ifdef CONFIG_PROC_FS
     if (proc_pccard) {
 	remove_proc_entry("pccard", proc_bus);

Index: include/pcmcia/cs.h
===================================================================
RCS file: /inst/cvs/linux/include/pcmcia/Attic/cs.h,v retrieving revision 1.1.2.8

pcmcia/cs.h +1 -0
diff -u -r1.1.2.8 cs.h
@@ -443,6 +443,7 @@
 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
 int pcmcia_modify_configuration(client_handle_t handle, modconf_t *mod);
 int pcmcia_modify_window(window_handle_t win, modwin_t *req);
+void pcmcia_queue_task(struct tq_struct *task);
 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
 int pcmcia_release_configuration(client_handle_t handle);
 int pcmcia_release_io(client_handle_t handle, io_req_t *req);

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#3 lore raw
Quoted 6 lines · David Woodhouse

If we don't specify CLONE_FS | CLONE_FILES | CLONE_SIGHAND then new ones get allocated just for us to free them again immediately. If we clone them, then we just increase and decrease the use counts of the parent's ones. The latter is slightly more efficient, and I don't think it really matters. If you really care, that can be changed. I've dropped CLONE_SIGHAND because daemonize() doesn't free that, but left CLONE_FS and CLONE_FILES.

Small suggestion - when your thread is created, make sure that all /proc accesses to stuff relating to this thread doesn't cause the kernel to panic.

I used to create some processes with '0' as the third arg until Debian's start-stop-daemon script started killing peoples machines with a kernel oops. Now I always use CLONE_FS | CLONE_FILES | CLONE_SIGHAND as per fs/buffer.c (which I used as the reference for creating kernel threads).
_____

  |_____| ------------------------------------------------- ---+---+-
  |   |         Russell King        [email protected]      --- ---
  | | | | http://www.arm.linux.org.uk/personal/aboutme.html   /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#4 lore raw
In reply to Jeff Garzik
Quoted 6 lines · David Woodhouse
Quoted 1 line · [email protected] said:

Racy. Use waitpid() in the thread killer instead.

Doesn't waitpid() require the thread we're waiting for to be child of the rmmod process? I suppose we could arrange that, but it's not particularly clean.

Doh, totally forgot about that. Will this work:

	save_current = current;
	current = find_task_by_pid(1);
	waitpid(...);
	current = save_current;

In any case, we -really- need a wait_for_kernel_thread_to_die() function.

Quoted 10 lines
Quoted 2 lines · [email protected] said:

Why are you cloning _FS, _FILES, and _SIGHAND? I don't see why the third arg should not be zero. man clone...

If we don't specify CLONE_FS | CLONE_FILES | CLONE_SIGHAND then new ones get allocated just for us to free them again immediately. If we clone them, then we just increase and decrease the use counts of the parent's ones. The latter is slightly more efficient, and I don't think it really matters. If you really care, that can be changed. I've dropped CLONE_SIGHAND because daemonize() doesn't free that, but left CLONE_FS and CLONE_FILES.

Cool tip, thanks.

pcmcia/cs.c line 2355

Quoted 4 lines
pcmcia/cs.c +4 -0
+        spin_lock_irq(&current->sigmask_lock);
+        sigfillset(&current->blocked);
+        recalc_sigpending(current);
+        spin_unlock_irq(&current->sigmask_lock);

what does this do?

Review

Quoted 7 lines
(quoted diff) +7 -0
+    /* Start the thread for handling queued events for socket drivers */
+    event_thread_pid = kernel_thread (pcmcia_event_thread, NULL, CLONE_FS | CLONE_FILES);
+
+    if (event_thread_pid < 0) {
+           printk(KERN_ERR "init_pcmcia_cs: fork failed: errno %d\n", -event_thread_pid);
+           return event_thread_pid;
+    }

why do you store the event_thread_pid but never use it?

regards,

Jeff

Signature · 7 lines
Jeff Garzik             |
Building 1024           | The chief enemy of creativity is "good" sense
MandrakeSoft            |          -- Picasso
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#5 lore raw
Quoted 5 lines · [email protected] said:

Doh, totally forgot about that. Will this work:

	save_current = current;
	current = find_task_by_pid(1);
	waitpid(...);
	current = save_current;

Changing the thread's parent to current->pid would be better than modifying current. Still sucks though....

Quoted 2 lines

In any case, we -really- need a wait_for_kernel_thread_to_die() function.

up_and_exit() would do it. Or preferably passing the address of the semaphore as an extra argument to kernel_thread() in the first place.

In the meantime, enough other places in the kernel have this same race that I'm not too concerned about it. Hopefully, we'll get the extra arg to kernel_thread before the final cut of 2.4, and this code can get converted along with everything else.

Quoted 6 lines

pcmcia/cs.c line 2355

Quoted 4 lines
pcmcia/cs.c +4 -0
+        spin_lock_irq(&current->sigmask_lock);
+        sigfillset(&current->blocked);
+        recalc_sigpending(current);
+        spin_unlock_irq(&current->sigmask_lock);

what does this do?

Well, I _hope_ it blocks all signals, so that we can sleep in TASK_INTERRUPTIBLE without adding 1 to the load average, and without having to worry about the pesky things actually interrupting us.

Quoted 1 line · [email protected] said:

why do you store the event_thread_pid but never use it?

Because I got half way through doing waitpid() before I realised it was sucky. We store it short-term so we can print it. No reason why we can't shift the static declaration into init_pcmcia_cs() though.

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#6 lore raw
In reply to Jeff Garzik
Quoted 6 lines · David Woodhouse
Quoted 2 lines · [email protected] said:

In any case, we -really- need a wait_for_kernel_thread_to_die() function.

up_and_exit() would do it. Or preferably passing the address of the semaphore as an extra argument to kernel_thread() in the first place.

Any solution which involves a function being called from a kernel thread, and/or passing another arg to a kernel thread, is a non-starter ... See the discussion about timer_exit() a while ago. This sort of thing should be done at a higher level. Not only does that eliminate any possibility of a race between thread function calling MOD_DEC_USE_COUNT/up_and_exit and module unload, but it also allows us to more easily implement wait_for_kernel_thread_to_die() without having to do silly stuff like pass extra args to threads (...modifying the thread API in the process).

IMHO it is possible to solve this in a generic way without having to change the code for every single kernel thread.

Thanks for all the explanation, I think I now understand all the stuff your kernel thread is doing. Your solution sounds like a decent solution for the problem described. I have not looked at the socket driver code observe parse_events() usage, so I cannot say whether your problem description is accurate however :)

Jeff

Signature · 7 lines
Jeff Garzik             |
Building 1024           | The chief enemy of creativity is "good" sense
MandrakeSoft            |          -- Picasso
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#7 lore raw
Quoted 5 lines · [email protected] said:

Thanks for all the explanation, I think I now understand all the
stuff your kernel thread is doing. Your solution sounds like a decent solution for the problem described. I have not looked at the socket driver code observe parse_events() usage, so I cannot say whether your problem description is accurate however :)

It's the socket drivers which _aren't_ in the kernel source which are most likely to exhibit this problem. Anything in the kernel tree was probably converted by Linus, and hence done right. As there are so few socket drivers in his tree, the amount of code duplication wasn't immediately obvious either.

The offenders are the multitude of PCMCIA and CF socket drivers for embedded boards which are floating around. They aren't likely to get merged into 2.4, unfortunately - but I think we should at least make this available in order for them to work correctly.

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#8 lore raw
Quoted 3 lines

It's the socket drivers which _aren't_ in the kernel source which are most likely to exhibit this problem. Anything in the kernel tree was probably converted by Linus, and hence done right. As there are so few socket drivers

Umm.. Linus drivers dont appear to be SMP safe on unload

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#9 lore raw
In reply to Jeff Garzik
Quoted 5 lines · David Woodhouse

It's the socket drivers which _aren't_ in the kernel source which are most likely to exhibit this problem. Anything in the kernel tree was probably converted by Linus, and hence done right. As there are so few socket drivers in his tree, the amount of code duplication wasn't immediately obvious either.

The i82365 and tcic drivers in the 2.4 tree have not been converted to use the thread stuff; as far as I know, the yenta driver is the only socket driver that works at all in 2.4.

-- Dave
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#10 lore raw
Quoted 3 lines · David Hinds

The i82365 and tcic drivers in the 2.4 tree have not been converted to use the thread stuff; as far as I know, the yenta driver is the only socket driver that works at all in 2.4.

OK. I take it you support my proposed change?

Can you review this patch for i82365.c?

Index: i82365.c
===================================================================
RCS file: /net/passion/inst/cvs/linux/drivers/pcmcia/Attic/i82365.c,v retrieving revision 1.1.2.14

i82365.c +27 -2
diff -u -r1.1.2.14 i82365.c
@@ -859,6 +859,26 @@
 
 /*====================================================================*/
 
+static u_int pending_events[8] = {0,0,0,0,0,0,0,0};
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static void pcic_bh(void *dummy)
+{
+	u_int events;
+	int i;
+
+	for (i=0; i < sockets; i++) {
+		spin_lock_irq(&pending_event_lock);
+		events = pending_events[i];
+		pending_events[i] = 0;
+		spin_unlock_irq(&pending_event_lock);
+		if (socket[i].handler)
+			socket[i].handler(socket[i].info, events);
+	}
+}
+
+static struct tq_struct pcic_task = {0, 0, &pcic_bh, NULL};
+
 static void pcic_interrupt(int irq, void *dev,
 				    struct pt_regs *regs)
 {
@@ -893,8 +913,13 @@
 	    }
 	    ISA_UNLOCK(i, flags);
 	    DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);
-	    if (events)
-		socket[i].handler(socket[i].info, events);
+
+	    if (events) {
+		    spin_lock(&pending_event_lock);
+		    pending_events[i] |= events;
+		    spin_unlock(&pending_event_lock);
+		    pcmcia_queue_task(&pcic_task);
+	    }
 	    active |= events;
 	}
 	if (!active) break;
Signature · 7 lines
dwmw2


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#12 lore raw
In reply to David Hinds
Quoted 9 lines · David Hinds

The i82365 and tcic drivers in the 2.4 tree have not been converted to use the thread stuff; as far as I know, the yenta driver is the only socket driver that works at all in 2.4.

Quoted 2 lines · David Woodhouse

OK. I take it you support my proposed change?
Can you review this patch for i82365.c?

It looks reasonable and straighforward to me.

Cool. Linus, please could you apply this patch. If the fact that i82365 and tcic are broken in 2.4 isn't on Ted's critical list, then I think it probably ought to have been - and this should fix it.

As before, this causes the PCMCIA core code to start a kernel thread solely for the purpose of running a queue of tasks submitted by random drivers. It also now converts the tcic and i82365 driver to use it, rather than just causing the machine to panic by calling parse_events() from interrupt context.

There's still a small amount of duplicated code, but far less than before, and I think the flexibility of making a task queue available rather than just accepting event submission asynchronously is probably going to be worth it.

Index: include/pcmcia/cs.h
===================================================================
RCS file: /net/passion/inst/cvs/linux/include/pcmcia/Attic/cs.h,v retrieving revision 1.1.2.8

pcmcia/cs.h +1 -0
diff -u -r1.1.2.8 cs.h
@@ -443,6 +443,7 @@
 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
 int pcmcia_modify_configuration(client_handle_t handle, modconf_t *mod);
 int pcmcia_modify_window(window_handle_t win, modwin_t *req);
+void pcmcia_queue_task(struct tq_struct *task);
 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
 int pcmcia_release_configuration(client_handle_t handle);
 int pcmcia_release_io(client_handle_t handle, io_req_t *req);

Index: drivers/pcmcia/cs.c
===================================================================
RCS file: /net/passion/inst/cvs/linux/drivers/pcmcia/Attic/cs.c,v retrieving revision 1.1.2.28

pcmcia/cs.c +73 -0

100 lines not on this page · raw message

Index: drivers/pcmcia/i82365.c
===================================================================
RCS file: /net/passion/inst/cvs/linux/drivers/pcmcia/Attic/i82365.c,v retrieving revision 1.1.2.14

pcmcia/i82365.c +27 -2
diff -u -r1.1.2.14 i82365.c
@@ -859,6 +859,26 @@
 
 /*====================================================================*/
 
+static u_int pending_events[8] = {0,0,0,0,0,0,0,0};
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static void pcic_bh(void *dummy)
+{
+	u_int events;
+	int i;
+
+	for (i=0; i < sockets; i++) {
+		spin_lock_irq(&pending_event_lock);
+		events = pending_events[i];
+		pending_events[i] = 0;
+		spin_unlock_irq(&pending_event_lock);
+		if (socket[i].handler)
+			socket[i].handler(socket[i].info, events);
+	}
+}
+
+static struct tq_struct pcic_task = {0, 0, &pcic_bh, NULL};
+
 static void pcic_interrupt(int irq, void *dev,
 				    struct pt_regs *regs)
 {
@@ -893,8 +913,13 @@
 	    }
 	    ISA_UNLOCK(i, flags);
 	    DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);
-	    if (events)
-		socket[i].handler(socket[i].info, events);
+
+	    if (events) {
+		    spin_lock(&pending_event_lock);
+		    pending_events[i] |= events;
+		    spin_unlock(&pending_event_lock);
+		    pcmcia_queue_task(&pcic_task);
+	    }
 	    active |= events;
 	}
 	if (!active) break;

Index: drivers/pcmcia/tcic.c
===================================================================
RCS file: /net/passion/inst/cvs/linux/drivers/pcmcia/Attic/tcic.c,v retrieving revision 1.1.2.9

pcmcia/tcic.c +26 -2
diff -u -r1.1.2.9 tcic.c
@@ -530,6 +530,26 @@
 
 /*====================================================================*/
 
+static u_int pending_events[2] = {0,0};
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static void tcic_bh(void *dummy)
+{
+	u_int events;
+	int i;
+
+	for (i=0; i < sockets; i++) {
+		spin_lock_irq(&pending_event_lock);
+		events = pending_events[i];
+		pending_events[i] = 0;
+		spin_unlock_irq(&pending_event_lock);
+		if (socket_table[i].handler)
+			socket_table[i].handler(socket_table[i].info, events);
+	}
+}
+
+static struct tq_struct tcic_task = {0, 0, &tcic_bh, NULL};
+
 static void tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
     int i, quick = 0;
@@ -567,9 +587,13 @@
 	    events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
 	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
 	    events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
+	}
+	if (events) {
+		spin_lock(&pending_event_lock);
+		pending_events[i] |= events;
+		spin_unlock(&pending_event_lock);
+		pcmcia_queue_task(&tcic_task);
 	}
-	if (events)
-	    socket_table[i].handler(socket_table[i].info, events);
     }
 
     /* Schedule next poll, if needed */
Signature · 8 lines
dwmw2



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#13 lore raw
Quoted 8 lines · David Woodhouse
Quoted 5 lines · David Hinds

The i82365 and tcic drivers in the 2.4 tree have not been converted to use the thread stuff; as far as I know, the yenta driver is the only socket driver that works at all in 2.4.

On Mon, Nov 13, 2000 at 09:52:30PM +0000, David Woodhouse wrote:

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

OK. I take it you support my proposed change?
Can you review this patch for i82365.c?

It looks reasonable and straighforward to me.

Cool. Linus, please could you apply this patch. If the fact that i82365 and tcic are broken in 2.4 isn't on Ted's critical list, then I think it probably ought to have been - and this should fix it.

It's purposefully not on Ted's critical list, the official line is "use pcmcia_cs external package" if you need i82365 or tcic instead of yenta AFAIK. However... fixing things and being able to support all pcmcia and cardbus adapters would be wonderful.

drivers/pcmcia/Config.in:

Quoted 8 lines

#tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
#if [ "$CONFIG_PCMCIA" != "n" ]; then
# if [ "$CONFIG_PCI" != "n" ]; then
# bool ' CardBus support' CONFIG_CARDBUS

#   fi
#   bool '  i82365 compatible bridge support' CONFIG_I82365
#   bool '  Databook TCIC host bridge support' CONFIG_TCIC

#fi

Signature · 7 lines
Jeff Garzik             |
Building 1024           | The chief enemy of creativity is "good" sense
MandrakeSoft            |          -- Picasso
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#14 lore raw
Quoted 5 lines · Jeff Garzik

It's purposefully not on Ted's critical list, the official line is "use pcmcia_cs external package" if you need i82365 or tcic instead of yenta AFAIK. However... fixing things and being able to support all pcmcia and cardbus adapters would be wonderful.

Quoted 9 lines

drivers/pcmcia/Config.in:

Quoted 8 lines

#tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
#if [ "$CONFIG_PCMCIA" != "n" ]; then
# if [ "$CONFIG_PCI" != "n" ]; then
# bool ' CardBus support' CONFIG_CARDBUS

#   fi
#   bool '  i82365 compatible bridge support' CONFIG_I82365
#   bool '  Databook TCIC host bridge support' CONFIG_TCIC

#fi

Ok, well the patch I've just submitted _ought_ to fix stuff, and certainly works with my own socket drivers for an embedded board I'm working on.

I have an i82365 eval board kicking around somewhere. I'll see if I can dig it out tomorrow and verify that it now works, and then perhaps we can consider re-enabling the config options.

I may add code to handle non-CardBus PCI->PCMCIA i82365 devices again while I'm at it - because I disapprove of having to specify "i365_base=0xc800 cs_irq=17" for a PCI card.

Signature · 8 lines
dwmw2



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#15 lore raw
In reply to Jeff Garzik
Quoted 6 lines

It's purposefully not on Ted's critical list, the official line is "use pcmcia_cs external package" if you need i82365 or tcic instead of yenta AFAIK. However... fixing things and being able to support all pcmcia and cardbus adapters would be wonderful.

From a practical point of view that currently means 'delete Linus tree pcmcia

regardless of what you are doing' since the modules from David Hinds and Linus pcmcia are not 100% binary compatible for all cases.

It isnt possible for anyone to ship a useful system with Linus pcmcia unless the ISA stuff is fixed

Alan

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#16 lore raw
Quoted 2 lines · Alan Cox

the modules from David Hinds and Linus pcmcia are not 100% binary compatible for all cases.

What cases are these?

David's been pretty good about putting 2.4.x support into pcmcia_cs package...

Signature · 7 lines
Jeff Garzik             |
Building 1024           | The chief enemy of creativity is "good" sense
MandrakeSoft            |          -- Picasso
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#17 lore raw
Quoted 6 lines
Quoted 1 line

pcmcia are not 100% binary compatible for all cases.

What cases are these?

David's been pretty good about putting 2.4.x support into pcmcia_cs package...

Build a tree with the kernel pcmcia cs, build the pcmcia modules from David Hinds on the same tree. Attempt to randomly load David's driver modules from yenta and vice versa.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#18 lore raw
In reply to Alan Cox
Quoted 3 lines · Alan Cox
Quoted 1 line

From a practical point of view that currently means 'delete Linus tree pcmcia

regardless of what you are doing' since the modules from David Hinds and Linus pcmcia are not 100% binary compatible for all cases.

However, deleting that code would render a significant number of ARM platforms without PCMCIA support, which would be real bad.
_____

  |_____| ------------------------------------------------- ---+---+-
  |   |         Russell King        [email protected]      --- ---
  | | | | http://www.arm.linux.org.uk/personal/aboutme.html   /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#19 lore raw
Quoted 5 lines
Quoted 2 lines

regardless of what you are doing' since the modules from David Hinds and Linus pcmcia are not 100% binary compatible for all cases.

However, deleting that code would render a significant number of ARM platforms without PCMCIA support, which would be real bad.

It would actually have made no difference as said code didnt actually work anyway. Dwmw2 seems to have solved that

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#20 lore raw
Quoted 8 lines · Alan Cox
Quoted 5 lines
Quoted 2 lines

regardless of what you are doing' since the modules from David Hinds and Linus pcmcia are not 100% binary compatible for all cases.

However, deleting that code would render a significant number of ARM platforms without PCMCIA support, which would be real bad.

It would actually have made no difference as said code didnt actually work anyway. Dwmw2 seems to have solved that

Alan, Russell is talking about CardBus controllers (it's also PCMCIA, in fact, these days it's the _only_ pcmcia in any machine made less than five years ago).

The patches to get i82365 and TCIC up and running again are interesting mainly for laptops with i486 CPUs and for desktops with pcmcia add-in cards (which are basically always ISA i82365-clones). They aren't interesting to ARM, I suspect.

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#21 lore raw
Quoted 3 lines

Alan, Russell is talking about CardBus controllers (it's also PCMCIA, in fact, these days it's the _only_ pcmcia in any machine made less than five years ago).

I have at least two machines here that are < 2 years old but disagree with you. Once is only months old.

Quoted 4 lines

The patches to get i82365 and TCIC up and running again are interesting mainly for laptops with i486 CPUs and for desktops with pcmcia add-in cards (which are basically always ISA i82365-clones). They aren't interesting to ARM, I suspect.

Much ARM stuff has embedded PCMCIA controllers not cardbus, ditto most MIPS WinCE hardware

Alan

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#22 lore raw
Quoted 6 lines · Alan Cox
Quoted 3 lines

Alan, Russell is talking about CardBus controllers (it's also PCMCIA, in fact, these days it's the _only_ pcmcia in any machine made less than five years ago).

I have at least two machines here that are < 2 years old but disagree with you. Once is only months old.

Who makes those pieces of crap? And who _buys_ them? I can understand it in embedded stuff simply because the chips are simpler and smaller, but in a laptop you should definitely try to avoid it.

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#23 lore raw
Quoted 3 lines

Who makes those pieces of crap? And who _buys_ them? I can understand it in embedded stuff simply because the chips are simpler and smaller, but in a laptop you should definitely try to avoid it.

These are mostly handhelds where the space/power issues get important. And as to who makes them, well intel and various mips chip makers. Who buys them. Everyone frantically trying to get to the shop as a new iPaq stock comes in 8)

Alan

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#24 lore raw
In reply to Linus Torvalds
Quoted 4 lines · Linus Torvalds

On Fri, 17 Nov 2000, Alan Cox wrote:
Alan, Russell is talking about CardBus controllers (it's also PCMCIA, in fact, these days it's the _only_ pcmcia in any machine made less than five years ago).

Actually, I wasn't. I was referring to the embedded-type ARM devices of which I have two sat in front of me (both are manufactured within the past year so are "current") and about half the platforms that "ARM Linux" covers have some form of PCMCIA.

Some ARM CPUs even have the PCMCIA controller embedded within them (look at arch/arm/tools/mach-types - each entry containing a reference to SA1100 means that particular platform has the ability to use PCMCIA).

All of the drivers for these devices were written around the in-kernel PCMCIA code.
_____

  |_____| ------------------------------------------------- ---+---+-
  |   |         Russell King        [email protected]      --- ---
  | | | | http://www.arm.linux.org.uk/personal/aboutme.html   /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#25 lore raw
In reply to Russell King
Quoted 7 lines · Russell King
Quoted 3 lines · Alan Cox
Quoted 1 line

From a practical point of view that currently means 'delete Linus tree pcmcia

regardless of what you are doing' since the modules from David Hinds and Linus pcmcia are not 100% binary compatible for all cases.

However, deleting that code would render a significant number of ARM platforms without PCMCIA support, which would be real bad.

Right now, I suspect that the in-kernel pcmcia code is actually at the point where it _is_ possible to use it. David Hinds has been keeping the cs layer in synch with the external versions, and tons of people have helped make the low-level drivers stable again.

If somebody still has a problem with the in-kernel stuff, speak up.

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#26 lore raw
Quoted 1 line · [email protected] said:

If somebody still has a problem with the in-kernel stuff, speak up.

I have an i82092AA evaluation board:

00:06.0 PCMCIA bridge: Intel Corporation 82092AA_0 (rev 02)

	Flags: slow devsel, IRQ 27
	I/O ports at 8400 [size=4]

I have three problems:

1. I have to specify the i365_base parameter when loading i82365,o

2. Even when I specify cs_irq=27, it resorts to polling:

Intel PCIC probe:
Intel i82365sl DF ISA-to-PCMCIA at port 0x8400 ofs 0x00, 2 sockets
host opts [0]: none
host opts [1]: none
ISA irqs (default) = none! polling interval = 1000 ms
Intel i82365sl DF ISA-to-PCMCIA at port 0x8400 ofs 0x80, 2 sockets
host opts [2]: none
host opts [3]: none
ISA irqs (default) = none! polling interval = 1000 ms

3. Note that it finds no IRQs available for the cards' IREQ to use. This is on an Alpha SX164.

I'll fix it over the weekend - basically it just looks like a little too much was stripped out of i82365.c when we started handling CardBus bridges elsewhere. We ought to still handle PCI->PCMCIA bridges which aren't CardBus-capable.

As a separate issue, the IDE on the same chip appears to be confusing the kernel. I seem to end up with the generic IDE driver driving the on-board CY82C693, which means I can't do DMA. That may be SRM's fault, though.

00:06.1 IDE interface: Intel Corporation 82092AA_1 (rev 02) (prog-if 00 [])

	Flags: slow devsel, IRQ 31
	I/O ports at 1090 [size=8]
	I/O ports at 1098
	I/O ports at 10a0 [size=8]
	I/O ports at 10a8 [size=8]

00:08.1 IDE interface: Contaq Microsystems 82c693 (prog-if 80 [Master])

	Flags: bus master, medium devsel, latency 0
	I/O ports at 01f0 [size=8]
	I/O ports at 03f4
	I/O ports at 1080 [size=16]

ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
PCI_IDE: unknown IDE controller on PCI bus 00 device 31, VID=8086, DID=1222
PCI_IDE: chipset revision 2
PCI_IDE: not 100% native mode: will probe irqs later
CY82C693: IDE controller on PCI bus 00 dev 41
CY82C693: chipset revision 0
CY82C693: not 100% native mode: will probe irqs later
CY82C693U driver v0.34 99-13-12 Andreas S. Krebs ([email protected])
CY82C693: port 0x01f0 already claimed by ide0
CY82C693: port 0x0170 already claimed by ide1
CY82C693: neither IDE port enabled (BIOS)

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#27 lore raw
In reply to Linus Torvalds
Quoted 16 lines · David Woodhouse
Quoted 1 line · [email protected] said:

If somebody still has a problem with the in-kernel stuff, speak up.

I have an i82092AA evaluation board:

00:06.0 PCMCIA bridge: Intel Corporation 82092AA_0 (rev 02)
Flags: slow devsel, IRQ 27
I/O ports at 8400 [size=4]

I have three problems:

1. I have to specify the i365_base parameter when loading i82365,o

2. Even when I specify cs_irq=27, it resorts to polling:

Quoted 9 lines

Intel PCIC probe:
Intel i82365sl DF ISA-to-PCMCIA at port 0x8400 ofs 0x00, 2 sockets
host opts [0]: none
host opts [1]: none
ISA irqs (default) = none! polling interval = 1000 ms
Intel i82365sl DF ISA-to-PCMCIA at port 0x8400 ofs 0x80, 2 sockets
host opts [2]: none
host opts [3]: none
ISA irqs (default) = none! polling interval = 1000 ms

For these two, it sounds to me like you need to be doing a PCI probe, and getting the irq and I/O port info from pci_dev. And calling pci_enable_device, which may or may not be a showstopper here...

Jeff

Signature · 7 lines
Jeff Garzik             |
Building 1024           | The chief enemy of creativity is "good" sense
MandrakeSoft            |          -- Picasso
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#28 lore raw
Quoted 3 lines · [email protected] said:

For these two, it sounds to me like you need to be doing a PCI probe,
and getting the irq and I/O port info from pci_dev. And calling pci_enable_device, which may or may not be a showstopper here...

Yep. The same code is already present in David Hinds' i82365.c, but appears to have been stripped out when CardBus sockets started to be supported elsewhere.

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#29 lore raw
In reply to Jeff Garzik
Quoted 13 lines · Jeff Garzik
Quoted 12 lines

2. Even when I specify cs_irq=27, it resorts to polling:

Intel PCIC probe:
Intel i82365sl DF ISA-to-PCMCIA at port 0x8400 ofs 0x00, 2 sockets
host opts [0]: none
host opts [1]: none
ISA irqs (default) = none! polling interval = 1000 ms
Intel i82365sl DF ISA-to-PCMCIA at port 0x8400 ofs 0x80, 2 sockets
host opts [2]: none
host opts [3]: none
ISA irqs (default) = none! polling interval = 1000 ms

Quoted 3 lines

For these two, it sounds to me like you need to be doing a PCI probe, and getting the irq and I/O port info from pci_dev. And calling pci_enable_device, which may or may not be a showstopper here...

The i82365 stuff actually used to do much of this, but it was so intimately intertwined with the cardbus handling that I pruned it out for my sanity.

It should be possible to do the same thing with a nice simple concentrated PCI probe, instead of having stuff quite as spread out as it used to be.

As to why it doesn't show any ISA interrupts, who knows... Some of the PCI PCMCIA bridges need to be initialized.

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#30 lore raw
Quoted 3 lines · [email protected] said:

It should be possible to do the same thing with a nice simple
concentrated PCI probe, instead of having stuff quite as spread out as it used to be.

That's the plan.

Quoted 2 lines

As to why it doesn't show any ISA interrupts, who knows... Some of
the PCI PCMCIA bridges need to be initialized.

ISTR it worked fine in an x86 box. I'll play with it over the weekend.

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#31 lore raw
In reply to Jeff Garzik
Quoted 8 lines

2. Even when I specify cs_irq=27, it resorts to polling:

Intel PCIC probe:
Intel i82365sl DF ISA-to-PCMCIA at port 0x8400 ofs 0x00, 2 sockets
host opts [0]: none
host opts [1]: none
ISA irqs (default) = none! polling interval = 1000 ms

The driver means it when it says "ISA irqs". A value of 27 is not valid for cs_irq because this is an ISA irq number and must be 0..15; this is not a property of the host system, this is a property of the i82365 register specification. PCI interrupts have to be handled differently (well, the stripped-down i82365 driver just can't handle them at all)

-- Dave
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#32 lore raw

2.4's internal PCMCIA works for me (was Re: [PATCH] pcmcia event thread)

In reply to Linus Torvalds
Quoted 6 lines · Linus Torvalds

Right now, I suspect that the in-kernel pcmcia code is actually at the point where it _is_ possible to use it. David Hinds has been keeping the cs layer in synch with the external versions, and tons of people have helped make the low-level drivers stable again.

If somebody still has a problem with the in-kernel stuff, speak up.

I'm going to speak up as someone who uses the in-kernel code without problems (on my Dell Inspiron 5000e and Dell/3Com CardBus 10/100 NIC). The in-kernel support always seems to get a bad rap, so I want to mention that, for some people anyway, the in-kernel code works just as well as the external code.

I do understand that the in-kernel support isn't as mature as the external support yet. However, it isn't universally broken and useless either.

-Barry K. Nathan <[email protected]>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#33 lore raw

Re: 2.4's internal PCMCIA works for me (was Re: [PATCH] pcmcia event thread)

In reply to Linus Torvalds
Quoted 3 lines · Barry K. Nathan

I do understand that the in-kernel support isn't as mature as the external support yet. However, it isn't universally broken and useless either.

That's certainly true; it should work fine for the large majority of configurations. I think the non-platform-specific issues are mostly resolved.

-- Dave
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#34 lore raw
In reply to Linus Torvalds

Linus Torvalds wrote:
[...]

Quoted 1 line

If somebody still has a problem with the in-kernel stuff, speak up.

The kernel's irq detection for the card sockets doesn't work for me. It's the NEC Versa LX story. The DH code also reports no IRQ found but still figures out a working IRQ (normally 3) and assigns it for the tulip card. I use the i82365 module w/ the DH code. The below is the output of the kernel pcmcia code.

[side note for David Hinds - please let me make both kernel pcmcia core modules and dh modules without having to do workarounds]

(pci=biosirq makes no change in any discernable fashion, parts omitted for technical clarity)

# dmesg
Linux PCMCIA Card Services 3.1.22
  options:  [pci] [cardbus] [pm]
PCI: No IRQ known for interrupt pin B of device 00:03.1. Please try using
pci=biosirq.
PCI: No IRQ known for interrupt pin A of device 00:03.0. Please try using
pci=biosirq.
Intel PCIC probe: not found.
Databook TCIC-2 PCMCIA probe: not found.
Yenta IRQ list 0c90, PCI irq0
Socket status: 30000860
Yenta IRQ list 0898, PCI irq0
Socket status: 30000046
[...]
cs: cb_alloc(bus 2): vendor 0x1011, device 0x0019
PCI: Enabling device 02:00.0 (0000 -> 0003)
Linux Tulip driver version 0.9.11 (November 3, 2000)
PCI: No IRQ known for interrupt pin A of device 02:00.0. Please try using
pci=biosirq.
PCI: Setting latency timer of device 02:00.0 to 64
eth0: Digital DS21143 Tulip rev 65 at 0x1800, 00:E0:98:70:1E:AF, IRQ 0.
eth0:  EEPROM default media type Autosense.
eth0:  Index #0 - Media MII (#11) described by a 21142 MII PHY (3) block.
eth0:  MII transceiver #0 config 3000 status 7809 advertising 01e1.
call_usermodehelper[/sbin/hotplug]: no root fs
# cardctl config
Socket 0:
  Vcc 3.3V  Vpp1 3.3V  Vpp2 3.3V
  interface type is "cardbus"
  function 0:
Socket 1:
  not configured
# lspci -vvv
00:03.0 CardBus bridge: Ricoh Co Ltd RL5c478 (rev 03)
        Subsystem: NEC Corporation: Unknown device 8039
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping-
SERR- FastB2B-
        Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR-
        Latency: 168
        Interrupt: pin A routed to IRQ 0
        Region 0: Memory at 10000000 (32-bit, non-prefetchable) [size=4K]
        Bus: primary=00, secondary=02, subordinate=02, sec-latency=176
        Memory window 0: 10c00000-10fff000 (prefetchable)
        Memory window 1: 11000000-113ff000
        I/O window 0: 00001800-000018ff
        I/O window 1: 00001c00-00001cff
        BridgeCtl: Parity- SERR- ISA- VGA- MAbort- >Reset- 16bInt+ PostWrite+
        16-bit legacy interface ports at 0001

00:03.1 CardBus bridge: Ricoh Co Ltd RL5c478 (rev 03)
Subsystem: NEC Corporation: Unknown device 8039
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping-
SERR- FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR-

        Latency: 168
        Interrupt: pin B routed to IRQ 0
        Region 0: Memory at 10001000 (32-bit, non-prefetchable) [size=4K]
        Bus: primary=00, secondary=06, subordinate=06, sec-latency=176
        Memory window 0: 10400000-107ff000 (prefetchable)
        Memory window 1: 10800000-10bff000
        I/O window 0: 00001000-000010ff
        I/O window 1: 00001400-000014ff
        BridgeCtl: Parity- SERR- ISA- VGA- MAbort- >Reset- 16bInt- PostWrite+
        16-bit legacy interface ports at 0001
# dump_pirq
Interrupt routing table found at address 0xf5a80:
  Version 1.0, size 0x0080
  Interrupt router is device 00:07.0
  PCI exclusive interrupt mask: 0x0000
  Compatible router: vendor 0x8086 device 0x1234

Device 00:03.0 (slot 0):
INTA: link 0x60, irq mask 0x0420
INTB: link 0x61, irq mask 0x0420

Interrupt router: Intel 82371AB PIIX4/PIIX4E PCI-to-ISA bridge
PIRQ1 (link 0x60): irq 10
PIRQ2 (link 0x61): irq 5
PIRQ3 (link 0x62): unrouted
PIRQ4 (link 0x63): irq 9
Serial IRQ: [enabled] [continuous] [frame=21] [pulse=4]

begin:vcard
n:Ford;David
x-mozilla-html:TRUE
adr:;;;;;;
version:2.1
email;internet:[email protected]
title:Blue Labs Developer
x-mozilla-cpt:;14688
fn:David Ford
end:vcard

#35 lore raw
Quoted 10 lines · David Ford

Linus Torvalds wrote:
[...]

Quoted 1 line

If somebody still has a problem with the in-kernel stuff, speak up.

The kernel's irq detection for the card sockets doesn't work for me. It's the NEC Versa LX story. The DH code also reports no IRQ found but still figures out a working IRQ (normally 3) and assigns it for the tulip card. I use the i82365 module w/ the DH code. The below is the output of the kernel pcmcia code.

Quoted 4 lines

PCI: No IRQ known for interrupt pin B of device 00:03.1. Please try using pci=biosirq.
PCI: No IRQ known for interrupt pin A of device 00:03.0. Please try using pci=biosirq.

Strange. Your interrupt router is a bog-standard PIIX4, we know how to route the thing, AND your device shows up:

Quoted 11 lines
# dump_pirq
Interrupt routing table found at address 0xf5a80:
  Version 1.0, size 0x0080
  Interrupt router is device 00:07.0
  PCI exclusive interrupt mask: 0x0000
  Compatible router: vendor 0x8086 device 0x1234

Device 00:03.0 (slot 0):
INTA: link 0x60, irq mask 0x0420
INTB: link 0x61, irq mask 0x0420

Quoted 6 lines

Interrupt router: Intel 82371AB PIIX4/PIIX4E PCI-to-ISA bridge
PIRQ1 (link 0x60): irq 10
PIRQ2 (link 0x61): irq 5
PIRQ3 (link 0x62): unrouted
PIRQ4 (link 0x63): irq 9
Serial IRQ: [enabled] [continuous] [frame=21] [pulse=4]

Can you (you've probably done this before, but anyway) enable DEBUG in arch/i386/kernel/pci-i386.h? I wonder if the kernel for some strange reason doesn't find your router, even though "dump_pirq" obviously does.. If there's something wrong with the checksumming for example..

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#36 lore raw
Quoted 4 lines · Linus Torvalds

Can you (you've probably done this before, but anyway) enable DEBUG in arch/i386/kernel/pci-i386.h? I wonder if the kernel for some strange reason doesn't find your router, even though "dump_pirq" obviously does.. If there's something wrong with the checksumming for example..

..building now.

-d

begin:vcard
n:Ford;David
x-mozilla-html:TRUE
adr:;;;;;;
version:2.1
email;internet:[email protected]
title:Blue Labs Developer
x-mozilla-cpt:;14688
fn:David Ford
end:vcard

#37 lore raw
Quoted 8 lines · David Ford
Quoted 4 lines · Linus Torvalds

Can you (you've probably done this before, but anyway) enable DEBUG in arch/i386/kernel/pci-i386.h? I wonder if the kernel for some strange reason doesn't find your router, even though "dump_pirq" obviously does.. If there's something wrong with the checksumming for example..

..building now.

Actually, try this patch first. It adds the PCI_DEVICE_ID_INTEL_82371MX router type, and also makes the PCI router search fall back more gracefully on the device it actually found if there is not an exact match on the "compatible router" entry...

It should make Linux find and accept the chip you have. Knock wood.

Linus

arch/i386/kernel/pci-irq.c renamed from linux/arch/i386/kernel/pci-irq.c +28 -23
@@ -283,12 +297,19 @@
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
+
 	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
+
 	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
 	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
 	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
+
 	{ "OPTI", PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700, pirq_opti_get, pirq_opti_set },
+
+	{ "NatSemi", PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, pirq_cyrix_get, pirq_cyrix_set },
+
 	{ "default", 0, 0, NULL, NULL }
 };
 
@@ -298,7 +319,6 @@
 static void __init pirq_find_router(void)
 {
 	struct irq_routing_table *rt = pirq_table;
-	u16 rvendor, rdevice;
 	struct irq_router *r;
 
 #ifdef CONFIG_PCI_BIOS
@@ -308,32 +328,31 @@
 		return;
 	}
 #endif
-	if (!(pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) {
+	/* fall back to default router if nothing else found */
+	pirq_router = pirq_routers + sizeof(pirq_routers) / sizeof(pirq_routers[0]) - 1;
+
+	pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
+	if (!pirq_router_dev) {
 		DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
-		/* fall back to default router */
-		pirq_router = pirq_routers + sizeof(pirq_routers) / sizeof(pirq_routers[0]) - 1;
 		return;
 	}
-	if (rt->rtr_vendor) {
-		rvendor = rt->rtr_vendor;
-		rdevice = rt->rtr_device;
-	} else {
-		/*
-		 * Several BIOSes forget to set the router type. In such cases, we
-		 * use chip vendor/device. This doesn't guarantee us semantics of
-		 * PIRQ values, but was found to work in practice and it's still
-		 * better than not trying.
-		 */
-		DBG("PCI: Guessed interrupt router ID from %s\n", pirq_router_dev->slot_name);
-		rvendor = pirq_router_dev->vendor;
-		rdevice = pirq_router_dev->device;
-	}
-	for(r=pirq_routers; r->vendor; r++)
-		if (r->vendor == rvendor && r->device == rdevice)
+
+	for(r=pirq_routers; r->vendor; r++) {
+		/* Exact match against router table entry? Use it! */
+		if (r->vendor == rt->rtr_vendor && r->device == rt->rtr_device) {
+			pirq_router = r;
 			break;
-	pirq_router = r;
-	printk("PCI: Using IRQ router %s [%04x/%04x] at %s\n", r->name,
-	       rvendor, rdevice, pirq_router_dev->slot_name);
+		}
+		/* Match against router device entry? Use it as a fallback */
+		if (r->vendor == pirq_router_dev->vendor && r->device == pirq_router_dev->device) {
+			pirq_router = r;
+		}
+	}
+	printk("PCI: Using IRQ router %s [%04x/%04x] at %s\n",
+		pirq_router->name,
+		pirq_router_dev->vendor,
+		pirq_router_dev->device,
+		pirq_router_dev->slot_name);
 }
 
 static struct irq_info *pirq_get_info(struct pci_dev *dev, int pin)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#38 lore raw

It's time for a week long party!

It works great, interrupts are even delivered to the tulip handler :)

Attached is the boot dmesg in case any aesthetic changes are desired.

Ted, please scratch off the NEC Versa LX PCMCIA entries as fixed, I assume this patch will go in on the next release.

MEGA thank yous,
-d

----
PCI: BIOS32 Service Directory structure at 0xc00fdb70
PCI: BIOS32 Service Directory entry at 0xfdb80
PCI: BIOS probe returned s=00 hw=01 ver=02.10 l=01
PCI: PCI BIOS revision 2.10 entry at 0xfdba1, last bus=1
PCI: Using configuration type 1
PCI: Probing PCI hardware
PCI: IDE base address fixup for 00:07.1
PCI: Scanning for ghost devices on bus 0
PCI: Scanning for ghost devices on bus 1
PCI: IRQ init
PCI: Interrupt Routing Table found at 0xc00f5a80
00:01 slot=00 0:60/0420 1:00/0000 2:00/0000 3:00/0000
00:03 slot=00 0:60/0420 1:61/0420 2:00/0000 3:00/0000
00:04 slot=00 0:61/0420 1:00/0000 2:00/0000 3:00/0000
00:05 slot=00 0:60/0420 1:00/0000 2:00/0000 3:00/0000
00:07 slot=00 0:fe/4000 1:ff/8000 2:00/0000 3:63/0200
00:11 slot=01 0:60/0420 1:61/0420 2:62/0800 3:61/0420
PCI: Using IRQ router PIIX [8086/7110] at 00:07.0
PCI: IRQ fixup
00:03.0: ignoring bogus IRQ 255
00:03.1: ignoring bogus IRQ 255
IRQ for 00:03.0(0) via 00:03.0 -> PIRQ 60, mask 0420, excl 0000 -> got IRQ 10
PCI: Found IRQ 10 for device 00:03.0
PCI: The same IRQ used for device 01:00.0
IRQ for 00:03.1(1) via 00:03.1 -> PIRQ 61, mask 0420, excl 0000 -> got IRQ 5
PCI: Found IRQ 5 for device 00:03.1
PCI: The same IRQ used for device 00:04.0
PCI: Allocating resources
PCI: Resource e0000000-efffffff (f=1208, d=0, p=0)
PCI: Resource 0000ec00-0000ecff (f=101, d=0, p=0)
PCI: Resource 0000ffa0-0000ffaf (f=101, d=0, p=0)
PCI: Resource 0000ef80-0000ef9f (f=101, d=0, p=0)
PCI: Resource fd000000-fdffffff (f=200, d=0, p=0)
PCI: Resource 0000dc00-0000dcff (f=101, d=0, p=0)
PCI: Resource feaff000-feafffff (f=200, d=0, p=0)
PCI: Sorting device list...
Limiting direct PCI/PCI transfers.

Linux PCMCIA Card Services 3.1.22
options: [pci] [cardbus] [pm]
Intel PCIC probe: not found.
Databook TCIC-2 PCMCIA probe: not found.
usb.c: registered new driver usbdevfs
usb.c: registered new driver hub
Yenta IRQ list 0898, PCI irq10
Socket status: 30000860
Yenta IRQ list 0898, PCI irq5
Socket status: 30000046

cs: cb_alloc(bus 2): vendor 0x1011, device 0x0019
PCI: Enabling device 02:00.0 (0000 -> 0003) Linux Tulip driver version 0.9.11 (November 3, 2000)

PCI: Setting latency timer of device 02:00.0 to 64
eth1: Digital DS21143 Tulip rev 65 at 0x1800, 00:E0:98:70:1E:AF, IRQ 10.
eth1:  EEPROM default media type Autosense.
eth1:  Index #0 - Media MII (#11) described by a 21142 MII PHY (3) block.
eth1:  MII transceiver #0 config 3000 status 7809 advertising 01e1.

call_usermodehelper[/sbin/hotplug]: no root fs

Quoted 93 lines · Linus Torvalds
Quoted 8 lines · David Ford
Quoted 4 lines · Linus Torvalds

Can you (you've probably done this before, but anyway) enable DEBUG in arch/i386/kernel/pci-i386.h? I wonder if the kernel for some strange reason doesn't find your router, even though "dump_pirq" obviously does.. If there's something wrong with the checksumming for example..

..building now.

Actually, try this patch first. It adds the PCI_DEVICE_ID_INTEL_82371MX router type, and also makes the PCI router search fall back more gracefully on the device it actually found if there is not an exact match on the "compatible router" entry...

It should make Linux find and accept the chip you have. Knock wood.

Linus

arch/i386/kernel/pci-irq.c Sat Nov 18 21:11:19 2000 renamed from linux/arch/i386/kernel/pci-irq.c Tue Oct 31 12:42:26 2000 +21 -23
@@ -283,12 +297,19 @@
        { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set },
        { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set },
        { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
+       { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
        { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
+
        { "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
+
        { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
        { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
        { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
+
        { "OPTI", PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700, pirq_opti_get, pirq_opti_set },
+
+       { "NatSemi", PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, pirq_cyrix_get, pirq_cyrix_set },
+
        { "default", 0, 0, NULL, NULL }
 };
 
@@ -298,7 +319,6 @@
 static void __init pirq_find_router(void)
 {
        struct irq_routing_table *rt = pirq_table;
-       u16 rvendor, rdevice;
        struct irq_router *r;
 
 #ifdef CONFIG_PCI_BIOS
@@ -308,32 +328,31 @@
                return;
        }
 #endif
-       if (!(pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) {
+       /* fall back to default router if nothing else found */
+       pirq_router = pirq_routers + sizeof(pirq_routers) / sizeof(pirq_routers[0]) - 1;
+
+       pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
+       if (!pirq_router_dev) {
                DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
-               /* fall back to default router */
-               pirq_router = pirq_routers + sizeof(pirq_routers) / sizeof(pirq_routers[0]) - 1;
                return;
        }
-       if (rt->rtr_vendor) {
-               rvendor = rt->rtr_vendor;
-               rdevice = rt->rtr_device;
-       } else {
-               /*
-                * Several BIOSes forget to set the router type. In such cases, we
-                * use chip vendor/device. This doesn't guarantee us semantics of
-                * PIRQ values, but was found to work in practice and it's still
-                * better than not trying.
-                */
-               DBG("PCI: Guessed interrupt router ID from %s\n", pirq_router_dev->slot_name);
-               rvendor = pirq_router_dev->vendor;
-               rdevice = pirq_router_dev->device;
-       }
-       for(r=pirq_routers; r->vendor; r++)
-               if (r->vendor == rvendor && r->device == rdevice)
+
+       for(r=pirq_routers; r->vendor; r++) {
+               /* Exact match against router table entry? Use it! */
+               if (r->vendor == rt->rtr_vendor && r->device == rt->rtr_device) {
+                       pirq_router = r;
                        break;
-       pirq_router = r;
-       printk("PCI: Using IRQ router %s [%04x/%04x] at %s\n", r->name,
-              rvendor, rdevice, pirq_router_dev->slot_name);
+               }
+               /* Match against router device entry? Use it as a fallback */
+               if (r->vendor == pirq_router_dev->vendor && r->device == pirq_router_dev->device) {
+                       pirq_router = r;

arch/i386/kernel/pci-irq.c Sat Nov 18 21:11:19 2000 line 358

Quoted 10 lines
arch/i386/kernel/pci-irq.c Sat Nov 18 21:11:19 2000 renamed from linux/arch/i386/kernel/pci-irq.c Tue Oct 31 12:42:26 2000 +7 -0
+               }
+       }
+       printk("PCI: Using IRQ router %s [%04x/%04x] at %s\n",
+               pirq_router->name,
+               pirq_router_dev->vendor,
+               pirq_router_dev->device,
+               pirq_router_dev->slot_name);
 }
 
 static struct irq_info *pirq_get_info(struct pci_dev *dev, int pin)

begin:vcard
n:Ford;David
x-mozilla-html:TRUE
adr:;;;;;;
version:2.1
email;internet:[email protected]
title:Blue Labs Developer
x-mozilla-cpt:;14688
fn:David Ford
end:vcard

#39 lore raw

neighbour table?

I get a message

neighbour table overflow

What does that mean? It seems that

net/ipv4/route.c

is the place where it prints this. But under what circumstances does this happen?
Thanks

-A.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#40 lore raw

Re: neighbour table?

Quoted 11 lines · Andrew Park

I get a message

neighbour table overflow

What does that mean? It seems that

net/ipv4/route.c

is the place where it prints this. But under what circumstances does this happen?
Thanks

It means you set the link state of eth0 up before lo.

Be sure lo is established before eth0 and you won't see this message.

-d

begin:vcard
n:Ford;David
x-mozilla-html:TRUE
adr:;;;;;;
version:2.1
email;internet:[email protected]
title:Blue Labs Developer
x-mozilla-cpt:;14688
fn:David Ford
end:vcard

#41 lore raw

Re: neighbour table?

In reply to Andrew Park
Quoted 10 lines · David Ford
Quoted 8 lines · Andrew Park

I get a message

neighbour table overflow

What does that mean? It seems that

net/ipv4/route.c

Quoted 7 lines
Quoted 3 lines

is the place where it prints this. But under what circumstances does this happen?
Thanks

It means you set the link state of eth0 up before lo.

Be sure lo is established before eth0 and you won't see this message.

Hmm. How does the interaction work. I've been meaning to track it for a while but haven't yet.

Quoted 1 line

From the cases I have observed it seems to be connected with arp requests

that aren't answered. (I.e when something is misconfigured and you try to nfsroot off of the wrong ip on your subnet)
And I keep thinking neighbour table underflow would have been a better message.

Eric

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#42 lore raw

Re: neighbour table?

In reply to Andrew Park
Quoted 9 lines · Eric W. Biederman
Quoted 1 line

Be sure lo is established before eth0 and you won't see this message.

Hmm. How does the interaction work. I've been meaning to track it for a while but haven't yet.

Quoted 1 line

From the cases I have observed it seems to be connected with arp requests

that aren't answered. (I.e when something is misconfigured and you try to nfsroot off of the wrong ip on your subnet)
And I keep thinking neighbour table underflow would have been a better message.

I'm not sure, I'm repeating what Alexey (iirc) has said in the past. I've been there/done that and sure enough making sure 'lo' is brought up first prevents that message. As to the NFS, no idea, I've never messed w/ nfsroot.

-d

begin:vcard
n:Ford;David
x-mozilla-html:TRUE
adr:;;;;;;
version:2.1
email;internet:[email protected]
title:Blue Labs Developer
x-mozilla-cpt:;14688
fn:David Ford
end:vcard

#43 lore raw
In reply to David Ford
Quoted 10 lines · Linus Torvalds

Strange. Your interrupt router is a bog-standard PIIX4, we know how to route the thing, AND your device shows up:

Quoted 6 lines
# dump_pirq
Interrupt routing table found at address 0xf5a80:
  Version 1.0, size 0x0080
  Interrupt router is device 00:07.0
  PCI exclusive interrupt mask: 0x0000
  Compatible router: vendor 0x8086 device 0x1234

Oh... the kernel pci-irq code looks for the "compatible router" if it is set; if unset, then it looks up the ID's of the router device.

0x8086, 0x1234 is not a known router type, so the kernel decides it can't interpret the routing table.

0x8086, 0x1234 is listed in pci_ids.h as an 82371MX. I'm suspicious of that: the MX chipset has an 82443MX, not an 82371. In any case, I think pci-irq.c should check both sets of ID's for a match.

-- Dave

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#44 lore raw
In reply to David Woodhouse

Hi!

Quoted 6 lines
Quoted 3 lines

Cool. Linus, please could you apply this patch. If the fact that i82365 and tcic are broken in 2.4 isn't on Ted's critical list, then I think it probably ought to have been - and this should fix it.

It's purposefully not on Ted's critical list, the official line is "use pcmcia_cs external package" if you need i82365 or tcic instead of yenta

Ted, is this true? It would be wonderfull to be able to use i82365 without need for pcmcia_cs...

I think in-kernel pcmcia crashing even on simple things *is* critical bug.

Pavel

Signature · 7 lines
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#45 lore raw

Date: Sat, 1 Jan 2000 02:54:52 +0000
From: Pavel Machek <[email protected]>
Cc: David Woodhouse <[email protected]>, David Hinds <[email protected]>,
[email protected], [email protected], [email protected], [email protected]

Quoted 2 lines

It's purposefully not on Ted's critical list, the official line is "use pcmcia_cs external package" if you need i82365 or tcic instead of yenta

Ted, is this true? It would be wonderfull to be able to use i82365 without need for pcmcia_cs...

I think in-kernel pcmcia crashing even on simple things *is* critical bug.

It was Linus who said that Pcmcia crashing wasn't necessarily a critical bug since 2.2 didn't have Pcmcia support in-kernel, and that for 2.4, it was likely that most distributions would be best served to ship with David Hind's external pcmcia driver.

That was several months ago, and perhaps things have changed. But that was I didn't spend time worrying about tracking PCMCIA bug reports; there were a non-trivial number of them, and they were mostly of the form "doesn't work on XXX hardware", "causes kernel oops on YYYY hardware", etc.

- Ted
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#46 lore raw
In reply to David Woodhouse
Quoted 5 lines · On Thu, Nov 16, 2000 at 01:26:36PM -0800, [email protected] wrote:
Quoted 5 lines

Ted, is this true? It would be wonderfull to be able to use i82365 without need for pcmcia_cs...

I think in-kernel pcmcia crashing even on simple things *is* critical bug.

It wasn't a critical bug, in the sense that because the i82365 driver did not work, it was not even offered as a config option. If anything it was merely a missing feature. And not a critical one, since the feature was available outside of the kernel.

It is a moot point, since i82365 works with the new patches.

Quoted 5 lines

That was several months ago, and perhaps things have changed. But that was I didn't spend time worrying about tracking PCMCIA bug reports; there were a non-trivial number of them, and they were mostly of the form "doesn't work on XXX hardware", "causes kernel oops on YYYY hardware", etc.

Some of these have been resolved, but some remain. They have not been easy things to decipher since they involve interactions between the PCI subsystem, PCMCIA, and specific hardware.

-- Dave
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#47 lore raw
In reply to Jeff Garzik
Quoted 6 lines
Quoted 2 lines

up_and_exit() would do it. Or preferably passing the address of the semaphore as an extra argument to kernel_thread() in the first place.

Any solution which involves a function being called from a kernel thread, and/or passing another arg to a kernel thread, is a non-starter ... See the discussion about timer_exit() a while ago. This sort of

timer_exit is a completely unrelated situation

Quoted 2 lines

IMHO it is possible to solve this in a generic way without having to change the code for every single kernel thread.

It comes entirely down to one thing. The termination function of the thread has to be code in the kernel code not a module. Thats it, nothing else. So you just need some kind of sleep/wakeup proceedure for it.

As far as I can see all you need is

wait_and_die(sem)
{
up(&sem); /* In the kernel so can unload */
sys_exit(0); /* Never return to the unloaded module code */
}

in the main kernel. In fact if you were bored you could build this on the kernel stack ;)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#48 lore raw
Quoted 1 line · [email protected] said:

Umm.. Linus drivers dont appear to be SMP safe on unload

AFAIK, no kernel threads are currently SMP safe on unload. However, the PCMCIA thread would be safe with the patch below, and we could fairly easily convert the others to use up_and_exit() once it's available.

Anyone using PCMCIA or CardBus with 2.4, even if you have a non-CardBus i82365 or TCIC controller for which the driver was disabled in test11-pre5, please could you test this? Especially if you have TCIC, in fact, because it's already been tested successfully on yenta and i82365.

(pcmcia-dif-7). Linus, this is the full patch against pre5, including the incremental part I sent this morning.

Index: drivers/pcmcia/Config.in
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/Config.in,v retrieving revision 1.1.2.7

pcmcia/Config.in +11 -11
diff -u -r1.1.2.7 Config.in
@@ -7,18 +7,18 @@
 mainmenu_option next_comment
 comment 'PCMCIA/CardBus support'
 
-dep_tristate 'CardBus support' CONFIG_PCMCIA $CONFIG_PCI
-if [ "$CONFIG_PCMCIA" != "n" ]; then
-  define_bool CONFIG_CARDBUS y
-fi
-
-#tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
+#dep_tristate 'CardBus support' CONFIG_PCMCIA $CONFIG_PCI
 #if [ "$CONFIG_PCMCIA" != "n" ]; then
-#   if [ "$CONFIG_PCI" != "n" ]; then
-#      bool '  CardBus support' CONFIG_CARDBUS
-#   fi
-#   bool '  i82365 compatible bridge support' CONFIG_I82365
-#   bool '  Databook TCIC host bridge support' CONFIG_TCIC
+#  define_bool CONFIG_CARDBUS y
 #fi
+
+tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
+if [ "$CONFIG_PCMCIA" != "n" ]; then
+   if [ "$CONFIG_PCI" != "n" ]; then
+      bool '  CardBus support' CONFIG_CARDBUS
+   fi
+   bool '  i82365 compatible bridge support' CONFIG_I82365
+   bool '  Databook TCIC host bridge support' CONFIG_TCIC
+fi
 
 endmenu

Index: drivers/pcmcia/cs.c
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/cs.c,v retrieving revision 1.1.2.28

pcmcia/cs.c +71 -0

98 lines not on this page · raw message

Index: drivers/pcmcia/i82365.c
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/i82365.c,v retrieving revision 1.1.2.14

pcmcia/i82365.c +29 -2
diff -u -r1.1.2.14 i82365.c
@@ -859,6 +859,28 @@
 
 /*====================================================================*/
 
+static u_int pending_events[8];
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static void pcic_bh(void *dummy)
+{
+	u_int events;
+	int i;
+
+	for (i=0; i < sockets; i++) {
+		spin_lock_irq(&pending_event_lock);
+		events = pending_events[i];
+		pending_events[i] = 0;
+		spin_unlock_irq(&pending_event_lock);
+		if (socket[i].handler)
+			socket[i].handler(socket[i].info, events);
+	}
+}
+
+static struct tq_struct pcic_task = {
+	routine:	pcic_bh
+};
+
 static void pcic_interrupt(int irq, void *dev,
 				    struct pt_regs *regs)
 {
@@ -893,8 +915,13 @@
 	    }
 	    ISA_UNLOCK(i, flags);
 	    DEBUG(2, "i82365: socket %d event 0x%02x\n", i, events);
-	    if (events)
-		socket[i].handler(socket[i].info, events);
+
+	    if (events) {
+		    spin_lock(&pending_event_lock);
+		    pending_events[i] |= events;
+		    spin_unlock(&pending_event_lock);
+		    pcmcia_queue_task(&pcic_task);
+	    }
 	    active |= events;
 	}
 	if (!active) break;

Index: drivers/pcmcia/pci_socket.c
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/pci_socket.c,v retrieving revision 1.1.2.7

pcmcia/pci_socket.c +1 -1
diff -u -r1.1.2.7 pci_socket.c
@@ -177,7 +177,7 @@
 	socket->dev = dev;
 	socket->op = ops;
 	dev->driver_data = socket;
-	init_waitqueue_head(&socket->wait);
+	spin_lock_init(&socket->event_lock);
 	return socket->op->open(socket);
 }
 

Index: drivers/pcmcia/pci_socket.h
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/pci_socket.h,v retrieving revision 1.1.2.5

pcmcia/pci_socket.h +3 -1
diff -u -r1.1.2.5 pci_socket.h
@@ -18,9 +18,11 @@
 	void *info;
 	struct pci_socket_ops *op;
 	socket_cap_t cap;
-	wait_queue_head_t wait;
+	spinlock_t event_lock;
 	unsigned int events;
 	struct socket_info_t *pcmcia_socket;
+	struct tq_struct tq_task;
+	struct timer_list poll_timer;
 
 	/* A few words of private data for the low-level driver.. */
 	unsigned int private[8];

Index: drivers/pcmcia/tcic.c
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/tcic.c,v retrieving revision 1.1.2.9

pcmcia/tcic.c +28 -2
diff -u -r1.1.2.9 tcic.c
@@ -530,6 +530,28 @@
 
 /*====================================================================*/
 
+static u_int pending_events[2];
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static void tcic_bh(void *dummy)
+{
+	u_int events;
+	int i;
+
+	for (i=0; i < sockets; i++) {
+		spin_lock_irq(&pending_event_lock);
+		events = pending_events[i];
+		pending_events[i] = 0;
+		spin_unlock_irq(&pending_event_lock);
+		if (socket_table[i].handler)
+			socket_table[i].handler(socket_table[i].info, events);
+	}
+}
+
+static struct tq_struct tcic_task = {
+	routine:	tcic_bh
+};
+
 static void tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
     int i, quick = 0;
@@ -567,9 +589,13 @@
 	    events |= (latch & TCIC_SSTAT_RDY) ? SS_READY : 0;
 	    events |= (latch & TCIC_SSTAT_LBAT1) ? SS_BATDEAD : 0;
 	    events |= (latch & TCIC_SSTAT_LBAT2) ? SS_BATWARN : 0;
+	}
+	if (events) {
+		spin_lock(&pending_event_lock);
+		pending_events[i] |= events;
+		spin_unlock(&pending_event_lock);
+		pcmcia_queue_task(&tcic_task);	
 	}
-	if (events)
-	    socket_table[i].handler(socket_table[i].info, events);
     }
 
     /* Schedule next poll, if needed */

Index: drivers/pcmcia/yenta.c
===================================================================
RCS file: /inst/cvs/linux/drivers/pcmcia/Attic/yenta.c,v retrieving revision 1.1.2.25

pcmcia/yenta.c +55 -31

140 lines not on this page · raw message

Index: include/linux/kernel.h
===================================================================
RCS file: /inst/cvs/linux/include/linux/kernel.h,v retrieving revision 1.1.1.1.2.11

linux/kernel.h +4 -0
diff -u -r1.1.1.1.2.11 kernel.h
@@ -45,10 +45,14 @@
 #define FASTCALL(x)	x
 #endif
 
+struct semaphore;
+
 extern struct notifier_block *panic_notifier_list;
 NORET_TYPE void panic(const char * fmt, ...)
 	__attribute__ ((NORET_AND format (printf, 1, 2)));
 NORET_TYPE void do_exit(long error_code)
+	ATTRIB_NORET;
+NORET_TYPE void up_and_exit(struct semaphore *, long)
 	ATTRIB_NORET;
 extern unsigned long simple_strtoul(const char *,char **,unsigned int);
 extern long simple_strtol(const char *,char **,unsigned int);

Index: include/pcmcia/cs.h
===================================================================
RCS file: /inst/cvs/linux/include/pcmcia/Attic/cs.h,v retrieving revision 1.1.2.8

pcmcia/cs.h +1 -0
diff -u -r1.1.2.8 cs.h
@@ -443,6 +443,7 @@
 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
 int pcmcia_modify_configuration(client_handle_t handle, modconf_t *mod);
 int pcmcia_modify_window(window_handle_t win, modwin_t *req);
+void pcmcia_queue_task(struct tq_struct *task);
 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
 int pcmcia_release_configuration(client_handle_t handle);
 int pcmcia_release_io(client_handle_t handle, io_req_t *req);

Index: kernel/exit.c
===================================================================
RCS file: /inst/cvs/linux/kernel/exit.c,v
retrieving revision 1.3.2.29

exit.c +8 -0
diff -u -r1.3.2.29 exit.c
@@ -467,6 +467,14 @@
 	goto fake_volatile;
 }
 
+NORET_TYPE void up_and_exit(struct semaphore *sem, long code)
+{
+	if (sem)
+		up(sem);
+	
+	do_exit(code);
+}
+
 asmlinkage long sys_exit(int error_code)
 {
 	do_exit((error_code&0xff)<<8);

Index: kernel/ksyms.c
===================================================================
RCS file: /inst/cvs/linux/kernel/ksyms.c,v
retrieving revision 1.3.2.65

ksyms.c +1 -0
diff -u -r1.3.2.65 ksyms.c
@@ -417,6 +417,7 @@
 EXPORT_SYMBOL(iomem_resource);
 
 /* process management */
+EXPORT_SYMBOL(up_and_exit);
 EXPORT_SYMBOL(__wake_up);
 EXPORT_SYMBOL(wake_up_process);
 EXPORT_SYMBOL(sleep_on);

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#49 lore raw
Quoted 8 lines · David Woodhouse
Quoted 1 line · [email protected] said:

Umm.. Linus drivers dont appear to be SMP safe on unload

AFAIK, no kernel threads are currently SMP safe on unload. However, the PCMCIA thread would be safe with the patch below, and we could fairly easily convert the others to use up_and_exit() once it's available.

Quoted 7 lines

Anyone using PCMCIA or CardBus with 2.4, even if you have a non-CardBus i82365 or TCIC controller for which the driver was disabled in test11-pre5, please could you test this? Especially if you have TCIC, in fact, because it's already been tested successfully on yenta and i82365.

(pcmcia-dif-7). Linus, this is the full patch against pre5, including the incremental part I sent this morning.

I have finally managed to find time to test it, and after five minutes, I must say that it looks very good. I was able to both plug and unplug cards, and cardmgr did what it was supposed to do. If something bad turns up, I will let you know.

I vote for inclusion! :-)

/Tobias

dmesg info:

Linux PCMCIA Card Services 3.1.22
options: [pci] [cardbus] [pm]
Intel PCIC probe:
Vadem VG-469 ISA-to-PCMCIA at port 0x3e0 ofs 0x00, 2 sockets
host opts [0]: none
host opts [1]: none
ISA irqs (scanned) = 3,4,5,7 polling interval = 1000 ms

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#50 lore raw
In reply to Alan Cox

Hi!

Quoted 11 lines
Quoted 1 line · [email protected] said:

Umm.. Linus drivers dont appear to be SMP safe on unload

AFAIK, no kernel threads are currently SMP safe on unload. However, the PCMCIA thread would be safe with the patch below, and we could fairly easily convert the others to use up_and_exit() once it's available.

Anyone using PCMCIA or CardBus with 2.4, even if you have a non-CardBus i82365 or TCIC controller for which the driver was disabled in test11-pre5, please could you test this? Especially if you have TCIC, in fact, because it's already been tested successfully on yenta and i82365.

Thanx a lot, it fixed problems with my i82365.

Pavel

Signature · 6 lines
I'm [email protected]. "In my country we have almost anarchy and I don't care."
Panos Katsaloulis describing me w.r.t. patents at [email protected]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#51 lore raw
In reply to Jeff Garzik
Quoted 11 lines

it looks like the loop can be simplified to

while (1) {
	mb();
	active = tq_pcmcia;
	if (!active)
		interruptible_sleep_on(&event_thread_wq);
	if (signal_pending(current)
		break;
	run_task_queue(&tq_pcmcia);
}

Not if you want it to work

Alan

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/