[PARPORT] Re: IMM driver weirdness.


Matthias Welwarsky (matze@stud.fbi.fh-darmstadt.de)
Thu, 24 Sep 1998 17:28:31 +0200


Hello David and list,

> > The offending code is:
> >
> > --- imm_detect() ---
> > /* Claim the bus so it remembers what we do to the control
> > * registers. [ CTR and ECP ]
> > */
> > if (imm_pb_claim(i))
> > while (imm_hosts[i].p_busy)
> > schedule(); /* We are safe to schedule here */
> > --- imm_detect() ---
>
> >From memory what is happening here is a lock out against the SCSI mid-level
> driver. In the kernel you can not be sure that some other thread is not running
> in the same driver. What has happened in the past is that the driver has just
> about finished one task when the next kicks off. Hence p_busy should be
> cleared elsewhere...

> I am forwarding this to the Linux parallel port list since this starts dealing with
> the finer details of parallel port sharing (trust me - I really need to refresh my
> knowledge on the subject, it is a bit of a black art at times). .

Yeah, I cannot blame you for anything - most of the kernel programming
interfaces are undocumented, parport isn't the only bad example, take
the scsi or the networking stuff, it's all the same. It's really sad:
most of the time you don't know if you're hunting a bug in your own or
in someone elses code :-(

> I have yet to hear of a report detailing a lock-up when "insmod ppa" or
> "insmod imm" which is atributable to the circumstances that you are suggesting.

I can assure you of that. I accidetially tried the ppa-driver before,
and it locked up the same way. Just forgot to mention this in my
previous mail, I'm sorry.

> > There are two or three problems:
> >
> > First: imm_hosts[i].p_busy will never become 0. So once you find a busy
> > port, imm_detect() will lock up in the loop. and even if there was some
> > code in the driver that resetted p_busy, what about drivers that don't
> > ever release a parport they once claimed?
>
> Those drivers should be taken out and shot. The mid-level SCSI driver (which
> calls the imm/ppa driver) will panic if the request is not completed in 3
> seconds.
>
> > I have a network adapter on
> > the first parport that will exactly to that: claim the port on open(),
> > release it on stop(). So you need to have to implement a counter that
> > makes you give up after some attempts or, even better, don't wait for
> > the bus to become idle at all but unregister the driver again and try
> > the next port.
>
> I am not sure what you are trying to prove here. The 3 second limit imposed
> by the mid level SCSI driver has resulted in every other parallel port sharing
> device "yielding" when required. The ppa/imm drivers will yield after each
> SCSI command in a similar fashion. This is a fundamental issue here with
> parport - you are NOT allowed to hog a parallel port or else the whole system
> could be brought down.

Hmno. There are cases where a driver just cannot release the port. You
seem to assume that parport is really a bus like scsi with per command
adressing, blockwise transfers aso. But this is only true for a certain
class of devices, like ZIPs and e.g. scanners. Actually there are
devices that cannot be addressed/deaddressed or
disconnected/reconnected.

If a driver is required to allow "stealing" of its ressources, parport
is simply fundamentally broken. As long as the device is actually in use
by the driver, how should it release it's ressources? If it would, and
another driver would try to initialise its native hardware on that port
(which will fail), it'll propably leave the attached device broken. Now,
what happens when the original driver comes back - bang.

For your own driver you may be able to guarantee the 3 seconds maximum
preemption delay, but not for others. So,if the kernel stability
actually demands on this, I'd regard this as a fundamental design flaw.
Actually, there should be a method to find out if a device supports
scsi-style disconnect/reconnect and in the NO case *not* to wait for the
bus to be released but just skip the port and try your luck at the next
one. There just HAS TO BE a method to say "this port is mine, don't try
to muck with it." If parport does not support this, it's broken. Look,
for the sharing to work properly, *every* driver must use the parport
interface, even those that actually don't support sharing.

Don't misunderstand me here: Your handling of the parport is correct if
your assumptions about the attached devices are correct. But within
imm_detect() you cannot be sure of the bus topology, thats why it's
broken.

> > Second, if you really think you should wait for the bus to become idle:
> > The wait loop is *very* unfriendly to other processes. It should be like
> > this:
> >
> > while (port_busy) {
> > current->timeout = jiffies + timeout;
> > current->state = TASK_INTERRUPTIBLE;
> > schedule();
> > if (signals_pending(current)) {
> > /* someone hit ^C to interrupt us */
> > goto out;
> > }
> > }
> >
> > ...
> > out:
> > /* clean up and exit */
> >
> >
> > You definitely need to handle signals, otherwise insmod or modprobe will
> > block forever.
>
> Voting time, what is everyones (Tim, Phil, Grant, Andrea, anyone else?) ideas
> on this subject?
>
> Sorry I haven't got time to seriously think this through myself, I am pulling an
> all nighter at the office to get a report off first thing tommorow morning...
> (Don't you hate it when reality creeps in on your kernel hacking time?)

Yeah, I know that .-)

Gruss,
        Matthias

-- 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 Wed 30 Dec 1998 - 10:18:21 EST