Re: SCSI device numbering

Albert Cahalan (albert@ccs.neu.edu)
Tue, 2 Jul 1996 08:28:08 -0400 (EDT)


From: Linus Torvalds <torvalds@cs.helsinki.fi>
> On Mon, 1 Jul 1996, Leonard N. Zubkoff wrote:
>>
>> So something like this:
>> - one major number for each SCSI bus (= usually one controller)
>> - 4 (8?) bits SCSI ID
>> - 7 bits SCSI LUN
>> - 4 bits partition information
>> - ???
>>
>> Yuk. Why should the dev_t need to encode these subsystem specific details?
>
> This wouldn't be a "dev_t" issue: as far as the _rest_ of the kernel is
> concerned, dev_t is just a 32-bit number. That goes without saying: I
> will totally ignore any patches that try to force any "regular" stuff on
> the device numbers.
>
> What I mean above is just what the SCSI drivers would use _internally_.
> External to the SCSI drivers, nothing even knows or cares..
>
> (We do want some kind of SCSI rules for the minor numbers, because we
> want the device numbers to at least look _similar_ even if we change
> controllers. But this is really internal to SCSI, not a "kernel" issue
> per se).

There are advantages to making block devices somewhat regular.
It becomes easier to share code between IDE and SCSI for example.

>> I'd much rather see:
>>
>> - 12 bits for the major number of each device type pretty much as we
>> have now.
>> (device types are the things that have a common set of properties)
>> - 16 bits for an index into a dynamically allocated dense array of
>> pointers to objects of that type
>> - 4 bits for partition information or other specialization
>
> NO! You seem to expect the kernel to actually care. The kernel should
> _not_ care at all about the actual layout of the device numbers. If some
> laser-guided-missile driver wants to use the 20 bit minor number for
> targeting information, it can do so. The kernel doesn't care.

Sure, that would not be a block device. It has no partitions, does
not use the page cache, etc.

> We're discussing only how the _internals_ of the SCSI layer decode
> the number it gets passed. For the rest of the kernel, there just
> needs to be some simple interface to get some specific information,
> for example something like:
>
> unsigned long dev_size(kdev_t); /* 512-byte sectors */
> int dev_readonly(kdev_t); /* readonly: != 0 */
> int check_disk_change(kdev_t); /* disk change info */

With regular device numbers some functions can be replaced by
simple macros.

> and then how the actual device lookup is done should be done in the
> driver (just add a few fields to the "struct device_struct", and let
> the drivers fill them in at register time, the same way it fills in
> the "struct file_operations *" fields).
>
>> I think that it's the *devices* that are the central objects here,
>> not their implementation on specific SCSI channels. I don't see any
>> reason that a dev_t needs to map directly to any SCSI details.
>> Each SCSI Device can refer to the specific bus, the driver that
>> handles that bus, and whatever details are necessary to address
>> that device.
>
> There is no need at all to even discuss internals of "dev_t" without
> specifying a driver: "dev_t" _has_ no internals (apart from the number of
> bits for major/minor numbers, and even that is mainly just a interface
> issue) on it's own. Only when talking about a specific driver does it
> make sense to try to specify what the numbers mean.
>
> And the numbers _will_ differ from driver to driver: IDE disks use 6 bits
> for partition information, while the floppy driver uses no bits at all,
> and instead uses 2 bits for specifying which floppy and 6 bits for
> specifying floppy type. I'm not going to accept any patches that try to
> "regularize" this - making up rules just for the fun of having rules
> makes no sense.

I think it is useful to be able to do this:
#define PARTITION(d) ((d) & 0xf)

I also think that kernel error messages and "ls -l /dev" will be
easier to read if dev_t is split on nibble boundries and everything
gets printed in hex.

> HOWEVER, within the SCSI subsystem we _do_ need to have some rules,
> because a user that changes his SCSI controller from a NCR controller to
> a BusLogic controller does _not_ want his /dev setup to change: his disks
> didn't change. So for SCSI it makes sense to make some rules for how the
> drivers should interpret the minor numbers.
>
>> I think 65536 devices of each type is probably sufficient for
>> the moment. If not, we can shrink the major number a bit more.
>> The reason 32 bits aren't enough in most of the suggestions
>> I've seen is that we're trying to encode irrelevant and unnecessary
>> information into the minor numbers. dev_t does not need to be the
>> way of naming devices from the user's perspective.
>
> dev_t _IS_ the way of naming devices when it comes to the kernel. There
> simply _is_ no other naming. The fact that you can then do stuff like
>
> mknod b 256 0x010101 /dev/scsi/id1lun1part1
>
> or whatever is irrelevant (although that also needs to be standardized,

A simple uniform mapping is a convenience for humans. The simple
mapping is important because people must often convert by hand.
I've seen this many times on the kernel list when someone posts
an oops report with device numbers in it.

Fortunately, a simple mapping is also convenient for programmers
and might even run a tiny tiny bit faster.

> But if anybody thought I have been advocating some kind of "global device
> numbers" for everything (SCSI, laser pointers, network cards, robot arms,
> keyboards..), think again. device numbers are supposed to be just ID's
> for the hardware, and they shouldn't have any _inherent_ properties.

Standard naming conventions are not _needed_, but _useful_.
They don't apply to character devices (except the obvious
convention, start with 0). They make devices easier to decode.
It is _really_ helpful to break things on nibble boundries.
The floppy type field using 6 bits could fit into the same
field that a SCSI lun would fit into. We don't need to call it
a lun of course, just put it in the same spot.