Tim Waugh (tim@cyberelk.demon.co.uk)
Wed, 17 Mar 1999 09:23:10 +0000 (GMT)
Right, I think I understand the problem that causes the oops now:
lp calls parport_claim_or_block
lp calls parport_write
parport_write calls port->ops->compat_write_block
- queues a task to do the real work
parport_write does down_interruptible() for callback.
--- SIGINT ---
lp calls parport_release
queued task is run, assuming port is claimed by the client device driver
struct pardevice *dev = port->dev; /* This is now NULL */
do characters until timeslice is up
parport_release like a good driver, only it's parport_release(NULL)
*BANG*
I don't know what the best solution is, although this comes to mind:
PARPORT_FLAG_RELDEFER, set on parport_release if there is something going
on in the background, and cleared (and the port actually released) when
the background operation stops. parport_claim has to refuse all claims
when the flag is set, and callback parameters must be around for at least
the duration of the port, i.e. you couldn't do this:
void callback (struct semaphore *sem)
{ up (sem); }
void do_stuff (struct parport *port)
{ struct semaphore sem = MUTEX_LOCKED;
port->ops->compat_write_block (...);
down_interruptible (&sem);
}
because sem won't stay around after we get a signal.
Alternatively, we could just not call the callback function if RELDEFER is
set.
It's quite ugly though. Other ideas?
Tim.
*/
-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --
This archive was generated by hypermail 2.0b3 on Sun 28 Mar 1999 - 17:01:33 EST