[LWN Logo]

Date: Thu, 27 May 1999 10:32:32 -0700 (PDT)
From: Linus Torvalds <torvalds@transmeta.com>
To: linux-usb@suse.com
Subject: Re: [linux-usb] Re: Names for USB devices.




On Thu, 27 May 1999, Dirk H Hohndel wrote:
> 
> Linus, this is not being user friendly, and this is not the concept of
> least surprise. This is something that is a MAJOR mess, if you think about
> it. By simply removing one device and inserting it again I now have to
> change /etc/printcap? And /etc/XF86Config? And lots of other config files?

I don't think you (or other people on this list) realize just how
impossible it is to handle this.

The remove and re-insert is easy if you only have one device. My scheme
will give you exactly the behaviour you want: a single device will
_always_ be /dev/lp0 or /dev/mouse0 (and /dev/mouse will always be the
"combination of all mice events" device - which is the one I would use and
I bet 95% of everybody else would use it too). 

With two devices, there isn't any way to avoid it. Not my scheme, but also
not any other scheme. Just take my word for it if you can't think about it
yourself. 

For example, let's assume that you have two identical devices, A and B.
Neither is connected at first. Let's go through the cases:

My scheme:
 - Add A. It obviously becomes dev0.

 - Add B. This isn't obvious, but a device add implies a reconfigure, and
   for all we know B might become dev0 and A is now dev1. That depends on
   whatever algorithm you use to traverse the device tree - which should
   be fixed in order to always give the same results. So B _may_ be dev1,
   but you have to realize that my scheme may make B=0, A=1.

   This is the inconsistency that people are afraid of. I agree. It's
   strange, and it _is_ surprising. I'm not really claiming anything else,
   but I _am_ claiming that the _timing_ of the surprise is less
   surprising then with the other schemes. 

 - remove A. No surprises here: B is now dev0. B might have been dev1
   before, but at least this is not at all surprising any more. You know
   exactly what's going to happen, and it makes tons of sense.

 - insert A. See the insert B case. This is entirely consistent. We don't
   know whether A or B is going to be dev0/dev1.

So my scheme has a surprise factor, and I agree, it's not "nice". I also
agree that if you want to avoid that surprise factor, then you want to
have a clever lpr that can query what kinds of devices there are, and you
hope that your printers or whatever have unique strings. If they don't,
you're kind of screwed. 

HOWEVER. My scheme has the big advantage that when you see what devices
are connected, YOU KNOW WHAT THE SETUP IS LIKE. You may not know whether
printer1 is lp0 or lp1, but that's pretty much true even with a serial
printer. And it won't really change at any other times than "reconfigure
events". My scheme has no history - each moment in time makes sense, quite
regardless of what it was that led up to it. And you can tell what the
devices are if you just know what the tree traversal function is (probably
simple depth-first.

So leave the above notion in your head. Admit that is has problems, but
also realize its strengths. 

Other proposals: use the lowest number available at the time of
connection. 

 - Add A. It obviously becomes dev0

 - Add B. It obviously becomes dev1

 - Remove A. B is still dev1

 - Add A. It is (again) dev0 and B is (still) dev1

Looks perfect, no?

No. The lowest number approach is actually probably the best alternative,
and it gets perfect behaviour above. That's a classic case of incomplete
information - when there isn't a perfect solution, you will still find
solutions that are perfect in _some_ circumstances. Let me show why the
above is _not_ perfect after all, by simply not doing step 3-4 at all.

You reboot. Suddenly A is dev1 and B is dev0. Fun? No. That's f*cking
broken, and anybody who doesn't admit to that is being hypocritical. You
did all your setup with A=dev0, and B=dev1, and you had a power outage,
and now it doesn't work any more. 

Ok. Instead say that you only skip setp 4, and you do 1-3.

Think about it. You now have one printer and it is dev1. You aren't ever
going to add A again, because the whole reason you inserted B is that you
wanted to get rid of A, and it's going into the trash or being donated to
charity or whatever.

So now you have two problems: you have a inconsistent device space (that
is not consistent with the current setup, and is only explainable by
history). The other problem is what happens when B is disconnected and
reconnected. Which could happen without you even knowing about it if there
is an electrical glitch, for example. 

Does disconnect-reconnect make the printer be dev0? You have two cases:

 - NO. It stays at dev1. Problems:

	How do you do that? How do you know that it wasn't A that was
	re-inserted after all? A and B are identical after all. 

	How do you make B be dev0 at all? You can't. You have to reboot
	your machine. So either it stays at dev1 forever, and the next
	time you reboot it magically changes.

	In short, this is (a) impossible and (b) broken.

 - YES. Re-inserting B now makes it dev0, because it's the lowest numbered
   device and there were no other devices. Problems:

	Electrical glitch. It will show up on the USB bus as a disconnect
	and a reconnect.  I call THAT surprising: it magically changes
	from dev1 to dev0 without you ever touching it.

	You now add back A. A becomes dev1. And you lost the whole idea of
	this sequence in the first place - you added and removed two
	devices, and the end result is different from the original one.

Do you see why this is all broken? My scheme has a very localized surprise
factor, and even that isn't actually surprising if you know about it:
devices _always_ have the same names as long as teh topology is the same.

In short, in my scheme you can glance at the device setup, and you know
what the results are. No other scheme gives that. Trust me - think it
through if you don't believe me.

		Linus

--
To get out of this list, please send email to majordomo@suse.com with
this text in its body: unsubscribe linux-usb